> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tuneplane.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 挂载受管目录

> 让作业只读访问任何人都不允许下载的材料。

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
tp volume create acme/support-transcripts -d "二线工单，已脱敏"
tp volume push ./transcripts --name acme/support-transcripts
tp submit my-sft --profile h200:8 --volume acme/support-transcripts
```

作业在 `$VOLUMES_DIR/support-transcripts` 只读读取这些文件。除非所有者打开，没人能下载它们。

## Volume 不是数据集

|    | Volume              | 数据集                        |
| -- | ------------------- | -------------------------- |
| 版本 | 没有。当前内容就是它的内容       | 不可变的版本                     |
| 引用 | `<owner>/<name>`    | `<owner>/<name>[@version]` |
| 变更 | 文件原地增删              | 每次一个新版本                    |
| 用于 | 内部文档、参考 PDF、一直在长的材料 | 一次完成的运行必须说得出名字的训练数据        |
| 下载 | 默认关闭，要所有者打开         | 任何能引用它的人都能取                |

volume 引用带版本后缀会在解析 spec 时被拒绝。格式错误的 id 同样，以及两个 volume 的叶子名会在
同一个挂载路径上撞车的情况。

## 创建并填充

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
tp volume create acme/support-transcripts -d "二线工单，已脱敏"
tp volume create acme/refs --public                    # 任何已登录用户都能引用
tp volume push ./transcripts --name acme/support-transcripts
tp volume ls
```

`tp volume push` 上传目录下的一切，除掉操作系统和 Office 的杂物。链路快的话把 `--concurrency`
调高。

删文件，或删整个 volume：

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
tp volume rm acme/support-transcripts -p old/2024 -p drafts
tp volume rm acme/support-transcripts --yes
```

## 从作业里引用它

在实验配置里声明，这是持久的写法：

```yaml theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
data:
  volumes:
    - acme/support-transcripts
    - bob/reference-pdfs
```

或者只覆盖这一次提交：

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
tp submit my-sft --profile h200:8 \
  --volume acme/support-transcripts --volume bob/reference-pdfs
```

每个都出现在 `$VOLUMES_DIR/<叶子名>`。从环境变量里读路径，永远不要硬编码。

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
import os, pathlib

root = pathlib.Path(os.environ["VOLUMES_DIR"]) / "support-transcripts"
for path in root.rglob("*.txt"):
    ...
```

引用了一个你看不到的 volume 的作业会在提交时被拒绝。这是有意的：一个空目录会让权限问题看起来像
建模问题。

## 哪些后端能挂

| Fleet kind | 能挂 volume                        | 怎么挂                     |
| ---------- | -------------------------------- | ----------------------- |
| `local`    | 能                                | bind mount              |
| `node`     | 能                                | 每个节点上同一路径的同一个文件系统       |
| `kuberay`  | 仅配了 `TUNEPLANE_K8S_VOLUME_PVC` 时 | 挂在 `/volumes` 的只读 claim |
| `slurm`    | 不能                               | 平台不控制镜像的 bind 列表        |

在挂不了的后端上，提交会被拒绝并点名那个设置，而不是启动一个挂载点是空的作业。

## 让一个文件变成人能读的东西

两个权限，都属于所有者，都默认关闭：

| 权限               | 允许什么                    |
| ---------------- | ----------------------- |
| `allow_download` | 把字节取出来。这是材料按设计离开平台的唯一通路 |
| `allow_preview`  | 控制台一次内联渲染一个文件。每次读取都被审计  |

它们互相独立。列出结构 —— 文件名、大小 —— 对任何能引用这个 volume 的人始终可见；内容不是。

## 从一个 volume 产出数据集

读一个 volume 并把结果发布出来，这叫 **Processing Run**：你的代码，在平台上跑，带溯源。

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
tp submit my-prep --profile h200:1 \
  --volume acme/support-transcripts \
  --output-dataset acme/support-sft@v1
```

作业往 `$TUNEPLANE_DATASET_OUT_DIR` 里写，运行成功后由平台发布。作业从不持有注册表凭据，发布出的
数据集继承它所读材料的分级。

这也是清洗一个 volume 的方式：读、处理、发布。平台从不改写你上传的东西。

## 确认成功

`tp volume ls` 会显示这个 volume 和它的文件数。在运行中的作业里：

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
ls -la "$VOLUMES_DIR"
```

挂载是只读的，所以往那里写会失败 —— 那是挂载在正常工作，不是 bug。

<Accordion title="Volume 防不住什么">
  如果你的代码能读到明文，任何存储控制都挡不住外带。一个能打开 PDF 的脚本，就能把它 base64 到自己
  的 stdout 里。

  Volume 真正强制的是：`allow_download` 关着时没有下载路由，`allow_preview` 关着时没有预览路由，
  打开时每读一个文件留一条审计，只读挂载，一条被审计的引用记录，以及没有批量日志下载。每一条
  出去的路都是某个人做过的决定和某个人能找到的记录。

  把材料完全挡在集群之外，是部署方的出网策略，不是这个功能。
</Accordion>

## 下一步

[数据集](/zh-Hans/guides/datasets) · [提交作业](/zh-Hans/guides/submit) ·
[数据页](/zh-Hans/console/data)
