引导用户在 AI Studio 无代码训练平台完成大模型微调,支持 ERNIE 和开源模型(Qwen/LLaMA)。当用户提到微调、训练模型、SFT、fine-tune、问答对、让模型学会、定制领域助手、专属领域 AI、行业术语、调教模型、业务知识注入、领域适配、医疗问答、客服问答、无代码训练、AiStudio 训练、ERNIE 微调、模型训练、finetune 时,优先触发。
Scanned 8/31/2026
Install to Claude Code
npx -y skills add liuyunlin/cli-trainer --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of cli-trainer?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/liuyunlin-cli-trainer)More formats (shields.io, HTML) on the badges page.
---
name: cli-trainer
description: 引导用户在 AI Studio 无代码训练平台完成大模型微调,支持 ERNIE 和开源模型(Qwen/LLaMA)。当用户提到微调、训练模型、SFT、fine-tune、问答对、让模型学会、定制领域助手、专属领域 AI、行业术语、调教模型、业务知识注入、领域适配、医疗问答、客服问答、无代码训练、AiStudio 训练、ERNIE 微调、模型训练、finetune 时,优先触发。
---
# CLI Trainer Skill
帮助用户在 AI Studio 云端完成大模型微调,不需要 GPU、不需要搭环境、不需要写训练代码。
用 `scripts/train.py` 执行所有平台交互,脚本路径通过 `$SKILL_PATH` 引用:
```bash
python3 "$SKILL_PATH/scripts/train.py" --check-data my_data.jsonl
```
---
## !! 绝对禁止事项(最高优先级)
1. **禁止自己猜测或硬写超参数然后提交。** 必须先运行 `--suggest-params`,把推荐值展示给用户,等用户确认再提交。
2. **禁止在用户明确确认前调用 `--submit`。** 展示参数时逐行解释含义,问”需要调整哪些?没问题就提交”,等用户回复。
3. **禁止把推荐参数当作默认训练配置直接提交。** 训练方式默认 `SFT/Full`;除非用户明确要求 `SFT/LoRA`,否则不要传 `--train-type`,也不要提交 `lora_rank`、`lora_alpha`、`lora_dropout` 等 LoRA 专属参数。`--suggest-params --model-type llama` 的输出可能包含 LoRA 字段,展示给用户前必须按实际 `train_type` 过滤并说明。
4. **训练方式变化时必须同步调整超参数。** 从 `SFT/LoRA` 改为 `SFT/Full` 时,必须删除 LoRA 专属参数,并把学习率降到 Full 微调适用范围(通常 `5e-5` 起步,必要时更低);从 `SFT/Full` 改为 `SFT/LoRA` 时,才可恢复 LoRA 字段和较高学习率。用户提出”学更完整长解释/长回答/保留更多上下文”时,提醒可把 `cutoff_len`/`max_seq_len` 提到 512 或更高,同时说明训练会更慢、更吃显存,OOM 时先降 `per_device_train_batch_size`。
---
## 执行顺序
1. **环境自检** — 首次使用时先跑一次,自动检测 Python 版本、依赖包、网络连通性,requests 缺失会自动安装
2. **鉴权** — 确认有 Access Token,没有就引导去 https://aistudio.baidu.com/account/accessToken 获取
3. **选模型** — 运行 `--list-models` 展示白名单,让用户选,不要让用户自己猜名称
4. **验数据** — 运行 `--check-data` 检查格式,提前发现错误
5. **准备/上传数据集** — 只能访问 AiStudio 新版 Git 仓库型数据集,不支持外部 URL。创建仓库时先确认真实 `gitlogin`;用 Playwright MCP 或 `web-access` skill 创建仓库并拿到真实 `repo_id`;上传前优先删除 `.gitattributes` 中的 JSON/JSONL LFS 规则,上传后记录 `is_lfs` 状态并确认文件大小。
6. **推荐超参** — 运行 `--suggest-params`,展示结果,**等用户确认后才提交**
7. **提交训练** — 运行 `--submit`,拿到 jobId
8. **监控训练** — 提交后运行 `--poll JOB_ID`;任务进入 running 且接口返回 `tensorboardUrl` 后自动打开 Tensorboard
9. **取结果** — 训练完成后给出模型仓库地址和训练摘要
---
## 各步骤关键细节
### 环境自检
```bash
python3 "$SKILL_PATH/scripts/train.py" --env-check
```
检查内容:Python 版本(需 3.8+)、requests 包(缺失时自动 pip install)、网络连通性。
如果 python3 命令本身不存在,告知用户安装 Python 3.8+:macOS 用 `brew install python3`,其他平台参考 https://www.python.org/downloads/
### 通用 [web-access](https://github.com/eze-is/web-access) / Codex 推荐安装 Playwright MCP
自建数据集、网页端创建数据集仓库、必要时初始化 Gitea 或操作登录后网页时,不要只固定使用一种浏览器方案。这里按"通用 web-access / Codex 推荐安装 Playwright MCP"处理:Codex 环境优先安装/启用 Playwright MCP;需要复用用户日常 Chrome 登录态时,再使用 `web-access`。目标是拿到页面详情页真实 `repo_id` 并完成必要的 `.gitattributes` 编辑;优先选择当前可用、已登录、最少阻塞的浏览器自动化能力。
推荐顺序:
1. **Playwright MCP 可用且页面已登录时优先使用。** 适合打开 AI Studio 页面、创建数据集、填写表单、选择协议、编辑 `.gitattributes`、读取 `repo_id`。常用能力:`browser_navigate`、`browser_snapshot`、`browser_click`、`browser_fill_form`、`browser_evaluate`。它不依赖用户 Chrome 的 remote debugging 授权,CDP 授权卡住时尤其适合。
2. **需要用户日常 Chrome 登录态时使用 `web-access`。** 如果 Playwright 未登录、页面需要真实 Chrome cookie/扩展/特殊会话,加载 `web-access` skill 并启动 CDP Proxy。
3. **两者都不可用时再让用户手动创建仓库。** 此时给出最短步骤,并要求用户回传详情页真实 `repo_id`,不要猜。
进入上传/建仓步骤前,若选择 `web-access`,按下面流程检查并准备它。
准备顺序:
1. 如果当前会话可用 `web-access` skill,先加载它并遵循其 `SKILL.md`
2. 如果 skill 元数据没触发,但 `$HOME/.codex/skills/web-access/SKILL.md` 存在,直接把 `WEB_ACCESS_SKILL_PATH` 指向该目录并运行 `scripts/check-deps.sh`
3. 如果目录不存在,先使用 `skill-installer` 安装 [`web-access`](https://github.com/eze-is/web-access)。安装完成后可立即用安装目录下的 `scripts/check-deps.sh`;同时告诉用户重启 AI IDE / 刷新 Agent 会话后才能自动识别新 skill
4. 如果安装失败或 Chrome 远程调试授权不可用,才退回让用户手动在网页创建数据集仓库
检查命令:
```bash
WEB_ACCESS_SKILL_PATH="${WEB_ACCESS_SKILL_PATH:-$HOME/.codex/skills/web-access}"
bash "$WEB_ACCESS_SKILL_PATH/scripts/check-deps.sh"
```
### Token
需要 token 时,**直接告诉用户**:「请把 https://aistudio.baidu.com/account/accessToken 页面的 token 粘贴给我,我来运行。」用户粘贴后,Agent 用以下方式在当前 shell 设置并使用,不要让用户自己执行任何 shell 命令:
```bash
export AISTUDIO_ACCESS_TOKEN="用户粘贴的token"
python3 "$SKILL_PATH/scripts/train.py" --verify-token
```
验证:`python3 "$SKILL_PATH/scripts/train.py" --verify-token`
如果用户已在本机手工用 `aistudio config/login` 配过 token,脚本无环境变量时自动读取 SDK 缓存;环境变量里的过期 token 会覆盖缓存,遇到 401 先检查环境变量。
如果用户已在本机手工用 `aistudio config/login` 配过 token,脚本无环境变量时自动读取 SDK 缓存;环境变量里的过期 token 会覆盖缓存,遇到 401 先检查环境变量。
### 选模型
```bash
python3 "$SKILL_PATH/scripts/train.py" --list-models
```
- 必须用白名单里的模型
- 单卡最大 32B 以下,超过会 OOM
- 训练方式默认 `SFT/Full`;只有明确需要 LoRA 时才传 `--train-type`
- ERNIE → 框架 PaddleFormers,trainType 只能 `SFT/Full`,数据格式 src/tgt
- 开源模型 → 框架 LlamaFactory,trainType 推荐 `SFT/Full` 或 `SFT/LoRA`,数据格式支持 Alpaca 和 ShareGPT
- 具体模型的风险提示以 `--list-models` 输出为准
### 数据格式
**ERNIE 格式(src/tgt 值必须是列表):**
```jsonl
{"src": ["问题"], "tgt": ["回答"]}
```
最常见错误:用了 Alpaca 格式,任务会跑起来但 poller 阶段报"非 ERNIE 格式"。
**LlamaFactory 格式 1:Alpaca(支持 JSONL 或 JSON 数组):**
```jsonl
{"instruction": "问题", "input": "", "output": "回答"}
```
JSON 数组文件也可检查,常见文件名是 `alpaca_data.json`:
```json
[{"instruction": "问题", "input": "", "output": "回答"}]
```
**LlamaFactory 格式 2:ShareGPT(支持 JSONL 或 JSON 数组):**
```jsonl
{"conversations": [{"from": "human", "value": "问题"}, {"from": "gpt", "value": "回答"}]}
```
OpenAI `messages` 也属于 ShareGPT 特例,但平台兼容性不确定时,优先转成 `conversations/from/value`。
```bash
python3 "$SKILL_PATH/scripts/train.py" --check-data 数据文件.jsonl
python3 "$SKILL_PATH/scripts/train.py" --check-data alpaca_data.json
python3 "$SKILL_PATH/scripts/train.py" --check-data sharegpt_data.jsonl
```
数据规模参考:50-500 条(验证流程)/ 1k-10k(场景微调)/ 10k+(全面提升)
### 上传数据
没有自己数据时,先读取 `$SKILL_PATH/references/datasets.md`,根据用户目标推荐合适的数据集;再用 `--list-datasets` 展示完整列表。有本地训练文件时,按下面门禁上传。浏览器自动化只负责建仓、读真实 `repo_id`、必要时编辑 `.gitattributes`;SDK/CLI 负责上传,`--verify-upload` 负责最终验收。
1. **准备 web-access/CDP**
```bash
WEB_ACCESS_SKILL_PATH="${WEB_ACCESS_SKILL_PATH:-$HOME/.codex/skills/web-access}"
bash "$WEB_ACCESS_SKILL_PATH/scripts/check-deps.sh"
```
如果 web-access skill 不在默认目录,从实际 `SKILL.md` 路径解析目录;Chrome 出现远程调试授权时让用户允许,页面未登录时让用户在 Chrome 登录 AI Studio。
2. **创建或确认数据集仓库**
- 在 `https://aistudio.baidu.com/my/dataset` 创建或打开数据集仓库。创建时需填写:
- **数据集英文ID**(必填):用小写字母、数字、下划线,形如 `yunlin/my_dataset`
- **数据集展示名称**(选填):面向社区展示,建议填写,描述数据集用途,最多 50 字
- **开源协议**(必选):允许商用选 **Apache 2.0**;有归因要求选 **CC BY 4.0**;不选则创建可能静默失败
- 创建或打开仓库后,从详情页读取完整 `repo_id`,形如 `gitlogin/repo_name`。不要用昵称、展示名、登录用户名或邮箱猜 `gitlogin`。
- `aistudio upload` / `aistudio_sdk.hub.upload_file` 只上传到已有数据集仓库,不会自动创建 dataset repo。如果上传时报 `preupload` 404,优先检查仓库是否已在网页端创建、`repo_id` 是否来自详情页、token 是否对该仓库有写权限、仓库类型是否为 dataset。
- 如果传 `--output-repo`,斜杠前半段必须和当前账号可写的 `gitlogin` 匹配。
3. **上传前处理 JSON/JSONL 的 LFS 规则**
- 预防优先:新仓库创建后、上传训练文件前,进入数据集详情页 → 文件列表 → `.gitattributes` → 编辑,删除训练文件扩展名对应的 LFS 规则,例如 `*.jsonl filter=lfs ...` 或 `*.json filter=lfs ...`,然后保存。
- ERNIE 的 `src/tgt` JSONL、LlamaFactory 的 Alpaca/ShareGPT JSONL/JSON 都要检查;训练用 JSON/JSONL 推荐作为普通文件上传,便于下载回验和排查。
- 如果已经上传成 LFS:不要直接判定训练必然失败。已实测部分 `is_lfs:true` 文件也可能被 AI Studio 成功挂载并完成训练;但它会降低可回验性,也会让 `waiting_data` 排查更困难。若任务卡在 `waiting_data`,优先删除旧 LFS 训练文件、移除 `.gitattributes` 中 JSON/JSONL LFS 规则,然后按本上传小节第 5 步 SDK 方案或第 6 步 CLI 方案重新上传。
4. **上传前检查文件大小**:普通文件超过 5MB 平台会拒绝,不要改走 LFS 绕过限制。超过 5MB 时先告知用户,可选:裁剪过长样本、减少数据量、拆分批次。
5. **用 SDK 上传数据集文件夹(推荐)**
- 上传原则见 `references/aistudio_sdk_upload.md`;主规则是:完整 `repo_id`、一仓一数据集、token 只走环境变量、JSON/JSONL 优先不走 LFS。
- SDK 日志出现 `201` 和 `Commit part 1 successful!` 才算提交成功;STS 分支的已知回退报错不单独视为失败。
- 上传后必须继续执行本上传小节第 6 步;不要只看 SDK 上传日志。
6. **用 CLI 上传单个训练文件(备选)**
```bash
AISTUDIO_CLI="${AISTUDIO_CLI:-$(python3 -m site --user-base)/bin/aistudio}"
[ -x "$AISTUDIO_CLI" ] || AISTUDIO_CLI="$(command -v aistudio)"
LOCAL_FILE="/path/to/train.jsonl" # 也可以是 alpaca_data.json
TRAIN_FILE="$(basename "$LOCAL_FILE")" # 仓库内文件名,提交训练时 --train-file 也用它
"$AISTUDIO_CLI" upload "$REPO_ID" "$LOCAL_FILE" "$TRAIN_FILE" --repo-type dataset
```
只有确认当前 CLI 不会打印完整 argv 时才使用备选方案;不要附加 `--token TOKEN`,token 仍应走环境变量或 SDK 缓存。
`REPO_ID` 必须是详情页显示的完整 `repo_id`。如果出现 `preupload` 404,回到本上传小节第 2 步确认仓库已存在且路径无误。
上传命令成功返回后,必须立刻主动告诉用户:训练文件已上传到哪个 `repo_id`、仓库内文件名是什么、接下来会做 `is_lfs` 和下载回验;不要等到提交训练后才暴露上传问题。
7. **验证上传结果**
```bash
python3 "$SKILL_PATH/scripts/train.py" \
--verify-upload \
--train-data "$REPO_ID" \
--train-file "$TRAIN_FILE" \
--local-file "$LOCAL_FILE"
```
验证标准:文件大小接近本地文件,下载回来后 `--check-data` 通过;推荐 `is_lfs:false`。如果 `is_lfs:true`,不要直接隐瞒或继续静默提交,必须提示风险:本项目 smoke 实测 LFS 也可能训练成功,但若任务卡 `waiting_data` 应优先修复 LFS。
验证通过后必须再主动给用户一个上传完成回执,至少包含:
- 数据集:`REPO_ID`
- 训练文件:`TRAIN_FILE`
- LFS 状态:`is_lfs:false`(推荐)或 `is_lfs:true` 风险说明
- 文件大小:仓库大小与本地大小是否一致或接近
- 下一步将使用的提交参数:`--train-data "$REPO_ID" --train-file "$TRAIN_FILE"`
8. **卡在 `waiting_data` 时按顺序排查**
- `REPO_ID` 是否来自详情页,`gitlogin` 是否真实可写
- `--train-file` 是否和仓库内文件名完全一致
- 训练文件大小是否接近本地文件;若 `is_lfs:true`,优先修复为普通 JSON/JSONL 后重试
- 下载回本地后 `--check-data` 是否通过
- 如果新 commit 和新 `mount Job` 仍循环”正在等待数据集下载完成...”,通常是平台挂载任务卡住;停止反复重传,保留 jobId、repo_id、commitId、mount Job 和上传校验结果给平台排查。
9. **为数据集仓库推送 README**
数据集仓库创建并验证上传通过后,必须自动写一份 README.md 并推送,方式与模型仓库相同(`GIT_ASKPASS` + sparse-checkout),remote 地址换成 `https://git.aistudio.baidu.com/$REPO_ID.git`。
README 以平台标准模板为基础,填入真实信息;无法获取的字段整行省略,不留占位符。
### 推荐超参并确认
```bash
python3 "$SKILL_PATH/scripts/train.py" --suggest-params 数据文件.jsonl --model-type ernie
```
脚本输出推荐值后,逐行解释给用户,明确问:"需要调整哪些?没问题就提交。" 等回复再往下走。
**ERNIE(PaddleFormers)主要参数:**
| 参数 | 类型 | 推荐值 | 说明 |
|------|------|-------|------|
| `num_train_epochs` | float | 3 | 训练轮数,数据少可调大到 5 |
| `per_device_train_batch_size` | int | 4 | 每步样本数,OOM 就调小到 2 |
| `learning_rate` | float | 5e-5 | 学习率,新手一般不用改 |
| `max_seq_len` | int | 512 | 最大序列长度,超过截断 |
| `max_steps` | int | -1 | -1 表示由 epochs 控制;不传时平台可能使用默认固定步数,导致 epochs 没有按预期跑满 |
| `warmup_steps` | int | 50 | 预热步数,约总步数的 5-10% |
| `logging_steps` | int | 5 | 每几步打一次日志 |
| `bf16` | bool | true | 混合精度,节省显存 |
**LlamaFactory(开源模型)核心训练参数:**
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `learning_rate` | float | `5e-5` | 建议范围 `1e-6`~`5e-4`,小模型(0.5B-3B)推荐 `5e-5`,大模型(7B+)推荐 `1e-5`~`3e-5` |
| `num_train_epochs` | float | `3.0` | 训练轮次,数据量小可适当增大 |
| `per_device_train_batch_size` | int | `2` | 单卡 batch size,0.5B 可用 `2`~`8`,7B+ 建议 `1`~`2` |
| `gradient_accumulation_steps` | int | `8` | 梯度累积步数,等效 batch = `batch_size × accumulation` |
| `cutoff_len` | int | `1024` | 最大序列长度,长文本场景可调至 `2048`/`4096`,显存随之增大 |
| `warmup_ratio` | float | `0.1` | 学习率预热比例 |
| `lr_scheduler_type` | string | `"cosine"` | 学习率调度策略:`cosine`、`linear`、`constant` |
| `max_grad_norm` | float | `1.0` | 梯度裁剪阈值,防止梯度爆炸 |
| `logging_steps` | int | `5` | 日志打印间隔 |
| `save_steps` | int | `50` | checkpoint 保存间隔 |
| `fp16` | bool | `true` | 混合精度 |
**LlamaFactory(SFT/LoRA 时生效)LoRA 参数:**
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `lora_rank` | int | `8` | LoRA 秩,越大表达能力越强但显存越多,常用 `8`/`16`/`32`/`64` |
| `lora_alpha` | int | `16` | 缩放系数,通常设为 `lora_rank` 的 1~2 倍 |
| `lora_dropout` | float | `0` | 防过拟合可设 `0.05`~`0.1` |
| `lora_target` | string | `"all"` | 应用 LoRA 的目标模块,`all` 表示所有线性层 |
训练方式选定后,按以下原则提交参数:`SFT/Full` 只传核心训练参数,不传 LoRA 参数;`SFT/LoRA` 在核心训练参数基础上叠加 LoRA 参数。只要训练方式发生变化,必须重新展示调整后的完整参数给用户确认。
上下文长度要跟目标回答风格联动:短问答/分类/固定格式可用脚本推荐的 `cutoff_len`/`max_seq_len`;如果用户希望模型学习更完整的长解释、长评论或保留热搜详情,优先建议 512。调大长度会增加训练时间和显存占用;出现 OOM 时,先把 `per_device_train_batch_size` 降到 2,再考虑降长度。
### 命名规范
提交训练前必须同时确定以下名称:
| 名称 | 填写位置 | 格式 | 示例 |
|------|---------|------|------|
| 训练任务名 | `--name` | `{model_short}_{domain}_{profile}`,只用字母/数字/下划线,**禁止缩写** | `ernie45_03b_self_cognition_smoke` |
| 模型英文ID | `--output-repo` | `{gitlogin}/{model_short}_{domain}_{profile}` | `yunlin/ernie45_03b_self_cognition_smoke` |
| 模型展示名称 | `--model-display-name` 目标值;训练成功后网页「模型展示名称」字段 | `【{基座模型名称}】{场景/功能描述}`,12 汉字以内,最多 50 字 | `【ERNIE-4.5-0.3B-PT】自我认知助手` |
| Model Card 标题(README H1) | README.md 第一行 | 与模型展示名称完全一致 | `# 【ERNIE-4.5-0.3B-PT】自我认知助手` |
**`{基座模型名称}` 取自 `--list-models` 白名单输出的模型名**(org 前缀后的部分,如 `PaddlePaddle/ERNIE-4.5-0.3B-PT` → `ERNIE-4.5-0.3B-PT`),不要使用产品别名。
**`{model_short}` 推导规则**:取白名单模型名(去掉 org 前缀),全部小写,`.` 去掉,`-` 换 `_`,`_instruct` 后缀省略。示例:`ERNIE-4.5-0.3B-PT` → `ernie45_03b_pt`,`Qwen2.5-7B-Instruct` → `qwen25_7b`,`DeepSeek-R1-Distill-Qwen-7B` → `deepseek_r1_distill_qwen_7b`。
**`{domain}` 拼写规则**:完整英文词组,下划线连接,**不得缩写**(`self_cognition` ✓,`selfcog` ✗;`customer_qa` ✓,`custqa` ✗)。
**`--output-repo` 必须显式传入**,否则平台自动生成 `train_xxxxxxxx`,无法通过模型库名称识别用途。
**`--model-display-name` 必须同步传入**,作为网页展示名称的目标值,便于提交后自动记录和状态提示。
**重要:`--output-repo` 只控制模型英文 ID / repo_id,不控制网页展示名称。** 通过 `--submit --output-repo` 让平台自动创建模型仓库时,AI Studio 会先用 repo 名(如 `qwen25_05b_self_cognition_smoke`)初始化网页「模型展示名称」。因此训练 `succeeded` 后,必须进入 `modelsdetail/{数字ID}/setModel` →「设置」→「基础信息」→「编辑」,把「模型展示名称」改为 `--model-display-name` 指定的中文展示名(如 `【Qwen2.5-0.5B-Instruct】自我认知助手`),再点击「完成编辑」。不要把 README H1 已正确误认为网页展示名称已正确。
**确定 gitlogin 的方法**:查看任一已完成训练的 `modelOutputRepo.modelRepo`(如 `yunlin/train_8265ac9e`,斜杠前的 `yunlin` 即 gitlogin);或通过 AI Studio 网页个人主页确认。
**确认命名空间可写**:只有当前 token 账号对应的 gitlogin 命名空间可写;传入 `--output-repo` 前确认仓库名未与现有非关联模型冲突。
### 提交
```bash
JOB_NAME="ernie45_03b_self_cognition_smoke" # 按本次训练目标替换
OUTPUT_REPO="$GITLOGIN/$JOB_NAME" # 替换 $GITLOGIN 为真实 gitlogin,如 yunlin
MODEL_DISPLAY_NAME="【ERNIE-4.5-0.3B-PT】自我认知助手"
python3 "$SKILL_PATH/scripts/train.py" --submit \
--base-model "PaddlePaddle/ERNIE-4.5-0.3B-PT" \
--train-data "$REPO_ID" \
--train-file "$TRAIN_FILE" \
--name "$JOB_NAME" \
--output-repo "$OUTPUT_REPO" \
--model-display-name "$MODEL_DISPLAY_NAME" \
--params '{"num_train_epochs": 3, "per_device_train_batch_size": 4, "learning_rate": 5e-5, "max_seq_len": 512, "bf16": true}'
```
注意:
- `--train-data` 必须使用数据集详情页显示的完整 `repo_id`,形如 `gitlogin/repo_name`;不要用昵称、展示名、邮箱或自己拼出来的仓库路径
- `--train-file` 强烈建议指定;不传时平台会自动选择数据集目录下首个 JSON/JSONL,只有仓库里训练文件唯一且明确时才可省略
- `--train-file` 的值如果指定,必须和数据集仓库里的实际文件名完全一致(进数据集详情页 → 文件列表确认),写错会导致 `waiting_data` 静默卡住
- 任务名 `--name` 不能含横杠,只能用字母/数字/下划线
- `--name` 只控制训练任务名;`--output-repo` 才控制最终模型仓库路径。如果省略 `--output-repo`,平台可能生成 `train_xxxxxxxx` 这类不可读仓库名
- `--output-repo` 不是必填项;只有确认目标命名空间可写、仓库名未和无关模型冲突时才传,不确定时先省略
- 每账号最多 30 个模型仓库,满了用 `--output-repo` 复用已有仓库或指定一个已有可写仓库
- 模型产物默认按“公开发布”处理:如果网页端或接口出现公开/私密选项,除非用户明确要求私密或数据/模型含敏感内容,否则选择公开。若平台训练完成后自动生成的模型仓库仍显示私密,第一时间提醒用户到 AI Studio 模型库页面把可见性改为公开,并补充模型卡片和协议
- 可视化参数(`report_to`/`visualdl`)由平台后端自动管理,用户传了反而会报"不支持的参数"错误,无需手动传
### 提交后监控与 Tensorboard
提交成功拿到 jobId 后,优先运行持续轮询:
```bash
python3 "$SKILL_PATH/scripts/train.py" --poll JOB_ID
```
`--poll` 会持续打印状态;任务进入 `running` 且接口返回 `tensorboardUrl` 后,会自动打开一次 Tensorboard。这个 URL 可能在 `waiting_data` 阶段提前生成,但不要在训练真正开始前打开空看板。如果没有自动打开,说明任务尚未进入 running 或 Tensorboard URL 尚未生成,可稍后手动运行:
```bash
python3 "$SKILL_PATH/scripts/train.py" --open-tb JOB_ID
```
状态响应规则:
- `waiting_data`:告诉用户平台正在下载/挂载模型和数据集,通常 1-10 分钟;Tensorboard 地址可能已生成,但要等进入 running 后再打开才有内容
- `pending`:告诉用户任务已排队,等待 GPU 分配
- `running`:报告进度、当前 loss,并用 `--train-summary JOB_ID` 解读 loss 趋势
- `succeeded`:运行 `--train-summary JOB_ID` 汇报最终 loss、模型仓库和测试建议
- `failed/cancelled`:必须主动运行 `--diagnose JOB_ID`,结合 system log 说明失败原因
- `waiting_data` 超过 10 分钟:必须主动运行 `--diagnose JOB_ID`;先按上传门禁核对 `repo_id`、`--train-file`、文件大小和下载回验;若 `is_lfs:true`,先修复 LFS 并重提。若这些都通过且 system log 持续卡在数据集下载,按平台 mount 异常处理,不要让用户重复修同一份数据
### 监控进度
```bash
python3 "$SKILL_PATH/scripts/train.py" --status JOB_ID # 查一次
python3 "$SKILL_PATH/scripts/train.py" --diagnose JOB_ID # 主动查状态 + system log + stdout
python3 "$SKILL_PATH/scripts/train.py" --logs JOB_ID # 查 stdout loss
python3 "$SKILL_PATH/scripts/train.py" --logs JOB_ID --system # 单独查 system log
```
状态含义:`waiting_data`(下载中,1-10min)→ `pending`(等 GPU,1-5min)→ `running`(训练中)→ `succeeded`
- `--logs` 查 stdout 是最可靠的 loss 监控方式,ERNIE/LlamaFactory 都支持
- `--diagnose` 是异常排查首选,会主动拉 system log;用于 `waiting_data` 超时、`failed`、`cancelled`、平台挂载/调度问题
- `--train-summary` 会从日志解析 loss/lr 并输出训练趋势,训练完成后依然有效
- Tensorboard 不是完全不可用:优先看 `Scalars` 面板。`Scalars` 能显示 loss/lr 等曲线时,说明 event file 和标量日志基本正常;`Time Series` 空白通常是新版 Tensorboard 面板兼容、前端缓存或加载问题,不等价于日志损坏或训练失败。训练结束后入口仍可能 `INACTIVE` 或部分面板不渲染,不要把 Tensorboard 作为唯一验收依据,优先以 raw log、`--train-summary` 和本地导出的 CSV/PNG 曲线为准
- `logUrl` 是鉴权 API,不是公开网页。浏览器直接打开 `/v1/train/jobs/.../master/output.log` 可能返回 `Missing or invalid Authorization header`;请用 `--logs`、`--export-artifacts`,或带 `Authorization: Bearer $AISTUDIO_ACCESS_TOKEN` 的 requests/curl 拉取日志。Tensorboard 能打开不代表 log API 可匿名访问
- `--poll` 会阻塞终端;对话场景不能长期占用终端时,改为周期性运行 `--status`、`--diagnose`、`--logs`、`--train-summary`
### 训练完成后
运行 `--train-summary` 获取 loss/lr 汇报:
```bash
python3 "$SKILL_PATH/scripts/train.py" --train-summary 训练任务ID
```
训练 `succeeded` 后,先完成训练证据归档,再处理模型卡片与可见性。
**训练证据归档清单:**
- `job_detail.json`:最终任务状态、模型仓库、Tensorboard/log URL
- `master_output_raw.log`:stdout 原始训练日志
- `system_raw.log`:系统日志,用于排查数据挂载/调度
- `train_summary.txt`:`--train-summary` 输出
- `loss_curve.csv`:从 raw log 解析出的 step/loss/lr/ppl 等指标
- `loss_curve.png`、`learning_rate_curve.png`、`training_curves.png`:本地曲线图
- `README.md`:记录 jobId、模型仓库、数据集、训练文件、超参、loss 摘要、Tensorboard 是否可用、任何 compact/截断处理
如果 Tensorboard 页面不可读,但 raw log 能解析出 loss/lr,训练证据仍然成立。最终回复用户时应区分“训练任务成功”和“模型效果已通过推理验收”。
训练 `succeeded` 后,**必须自动完成以下两步,不要等用户提醒**:
#### 第一步:通过 git 自动推送 README
AI Studio 模型仓库支持通过 git 推送。不要把 token 拼到 remote URL;用 `GIT_ASKPASS` 从环境变量读取凭据:
```bash
# REPO_ID 示例:yunlin/qwen25_05b_self_cognition_smoke
cd /tmp && rm -rf model_readme_tmp
ASKPASS_FILE="$(mktemp)"
cat > "$ASKPASS_FILE" <<'EOF'
#!/usr/bin/env sh
case "$1" in
*Username*) printf '%s\n' "$AISTUDIO_ACCESS_TOKEN" ;;
*Password*) printf '%s\n' "$AISTUDIO_ACCESS_TOKEN" ;;
*) printf '%s\n' "$AISTUDIO_ACCESS_TOKEN" ;;
esac
EOF
chmod 700 "$ASKPASS_FILE"
trap 'rm -f "$ASKPASS_FILE"' EXIT
GIT_ASKPASS="$ASKPASS_FILE" GIT_TERMINAL_PROMPT=0 \
git clone "https://git.aistudio.baidu.com/$REPO_ID.git" model_readme_tmp \
--no-checkout --depth=1 --filter=blob:none 2>&1 | tail -3
cd /tmp/model_readme_tmp
git sparse-checkout init --cone
git sparse-checkout set README.md
git checkout
# ⚠️ 重要:sparse-checkout 后 git status 会显示其他文件为"未跟踪"或"已删除"。
# 只能 git add README.md,绝对不能 git add . 或 git add -A,
# 否则会把模型权重等文件当作删除提交,破坏仓库。
# 读取 references/model-card-spec.md,以其为模板填入真实训练数据,用 heredoc 写入:
cat > README.md << 'READMEEOF'
---
license: Apache License 2.0
---
# 【{基座模型名称}】{场景/功能描述}
...(按 references/model-card-spec.md 填充实际值,无法获取的字段整行删除,不留占位符)...
READMEEOF
git config user.email "$GIT_USER_EMAIL" # 替换为真实邮箱,或用 git global config
git config user.name "liuyunlin"
git add README.md
git commit -m "docs: 完善模型卡片 README"
GIT_ASKPASS="$ASKPASS_FILE" GIT_TERMINAL_PROMPT=0 git push origin master
```
**Model Card 内容以 `$SKILL_PATH/references/model-card-spec.md` 为模板生成。** 根据实际训练数据填充各字段;无法获取的字段连同对应行一起删除,不留占位符。
#### 第二步:设置模型展示名称、模型元信息标签 + 确认公开状态
git push 只能更新 README 文件内容,**模型展示名称、标签(多语言、任务方向、训练框架、基座模型)和公开状态必须通过网页端操作**。尤其注意:自动创建仓库时网页展示名称通常会被初始化为 repo 名,必须在本步骤显式改成规范展示名。
**默认标签选择规则**(根据训练场景选择,不要只选"文本生成"一个):
| 维度 | 选择规则 |
|------|---------|
| 多语言 | 中文数据 → **中文**;英文数据 → **English**;混合 → 两个都选 |
| 任务方向 | 问答对 / QA / 知识库 → **问答** + **文本生成**<br>对话 / Chat / 角色扮演 → **文本对话** + **文本生成**<br>分类/NER/抽取 → **文本分类** 或 **命名实体识别**<br>写作/摘要 → **文本生成**<br>医疗/法律/金融等专业领域 → 在以上基础上额外添加对应领域标签 |
| 训练框架 | ERNIE 系列 → **ERNIEKit**;Qwen/LLaMA 等 → **LlamaFactory** |
| 基座模型 | 搜索 base_model 名称(如 `ERNIE-4.5-0.3B-PT`),选中匹配项 |
**操作前必须获取数字 modelId**:先导航到 `https://aistudio.baidu.com/my/models`,用 eval 找到目标模型 `<a>` 标签的 href,从中提取数字 ID(如 `48193`)。**不能用仓库路径 `yunlin/repo_name` 拼 URL**,否则 404,所有操作都打空炮。
**优先使用 CDP(web-access)在设置页直接操作**:导航到 `https://aistudio.baidu.com/modelsdetail/{数字ID}/setModel`,点击「编辑」按钮,用 `execCommand('insertText')` 填写模型展示名称,点「完成编辑」;然后点「设为公开」。
**Playwright MCP 备选**(已验证可行):
```
模型空间 Tab → 模型元信息 区域:
- 模型展示名称:填入 Model Card 标题,格式 `【{基座模型名称}】{场景/功能描述}`,与创建模型时填写的展示名称完全一致,例如 `【Qwen2.5-0.5B-Instruct】自我认知助手`
- 多语言:点击添加 → 按上表选中对应语言 → 确定
- 任务方向:点击添加 → 按上表选中 1-2 个任务标签 → 确定
- 训练框架:下拉选择 ERNIEKit(ERNIE 模型)或 LlamaFactory(开源模型)
- 基座模型:点击添加 → 搜索 base model 名称 → 选中 → 确定
填写 commit 信息 → 点击"完成编辑"保存
```
Playwright 操作要点:
- 弹出的多选框不在 accessibility tree 里,必须用坐标点击:先用 `page.evaluate` 找 span 的坐标,再 `page.mouse.click`
- 训练框架是单选 combobox,直接点选项文本即可,无需确定按钮
- 基座模型有搜索框,在弹窗内找到 `input[placeholder="请输入搜索关键词"]` 并区分它和顶部导航搜索框(用坐标或 index 区分)
- 每个多选弹窗确认后,点"完成编辑"时需要填写 commit 信息,否则提交不会生效
**确认公开状态**(必须主动执行):
`{MODEL_ID}` 是**数字 ID**,不是仓库路径。获取方式:导航到 `https://aistudio.baidu.com/my/models`,找到目标模型卡片,从 `<a>` 标签 href(如 `/modelsdetail/48193?modelId=48193`)提取数字 ID,再拼 setModel URL。
导航到 `https://aistudio.baidu.com/modelsdetail/{数字ID}/setModel`,检查右侧"其他设置"区域:
- 显示"当前模型状态为 **公开**" → 无需操作
- 显示私密 → 点击"设为公开"切换
### LoRA 产物可用性确认
开源模型使用 `SFT/LoRA` 时,训练任务 `succeeded` 不等于产物一定可直接推理。训练结束后必须确认平台是否完成 **LoRA 合并导出**,而不是只上传 adapter。
检查顺序:
1. 查 system/stdout 日志,确认出现类似 `LoRA 合并配置 export_config.yaml 已生成`、导出/上传模型文件完成等信息
2. 查模型仓库文件,确认至少有 `model.safetensors`、`config.json`、`tokenizer.json`、`tokenizer_config.json`、`generation_config.json` 等直接推理所需文件
3. 用 AiStudio API 对最终模型仓库做一次最小调用测试,确认 `errorCode: 0` 且能返回正常文本
示例(避免把 token 展开到 `curl` 命令行参数中):
```python
import os
import requests
resp = requests.post(
"https://aistudio.baidu.com/llm/lmapi/v1/chat/completions",
headers={
"Content-Type": "application/json",
"Authorization": f"token {os.environ['AISTUDIO_ACCESS_TOKEN']}",
},
json={
"model": "gitlogin/model_repo",
"messages": [{"role": "user", "content": "1+1等于几?只输出答案。"}],
},
timeout=60,
)
print(resp.json())
```
判断标准:
- 如果模型仓库只有 LoRA adapter 文件,没有完整权重/配置/tokenizer,不能直接按完整模型调用;需要平台完成合并导出,或另走 adapter 加载流程
- 如果 API 调用成功,说明产物可作为完整模型使用;但可见性需到模型库网页确认,若仍私密则提醒用户改为公开
- 最终答复用户时要区分”训练任务成功”和”模型产物已实测可用”
---
## 常见错误速查
| 错误 | 原因 | 解决 |
|------|------|------|
| `waiting_data` 超过 10 分钟 | 常见根因:仓库/路径不对、文件名写错、LFS 指针、平台挂载异常 | 按序排查:1)确认 `repo_id` 来自详情页;2)核对 `--train-file` 和仓库实际文件名;3)确认文件大小接近本地文件;4)若 `is_lfs:true`,优先修复为普通 JSON/JSONL;5)下载回验 `--check-data`;6)若 system log 仍循环“正在等待数据集下载完成...”,说明可能是平台内部的数据集挂载任务卡住,保留 jobId 给平台排查,或取消后稍后重提 |
| 提交时报数据集权限错误 | 常见不是公开权限问题,而是仓库路径不对、`gitlogin` 不匹配或文件没传成功 | 确认真实 `gitlogin` 和完整 `repo_id`,用新版数据集仓库重新上传 |
| "非 ERNIE 格式" | Alpaca 格式,或 src/tgt 值是字符串非列表 | `{"src": ["问题"], "tgt": ["回答"]}` |
| "类型错误:期望 float,实际 str" | 超参数是字符串 | 去掉引号:`3` 不是 `"3"` |
| "PaddleFormers 仅支持 SFT/Full" | ERNIE 传了 LoRA | `--train-type "SFT/Full"` |
| 任务名报错 | name 含横杠 | 改用下划线 |
| 模型库满 | 超过 30 个仓库 | 删旧仓库或 `--output-repo` 复用 |
| 训练完成后模型上传失败 | `gitlogin` 或 `--output-repo` 命名空间不可写/未初始化 | 用 web-access/CDP 创建一个空数据集仓库初始化命名空间;确认 `--output-repo` 前缀是可写 `gitlogin` 后重新提交 |
| 微调后的模型再训练报错 | 平台白名单只允许官方模型 | 只能从官方基础模型重新训练,迭代时合并数据集 |
| code=401 | Token 过期 | 重新获取 Access Token |
| 文件选择不符合预期 | 未传 `--train-file`,平台自动选择了首个 JSON/JSONL;或文件名写错 | 显式加 `--train-file 文件名.jsonl` |
```bash
python3 "$SKILL_PATH/scripts/train.py" --cancel JOB_ID # 取消卡住的任务
```
---
## 脚本参数速查
```
--env-check 检查本地环境(Python 版本、依赖、网络)
--verify-token 验证 Token
--list-models 列出可用模型(白名单)
--list-datasets 列出内置推荐数据集
--check-data <file> 检查数据格式
--verify-upload --train-data REPO_ID --train-file F [--local-file FILE]
验证上传结果并打印上传完成回执
--suggest-params <file> [--model-type ernie|llama] 推荐超参数
--submit ... 提交训练任务
--base-model MODEL 基底模型
--train-type TYPE 训练类型(默认 SFT/Full;可选 SFT/LoRA)
--train-data REPO_ID 数据集仓库路径,必须是详情页真实 repo_id,形如 gitlogin/repo_name
--train-file FILENAME 数据文件名(如 train.jsonl)
--params JSON 超参数 JSON 字符串
--name NAME 任务名称(只允许字母、数字、下划线)
--model-display-name NAME 模型网页展示名称目标值;不等于 --output-repo,succeeded 后需网页校验/补改
--output-repo GITLOGIN/REPO 模型输出仓库(可选,超过 30 个仓库时复用;命名空间必须可写)
--max-run-time HOURS 最长运行时间(小时,1-240)
--status <job_id> 查看任务状态
--logs <job_id> [--system] 查看训练日志(stdout loss)
--diagnose <job_id> 主动诊断状态、system log 和 stdout
--train-summary <job_id> 训练完成后汇报 loss/lr 趋势和健康状态
--poll <job_id> 持续轮询(阻塞终端,对话场景不推荐)
--cancel <job_id> 取消任务
--api-key TOKEN / --env-file FILE 仅本地手工调试;自动化流程优先用环境变量
--base-url URL
```
---
## References 索引
| 文件 | 何时加载 |
|------|---------|
| `references/datasets.md` | 用户没有自己的数据,或问"用什么数据集好"时,先读此文件再推荐 |
| `references/aistudio_sdk_upload.md` | 需要用 SDK 上传数据集时 |
| `references/model-card-spec.md` | 训练 `succeeded` 后生成 README.md(Model Card)时读取,即 README 模板,填充后直接推送 |
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!