这类问题我又碰上了一次。outlines 0.1.4 配 transformers 4.44 加载本地 Qwen2.5-7B,用 generate.json 换成 regex(r"\d{4}-\d{2}-\d{2}") 约束输出,请求跑了三十秒不返回,最后给出空字符串,GPU 占用一直是满的。
第一反应是「max_tokens 设得太小,还没走到日期就被截断」,验证下来不成立。
排查方向其实有限,先把可能性排一排。正则允许无限延续,状态机始终不进入终止态;模型的词表切分与正则的字符粒度对不上,找不到可走的 token;batch 采样与 FSM 索引选择器同时开着,逻辑索引错位。
动手时先用最短的固定串验证约束链路是否通
python -c "import outlines;m=outlines.models.transformers('Qwen/Qwen2.5-7B-Instruct');print(outlines.generate.regex(m,'2024-01-01'))"
接着把约束换成有限枚举,排除状态机问题
python -c "import outlines;print(outlines.generate.choice(outlines.models.transformers('Qwen/Qwen2.5-7B-Instruct'),['2024-01-01','2024-06-30']))"
显式限制生成长度并只跑单条
python -c "print({'max_tokens':16,'batch':1})"
末了改回 json 结构约束,由业务层校验日期格式
python -c "import outlines;print(outlines.generate.json(outlines.models.transformers('Qwen/Qwen2.5-7B-Instruct'),{'date':'string'}))"
怎么算真的好了,看的是同一批现象。同样的输入在两秒内返回 2024-01-01,格式校验通过,GPU 占用回落到正常推理水平。
补一句。正则约束看着最精确,实际上对词表最不友好,能用枚举或 JSON 结构表达的就别写正则,尤其是日期、金额这类边界很宽的模式。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
