现场是这样的。上传 1200 条数据建 job,控制台只显示 failed 一个词,事件列表里也只有状态变化,账单里训练费用已经扣掉,完全不知道从哪查起。

中间走过弯路,把「训练数据里有超长样本,被截断后整批校验不通过」当成主因,改完现象没变。

真正麻烦的地方在于,几个原因的现象几乎一样。失败原因写在 job 详情的 error 字段,列表接口不带这个字段;逐条错误在 result_files 的错误文件里,要下载才知道哪行有问题;用了不支持微调的模型快照,创建能过,开始训练才失败。

取 job 详情的 error 与状态字段

curl -s https://api.openai.com/v1/fine_tuning/jobs/ftjob_abc -H "Authorization: Bearer $OPENAI_API_KEY" | jq '.status,.error'

随后列出这次任务产出的文件 id

curl -s https://api.openai.com/v1/fine_tuning/jobs/ftjob_abc -H "Authorization: Bearer $OPENAI_API_KEY" | jq -r '.result_files[].id'

下载错误文件看前几条

curl -s https://api.openai.com/v1/files/$FID/content -H "Authorization: Bearer $OPENAI_API_KEY" | head -5

剩下的就是把长度异常的样本过滤掉再提交

python -c "import json;[print(i,len(json.dumps(json.loads(l),ensure_ascii=False))) for i,l in enumerate(open('train.jsonl'))][:5]"

别只看报错消失,验证要多做一步。job 详情里 error 为 null 且 status 到 succeeded,输出模型出现在模型列表,失败任务的错误文件能在本地复盘到具体行号。

容易忽略的是,failed 不代表免费,训练 token 已经消耗,先看 error 再重跑,否则同一份坏数据会连着烧三次钱。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189