先看现象。训练集用 messages 数组,验证集是从旧项目拿的 prompt/completion 结构 jsonl,创建 job 时 400,原文 validation file has an invalid format,两份文件都能正常解析成 JSON。
排查方向其实有限,先把可能性排一排。训练集和验证集必须是同一种结构,一个 messages 一个 prompt 会直接判非法。也可能是验证集条数太少,低于接口要求的下限。
少数情况下是验证集上传时 purpose 选错,必须是 fine-tune。
不容易想到的是,文件末尾缺换行或夹了空行,解析到一半就报格式错。
上来先比对两份文件首行的键名
python -c "import json;print(list(json.loads(open('train.jsonl').readline()).keys()),list(json.loads(open('val.jsonl').readline()).keys()))"
随后把 prompt/completion 转成 messages 结构
python -c "import json;d=json.loads(open('val.jsonl').readline());print(json.dumps({'messages':[{'role':'user','content':d['prompt']},{'role':'assistant','content':d['completion']}]},ensure_ascii=False))"
接着用同一个脚本切出两份保证结构一致
python convert.py --input raw.jsonl --out train.jsonl --split 0.9 --val val.jsonl
末了验证集同样以 fine-tune 用途上传
curl https://api.openai.com/v1/files -H "Authorization: Bearer $OPENAI_API_KEY" -F purpose=fine-tune -F file=@val.jsonl
恢复的判定其实很直接。job 创建返回 200,validation_file 的 id 能在文件列表里查到且 bytes 匹配,训练开始后 events 里出现 valid_loss 数值。
提醒一点。两份文件最好出自同一个转换脚本,手工拼的验证集最容易在键名和角色上出偏差,报错文案只说格式无效,不会指出差在哪个字段。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。
