> ## 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.

# tp init 生成了什么

> tp init 生成什么、CLI 上传什么、什么永远不离开笔记本

TunePlane 的 **lab** 是本机上一个普通 git 仓库。控制台不会去 clone。`tp submit` 打一个文件子集的包，上传后由服务端再注入 Job Capsule。

## `tp init my-lab --yes` 之后

```text theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
my-lab/
├── tuneplane.yaml      # 仓库标记 + 项目名（tuneplane 找根目录的唯一信号）
├── experiments/        # tp new 在这里建目录
├── configs/            # 官方基底 + 模型片段，你可以改、可以 pin
├── common/             # 共享代码：数据脚本、环境、奖励
├── .gitignore
└── README.md
```

`tuneplane.yaml` 需要一个 `name`，字符限制 `[A-Za-z0-9._-]`。这就是控制台项目名。提交时不要传 `--project`。

```yaml theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
name: my-lab
```

需要项目的命令（`tp new`、`submit`、`ls`、`validate`）从当前目录往上找这个文件。CI 可以设 `TUNEPLANE_CLIENT_REPO_ROOT`，不必 `cd`。`tp login` / `logout` / `status` 是全局的，不依赖项目。

## 一个实验目录

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
tp new my-grpo --method nemo-rl/grpo
```

```text theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
experiments/my-grpo/
├── config.yaml           # 你的差异；靠 defaults 继承
├── README.md             # 脚手架说明，不执行
└── recipe.lock.json      # 方法 + 框架钉死
```

`custom/custom` 还会有 `train.sh`（唯一入口）。旁边可以再放 `train.py`。`tp plugin install … --exp` 之后会多 `plugins.lock.json`。

不要在实验目录里放一个 `framework` 文件指望平台去读。方法以锁文件为准。

## 什么会被上传

CLI 打包实验、`common/`、`configs/`。排除列表和服务器共用（`tuneplane.contract.env` 里的 `PACKAGE_EXCLUDES`）：

| 模式                                         | 为什么丢掉                                             |
| ------------------------------------------ | ------------------------------------------------- |
| `.tuneplane-data/**`                       | 本机凭据。进了包就等于把 token 送到集群。                          |
| `.git/**`                                  | 历史用 provenance 里的 commit SHA 记录，不是整库克隆。           |
| `**/outputs/**`                            | 本机残留产物。集群产物在 `$TUNEPLANE_OUT_DIR`。                |
| `datasets/**/raw/**`、`datasets/**/data/**` | 原始数据体积。用[平台数据集](/zh-Hans/guides/datasets)或 HF id。 |
| `**/__pycache__/**`                        | 字节码。                                              |
| `**/*.key`、`**/secrets.env`                | 密钥放服务端，不进作业包。                                     |

JobSpec 写在包内 `.tuneplane/jobspec.json`。注意是 `.tuneplane/`，不是 `.tuneplane/`。`.tuneplane` 会被排除，写进去集群侧读不到。

## 仓库里不会有的东西

* 集群 kubeconfig、Slurm JWT、对象存储密钥
* Job Capsule（`runner.pex`）。准入后由服务端注入。
* 硬件并行度。来自 `--profile` 和注册表。

## Git

提交会记录 `NRL_GIT_COMMIT` 和 `NRL_GIT_DIRTY`。工作区不干净默认拒绝，除非 `--allow-dirty`。未跟踪文件两种情况下都会当警告列出来。`tp init` 默认就初始化 git，第一次提交不要拖到交作业那一刻。

git 决定 run 能不能复现，但不是提交的前提。不是 git 仓库的工作目录——`tp init --no-git`、从别处拷过来的目录、根本没装 git 的机器——照样能提交，只是不记录 commit，控制台上这个 run 没有溯源信息。已经是仓库、只是还没有 commit 的情况下 `.gitignore` 照旧生效：文件清单仍然来自 git，缺的只是那个 commit。完全没有仓库时变的才是文件清单：没有 git 帮你应用 `.gitignore`，打包就是把同样那三个目录按平台内置排除项（`outputs/`、`tuneplane_plugins/`、`__pycache__/`、`.venv/`、各种缓存，以及看起来像密钥的文件）走一遍，且超过 64 MB 直接拒绝——免得没人打算上传的产物悄悄进了包。真要带大文件，用 `TUNEPLANE_CLIENT_MAX_PACKAGE_MB` 抬上限。

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
git add -A && git commit -m "first grpo config"
tp submit my-grpo --profile h200:8
```
