
移动开发学习簿
Lv.1Digitalbuilder,记录从构想到上线的过程,技术方向以软件工程为主。持续整理代码实现与工程实践、开发效率提升和可复用的工程方法;习惯用项目结果检验技术判断。
发表的评论
我一般会把每个chunk前面标上序号和来源,然后让模型回答时引用编号,这样它不容易把无关内容混进来。你说加“不知道”之后变保守,可能是没给模型留“部分回答”的余地,可以改成“资料里没有的部分明确说没有,有提到的正常答”。另外system prompt里最好把“只依据资料”和“允许合理归纳”的边界写清楚,太死或太松都容易翻车。
别硬靠Prompt卡流程,试试用LangGraph把步骤拆成节点,每步输出校验后再往下走。
ResNet-50掉4个点不太正常,一般纯转ONNX精度损失在千分位。先别急着怀疑算子,建议逐层对比PyTorch和ORT的输出,大概率是某个op的数值行为不一致,比如 AdaptiveAvgPool 在动态shape下容易出问题。另外检查下预处理,mean/std和resize方式两边是否完全对齐,这个坑踩过好几次。移动端的话4个点确实有点多,但先定位到具体层再决定要不要换TFLite也不迟。
loss卡在0.3其实挺常见的,指令微调本来就不像预训练那样能压到很低,模型在拟合你QA格式的分布而已。关键还是看下游任务的实际表现,生成流畅、答案靠谱就说明LoRA学到东西了。建议你多做点人工评测或者搞个小测试集算一下准确率,比盯着loss有用。5000条对运维问答来说不算多,如果效果还差点意思,优先补数据多样性,别急着换方法。
我之前也动过把训练管线从PyTorch搬去JAX的念头,折腾了两周最后还是退回来了。编译时间长这个事真不是错觉,模型一复杂,每次改点结构就得重新jit,等编译的时间都够我跑好几轮实验了。速度上确实有提升,但没到网上吹的那种翻倍,大概快个百分之二三十,可这是在编译稳定、shape不频繁变的前提下,实际做研究时改来改去,这点优势基本被抵消了。自定义算子和动态控制流在JAX里确实麻烦,vmap和jit对
这个坑我也踩过,代码片段的向量相似度有时候真的挺玄学的,Flask和FastAPI写路由那几行,embedding出来几乎分不开,光靠调阈值肯定治标不治本。我后来是在入库前给每个chunk的metadata里塞一个framework字段,检索时直接把filter条件带上,比如where framework == 'flask',这比事后调阈值靠谱多了。打标这事其实不用手动,你们内部代码仓库里文件路
这个问题挺常见的,我之前的客服Agent也遇到过类似情况,聊到六七轮之后模型就开始放飞自我了。后来我发现光在system里写“只回答产品问题”其实约束力有限,因为随着对话变长,system的权重会被后面堆积的user/assistant消息稀释掉。我现在的做法是在每轮请求时把system message放在最前面,同时在最后一条user消息后面追加一个隐式的“检查点”,比如让它先判断当前问题是否属
这个问题挺典型的,我一开始也踩过类似的坑。你描述的“一调用工具就慢”其实大概率不是 Function Calling 解析本身的问题,Qwen2.5-7B 的 tool call 解析开销远没到几十秒级别。更可能的是 agent 框架在每一轮都把完整对话历史加上工具描述重新塞进 prompt,导致上下文暴涨,prefill 阶段直接拖垮响应。vLLM 默认配置下如果没开 chunked prefi
我之前也踩过这个坑,光靠prompt里写“必须按步骤来”基本没用,模型该跳步还是跳步。后来我改成用LangGraph把流程拆成节点,每步的输出单独存state里,下一步只能读上一步的结果,这样它就没法乱来了。另外日报这种任务其实可以给每步加个校验,比如分析没输出关键词就直接打回重跑。你可以先试试把流程控制从prompt里抽出来,交给代码管,会稳很多。
我也遇到过这问题,Cursor补全短变量还行,一长就容易自作主张。后来我把常用的变量名在文件开头用注释列了个“命名清单”,补全时它明显老实多了。还有个偏方是写的时候故意打全名再按Tab,别让它有机会猜。实在不行就去设置里把补全触发调保守点,牺牲点速度换准确率。
感觉问题不在框架,是任务拆得太细,模型每步都在赌。先试试把决策点收敛到两三个,跑不通再谈换不换。
同感,我博一那会儿也是两边横跳,后来干脆把TF1.x当“历史遗迹”处理,只维护能跑就行,新东西全用PyTorch写。其实框架语法忘得快很正常,但计算图和自动求导这些底层逻辑是通的,切换时别死记API,想想数据怎么流动会快很多。要是导师不强制,建议主攻PyTorch,TF1.x的代码能看懂、能改通就够了,部署那套等真进工业界再补也来得及。
让AI先写纯函数组件再手动补Tailwind类名,我试过这招确实稳很多,它凭空造结构就是提示词管不住的。
试试调低temperature或换Q5量化,7B写长函数确实容易断片。
我前段时间也踩过这个坑,PDF技术手册这种结构化文档直接按固定长度切真的很容易出问题,因为手册里经常是“参数说明+配置示例+注意事项”连在一起,你一刀切下去可能把关键上下文切没了。500这个粒度其实不算大,但overlap只给50有点抠,建议先提到100左右试试。另外你说的召回不准,大概率不是单一原因,embedding模型对中文技术文档的语义捕捉本身就参差不齐,可以换成bge-m3或者m3e这类
我也踩过这个坑,torch.compile 碰上 ReAct 那种边跑边拼 prompt 的循环基本就是灾难,graph break 多到怀疑人生,最后性能还不如直接 eager 跑。我的做法是把 compile 的范围缩到最小,只包住真正吃算力的那段纯前向,也就是 input_ids 已经定下来之后的那部分,工具调用、prompt 拼接、KV Cache 的搬运全放在外面用 eager 管。KV
我后来改成只在需要多步推理或者工具选择有歧义的时候才要求输出Thought,简单调用直接给Action,跑下来稳定不少。强制每步都写Thought确实容易让模型为了凑格式硬编理由,尤其是小模型更明显。你可以试试按任务复杂度动态控制,或者把Thought换成更轻量的“理由”字段,别让它写太长。
我之前也踩过这个坑,后来发现罪魁祸首是streamer里攒着的token id没清,每次工具返回都往列表里塞,越堆越长。你可以在每轮generate结束后手动把streamer的缓存和past_key_values置空,另外检查下是不是每次都在往新list里append张量。还有种可能是Python引用没断,gc.collect()配合empty_cache()一起上会好很多。
这情况挺像典型的显存碎片问题,尤其你换了SGD+momentum之后,优化器状态的内存分配模式变了,虽然理论占用更小,但分配时机不同很容易让缓存碎片化。gradient checkpointing只在forward开的话,backward阶段重计算时还是会额外占显存,如果恰好赶上碎片多的时刻就容易炸。可以试试在训练循环里定期调torch.cuda.empty_cache(),或者设PYTORCH_
试试加个意图路由再检索,直接拿问题去匹配容易串味。