OpenAI Curie模型微调因Token超限失败,求解决方法
解决OpenAI Curie微调时的"训练样本超出token限制"问题
核心问题分析
错误提示明确说明:训练文件中符合Curie模型2048token限制的有效样本数量不足。虽然训练文件显示已处理,但大部分样本的prompt+completion总长度超过了模型的上下文窗口阈值,导致可用训练样本数达不到要求。
具体解决步骤
1. 批量检查并过滤超长样本
编写脚本统计每个样本的token总数,直接过滤掉总长度超过2048token的条目:
import tiktoken import json def count_tokens(text, model="curie"): encoding = tiktoken.encoding_for_model(model) return len(encoding.encode(text)) # 加载训练数据(假设为JSONL格式,每行一个样本) with open("training_data.jsonl", "r", encoding="utf-8") as f: training_data = [json.loads(line) for line in f] # 筛选符合token限制的样本 filtered_data = [] for item in training_data: total_tokens = count_tokens(item["prompt"] + item["completion"]) if total_tokens <= 2048: filtered_data.append(item) # 保存过滤后的数据 with open("filtered_training_data.jsonl", "w", encoding="utf-8") as f: for item in filtered_data: json.dump(item, f) f.write("\n") print(f"过滤后剩余有效样本数:{len(filtered_data)}")
确保过滤后剩余的有效样本数满足微调最低要求(至少10个以上,建议保留更多以保证效果)。
2. 对超长Completion内容截断处理
如果不想丢弃样本,可以针对性截断过长的completion部分,同时保证JSON结构完整:
import tiktoken import json def truncate_completion(prompt, completion, max_total_tokens=2048, model="curie"): encoding = tiktoken.encoding_for_model(model) prompt_tokens = len(encoding.encode(prompt)) available_tokens = max_total_tokens - prompt_tokens if available_tokens <= 0: return None # 连prompt都超限制,直接丢弃该样本 # 截断completion到可用token数 completion_encoded = encoding.encode(completion) truncated_completion = encoding.decode(completion_encoded[:available_tokens]) # 尝试修复不完整的JSON结构 try: json.loads(truncated_completion) return truncated_completion except: truncated_completion = truncated_completion.rstrip(",") + "}" try: json.loads(truncated_completion) return truncated_completion except: return None # 无法修复则丢弃 # 处理训练数据 processed_data = [] for item in training_data: truncated_comp = truncate_completion(item["prompt"], item["completion"]) if truncated_comp: processed_data.append({"prompt": item["prompt"], "completion": truncated_comp}) # 保存处理后的数据 with open("processed_training_data.jsonl", "w", encoding="utf-8") as f: for item in processed_data: json.dump(item, f) f.write("\n")
3. 确认数据格式合规
确保训练文件是JSONL格式(每行一个独立的JSON对象),而非单个大JSON数组。即使文件显示已处理,格式错误也可能导致有效样本被误判。
4. 重新上传并启动微调任务
将过滤/处理后的文件重新上传,启动新的微调任务:
import openai openai.api_key = "your_api_key" # 上传处理后的文件 upload_response = openai.File.create( file=open("filtered_training_data.jsonl", "rb"), purpose="fine-tune" ) # 创建新的微调任务 fine_tune_response = openai.FineTune.create( training_file=upload_response["id"], model="curie" ) print(f"新微调任务ID:{fine_tune_response['id']}")
额外注意事项
- Curie模型的上下文窗口固定为2048token,
prompt+completion总长度必须严格控制在该范围内 - 如果业务确实需要长输出,可以考虑切换到支持更大上下文的模型(如GPT-3.5-turbo-instruct,支持4096token),但需注意微调成本变化
内容的提问来源于stack exchange,提问作者user1180944
相关产品推荐
相关产品推荐

