CLI Trainer Skill
帮助用户在 AI Studio 云端完成大模型微调,不需要 GPU、不需要搭环境、不需要写训练代码。
用 scripts/train.py 执行所有平台交互,脚本路径通过 $SKILL_PATH 引用:
python3 "$SKILL_PATH/scripts/train.py" --check-data my_data.jsonl
!! 绝对禁止事项(最高优先级)
- 禁止自己猜测或硬写超参数然后提交。 必须先运行
--suggest-params,把推荐值展示给用户,等用户确认再提交。 - 禁止在用户明确确认前调用
--submit。 展示参数时逐行解释含义,问”需要调整哪些?没问题就提交”,等用户回复。 - 禁止把推荐参数当作默认训练配置直接提交。 训练方式默认
SFT/Full;除非用户明确要求SFT/LoRA,否则不要传--train-type,也不要提交lora_rank、lora_alpha、lora_dropout等 LoRA 专属参数。--suggest-params --model-type llama的输出可能包含 LoRA 字段,展示给用户前必须按实际train_type过滤并说明。 - 训练方式变化时必须同步调整超参数。 从
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。
执行顺序
- 环境自检 — 首次使用时先跑一次,自动检测 Python 版本、依赖包、网络连通性,requests 缺失会自动安装
- 鉴权 — 确认有 Access Token,没有就引导去 https://aistudio.baidu.com/account/accessToken 获取
- 选模型 — 运行
--list-models展示白名单,让用户选,不要让用户自己猜名称 - 验数据 — 运行
--check-data检查格式,提前发现错误 - 准备/上传数据集 — 只能访问 AiStudio 新版 Git 仓库型数据集,不支持外部 URL。创建仓库时先确认真实
gitlogin;用 Playwright MCP 或web-accessskill 创建仓库并拿到真实repo_id;上传前优先删除.gitattributes中的 JSON/JSONL LFS 规则,上传后记录is_lfs状态并确认文件大小。 - 推荐超参 — 运行
--suggest-params,展示结果,等用户确认后才提交 - 提交训练 — 运行
--submit,拿到 jobId - 监控训练 — 提交后运行
--poll JOB_ID;任务进入 running 且接口返回tensorboardUrl后自动打开 Tensorboard - 取结果 — 训练完成后给出模型仓库地址和训练摘要
各步骤关键细节
环境自检
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 / Codex 推荐安装 Playwright MCP
自建数据集、网页端创建数据集仓库、必要时初始化 Gitea 或操作登录后网页时,不要只固定使用一种浏览器方案。这里按"通用 web-access / Codex 推荐安装 Playwright MCP"处理:Codex 环境优先安装/启用 Playwright MCP;需要复用用户日常 Chrome 登录态时,再使用 web-access。目标是拿到页面详情页真实 repo_id 并完成必要的 .gitattributes 编辑;优先选择当前可用、已登录、最少阻塞的浏览器自动化能力。
推荐顺序:
- Playwright MCP 可用且页面已登录时优先使用。 适合打开 AI Studio 页面、创建数据集、填写表单、选择协议、编辑
.gitattributes、读取repo_id。常用能力:browser_navigate、browser_snapshot、browser_click、browser_fill_form、browser_evaluate。它不依赖用户 Chrome 的 remote debugging 授权,CDP 授权卡住时尤其适合。 - 需要用户日常 Chrome 登录态时使用
web-access。 如果 Playwright 未登录、页面需要真实 Chrome cookie/扩展/特殊会话,加载web-accessskill 并启动 CDP Proxy。 - 两者都不可用时再让用户手动创建仓库。 此时给出最短步骤,并要求用户回传详情页真实
repo_id,不要猜。
进入上传/建仓步骤前,若选择 web-access,按下面流程检查并准备它。
准备顺序:
- 如果当前会话可用
web-accessskill,先加载它并遵循其SKILL.md - 如果 skill 元数据没触发,但
$HOME/.codex/skills/web-access/SKILL.md存在,直接把WEB_ACCESS_SKILL_PATH指向该目录并运行scripts/check-deps.sh - 如果目录不存在,先使用
skill-installer安装web-access。安装完成后可立即用安装目录下的scripts/check-deps.sh;同时告诉用户重启 AI IDE / 刷新 Agent 会话后才能自动识别新 skill - 如果安装失败或 Chrome 远程调试授权不可用,才退回让用户手动在网页创建数据集仓库
检查命令:
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 命令:
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 先检查环境变量。
选模型
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 值必须是列表):
{"src": ["问题"], "tgt": ["回答"]}
最常见错误:用了 Alpaca 格式,任务会跑起来但 poller 阶段报"非 ERNIE 格式"。
LlamaFactory 格式 1:Alpaca(支持 JSONL 或 JSON 数组):
{"instruction": "问题", "input": "", "output": "回答"}
JSON 数组文件也可检查,常见文件名是 alpaca_data.json:
[{"instruction": "问题", "input": "", "output": "回答"}]
LlamaFactory 格式 2:ShareGPT(支持 JSONL 或 JSON 数组):
{"conversations": [{"from": "human", "value": "问题"}, {"from": "gpt", "value": "回答"}]}
OpenAI messages 也属于 ShareGPT 特例,但平台兼容性不确定时,优先转成 conversations/from/value。
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 负责最终验收。
准备 web-access/CDP
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。创建或确认数据集仓库
- 在
https://aistudio.baidu.com/my/dataset创建或打开数据集仓库。创建时需填写:- 数据集英文ID(必填):用小写字母、数字、下划线,形如
yunlin/my_dataset - 数据集展示名称(选填):面向社区展示,建议填写,描述数据集用途,最多 50 字
- 开源协议(必选):允许商用选 Apache 2.0;有归因要求选 CC BY 4.0;不选则创建可能静默失败
- 数据集英文ID(必填):用小写字母、数字、下划线,形如
- 创建或打开仓库后,从详情页读取完整
repo_id,形如gitlogin/repo_name。不要用昵称、展示名、登录用户名或邮箱猜gitlogin。 aistudio upload/aistudio_sdk.hub.upload_file只上传到已有数据集仓库,不会自动创建 dataset repo。如果上传时报preupload404,优先检查仓库是否已在网页端创建、repo_id是否来自详情页、token 是否对该仓库有写权限、仓库类型是否为 dataset。- 如果传
--output-repo,斜杠前半段必须和当前账号可写的gitlogin匹配。
- 在
上传前处理 JSON/JSONL 的 LFS 规则
- 预防优先:新仓库创建后、上传训练文件前,进入数据集详情页 → 文件列表 →
.gitattributes→ 编辑,删除训练文件扩展名对应的 LFS 规则,例如*.jsonl filter=lfs ...或*.json filter=lfs ...,然后保存。 - ERNIE 的
src/tgtJSONL、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 方案重新上传。
- 预防优先:新仓库创建后、上传训练文件前,进入数据集详情页 → 文件列表 →
上传前检查文件大小:普通文件超过 5MB 平台会拒绝,不要改走 LFS 绕过限制。超过 5MB 时先告知用户,可选:裁剪过长样本、减少数据量、拆分批次。
用 SDK 上传数据集文件夹(推荐)
- 上传原则见
references/aistudio_sdk_upload.md;主规则是:完整repo_id、一仓一数据集、token 只走环境变量、JSON/JSONL 优先不走 LFS。 - SDK 日志出现
201和Commit part 1 successful!才算提交成功;STS 分支的已知回退报错不单独视为失败。 - 上传后必须继续执行本上传小节第 6 步;不要只看 SDK 上传日志。
- 上传原则见
用 CLI 上传单个训练文件(备选)
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。如果出现preupload404,回到本上传小节第 2 步确认仓库已存在且路径无误。 上传命令成功返回后,必须立刻主动告诉用户:训练文件已上传到哪个repo_id、仓库内文件名是什么、接下来会做is_lfs和下载回验;不要等到提交训练后才暴露上传问题。验证上传结果
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"
- 数据集:
卡在
waiting_data时按顺序排查REPO_ID是否来自详情页,gitlogin是否真实可写--train-file是否和仓库内文件名完全一致- 训练文件大小是否接近本地文件;若
is_lfs:true,优先修复为普通 JSON/JSONL 后重试 - 下载回本地后
--check-data是否通过 - 如果新 commit 和新
mount Job仍循环”正在等待数据集下载完成...”,通常是平台挂载任务卡住;停止反复重传,保留 jobId、repo_id、commitId、mount Job 和上传校验结果给平台排查。
为数据集仓库推送 README
数据集仓库创建并验证上传通过后,必须自动写一份 README.md 并推送,方式与模型仓库相同(
GIT_ASKPASS+ sparse-checkout),remote 地址换成https://git.aistudio.baidu.com/$REPO_ID.git。README 以平台标准模板为基础,填入真实信息;无法获取的字段整行省略,不留占位符。
推荐超参并确认
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-65e-4,小模型(0.5B-3B)推荐 5e-5,大模型(7B+)推荐 1e-53e-5 |
num_train_epochs |
float | 3.0 |
训练轮次,数据量小可适当增大 |
per_device_train_batch_size |
int | 2 |
单卡 batch size,0.5B 可用 28,7B+ 建议 12 |
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 前确认仓库名未与现有非关联模型冲突。
提交
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 后,优先运行持续轮询:
python3 "$SKILL_PATH/scripts/train.py" --poll JOB_ID
--poll 会持续打印状态;任务进入 running 且接口返回 tensorboardUrl 后,会自动打开一次 Tensorboard。这个 URL 可能在 waiting_data 阶段提前生成,但不要在训练真正开始前打开空看板。如果没有自动打开,说明任务尚未进入 running 或 Tensorboard URL 尚未生成,可稍后手动运行:
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 异常处理,不要让用户重复修同一份数据
监控进度
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 汇报:
python3 "$SKILL_PATH/scripts/train.py" --train-summary 训练任务ID
训练 succeeded 后,先完成训练证据归档,再处理模型卡片与可见性。
训练证据归档清单:
job_detail.json:最终任务状态、模型仓库、Tensorboard/log URLmaster_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 从环境变量读取凭据:
# 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 / 知识库 → 问答 + 文本生成对话 / Chat / 角色扮演 → 文本对话 + 文本生成分类/NER/抽取 → 文本分类 或 命名实体识别写作/摘要 → 文本生成医疗/法律/金融等专业领域 → 在以上基础上额外添加对应领域标签 |
| 训练框架 | 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。
检查顺序:
- 查 system/stdout 日志,确认出现类似
LoRA 合并配置 export_config.yaml 已生成、导出/上传模型文件完成等信息 - 查模型仓库文件,确认至少有
model.safetensors、config.json、tokenizer.json、tokenizer_config.json、generation_config.json等直接推理所需文件 - 用 AiStudio API 对最终模型仓库做一次最小调用测试,确认
errorCode: 0且能返回正常文本
示例(避免把 token 展开到 curl 命令行参数中):
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 |
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 模板,填充后直接推送 |