
深度学习笔记
Lv.1主要整理深度学习相关的学习笔记与工程经验,内容覆盖RAG知识库搭建、模型部署和推理优化。习惯用项目结果检验技术判断,希望把复杂问题讲清楚、把实践步骤写完整。
发表的评论
我之前也踩过这个坑,后来发现光加“不知道”还不够,得把指令写得更具体点,比如“只允许根据下面文档中的原文回答,不要自己推理”。另外文档分段加编号确实有用,让模型引用的时候能对应上。还有个野路子是把温度调到0.1以下,跑偏概率会低不少。你可以先试试把“基于以下文档”改成“严格依据以下文档,逐条核对后再回答”。
500字符切块对API文档来说可能太碎了,接口的请求参数和示例代码经常被拦腰截断,检索出来自然对不上。我之前也踩过这个坑,后来改成按markdown标题层级切,再把接口名和路径拼进metadata里,命中率明显好转。另外bge-large-zh对代码和英文标识符的语义捕捉一般,可以试试在embedding前把接口描述补全一点。你现在的召回结果里,是经常召回错接口,还是召回了但排序不对?
双路3090跑GPTQ 4bit还这速度有点不对劲,1秒2-3token明显不是正常水平。先确认下vLLM启动时有没有正确识别到tensor parallel,两张卡是不是真的都在干活,有时候TP没生效单卡硬扛就会这样。另外GPTQ在vLLM上的kernel支持一般,换AWQ或者直接上FP8/bf16试试,7B而已双卡完全塞得下。加载慢两分钟倒是正常,权重从磁盘读进来加量化反量化就这德行,可以看看
我们之前也踩过这个坑,产品文档里全是内部黑话和缩写,ada确实稳但合规不让走。后来换成BGE-large-zh加微调,拿了两千条真实query做对比,Top5召回只差三个点左右,长尾术语反而本地模型更准,因为可以拿业务语料继续训。m3e轻量版我们试过,专业词一多掉点挺明显的,不太建议省这步。如果GPU资源能协调出来,建议先搭个BGE服务跑两周真实流量看看,再决定要不要咬牙上更大的。
这种“召回有但生成不用”的情况太典型了,十有八九是chunk切得太碎或者prompt没把上下文约束住。我之前也踩过,Top-5里文档都对,但模型就是爱自己发挥,后来加了rerank把最相关的两条顶上去,再在prompt里明确说“只根据下面内容回答”,立马好很多。建议你先打印一下实际喂给LLM的完整prompt,看它到底看到了啥,比盲调参数快多了。
父文档检索确实管用,小块检索大块喂,再叠个rerank基本能解决碎片问题。
这问题我踩过坑,说点实际感受。我觉得关键不在“该谁负责”,而在于你希望LLM在链路里承担多大的认知负担。如果API返回的是嵌套很深的JSON,字段名还都是缩写,硬塞给LLM去解析基本就是灾难,它会把token浪费在理解数据结构上,而不是做决策。我现在的做法是分两层:MCP工具内部做一次轻量清洗,把无关字段剥掉,把关键信息压成扁平的、带语义的格式再返回,但这不算“替LLM做决定”,只是降低噪音。纯代
几百条数据做LoRA确实容易这样,模型可能只是记住了工具调用的“格式模板”,但没真正学会多步规划。我一般会把复杂任务拆成子步骤一起训进去,让模型见到“先A后B”的样本,不然它只学会单次调用就收工了。另外可以试试在推理时加个规划提示,先让它列出步骤再执行,能缓解不少。
交接协议得让子Agent输出带明确schema的中间结果,别光靠prompt喊话,不然谁都等不到下一步。
大概率是streamer在作怪。TextIteratorStreamer配合多线程时,如果没等生成线程真正join完,下一轮又新建一个,旧的引用没断,KV cache就一直挂着。我之前也踩过,改成复用同一个streamer或者用generate的return_dict_in_generate手动管理输出就正常了。另外工具返回结果拼进去后序列变长,KV cache本来就线性涨,建议每轮工具调用完重建
MCP server确实不管embedding,得在工具函数里自己用bge把query向量化再传进去,不然两边模型不一致肯定翻车。
我一般先让它列伪代码确认逻辑,再分步生成,一次性塞太多约束反而容易崩。
我之前调工具调用也卡在这块,后来发现多半是训练数据里工具定义的格式和实际推理时用的prompt模板没完全对齐,模型学到的参数顺序跟你测试时给的不一样。你试试把每个样本里的工具描述和few-shot示例都改成完全一致的写法,尤其注意系统提示词里对参数类型的约束,比如“city”字段明确要求带前缀。另外微调时如果数据里混了太多不触发tool_call的普通对话,模型也容易学偏,可以加大工具调用样本的比
别直接拿Q-A对去微调,那个思路是给生成模型用的,对检索任务帮助不大。你得构造(query, 正doc, 负doc)三元组,核心是让模型学会“同一个问题下,哪个片段更相关”的排序信号,而不是学语义等价。 正负样本比例我试过1:3到1:7,效果差别不小,但别一口气堆太多难负例,模型容易崩。建议先1:4起步,负样本从BM25召回的高分但不相关文档里挖,这种“伪相关”负样本比随机采样有用得多,能逼模型
50万条这量级确实该换Milvus了,faiss扛不住增量更新,ES的kNN精度够用但别指望混合检索多强。 其实你这场景pgvector最省心,直接复用业务库,BM25+向量不是必须,先看纯向量能不能过阈值再说。
这问题八成是chunk把表格和上下文切散了,bge对表格结构不敏感,先试试表格区域单独提取加语义描述,再考虑reranker。
我自己也折腾过一阵RAG的prompt,你说的这个“时准时偏”太真实了。感觉核心矛盾在于:检索质量本身就不稳定,prompt再怎么写也只是在补救,所以别指望一个万能模板能解决所有问题。我试下来比较有用的一个思路是,把prompt拆成“硬规则”和“软引导”两层,硬规则就是明确告诉模型只能基于给定片段回答,禁止脑补,软引导则是像你提到的相关性判断,但别让模型先做二选一的判断题,而是让它直接输出答案并附
长文本+小batch基本就是在用时间换显存,试试gradient accumulation加更大的有效batch,loss震荡应该能压下来。
说实话LoRA在7B上batch size只能开到2确实有点反常,我怀疑你没开gradient checkpointing,那个能省掉一大半激活显存,24G跑7B+LoRA正常来说batch size 4到8应该没问题。DeepSpeed ZeRO-3和FSDP本质都是把优化器状态、梯度甚至参数分片到多卡上,但单卡场景下ZeRO-3反而会因为通信开销拖慢速度,而且配置起来坑挺多,比如要处理`fin
我之前也踩过这个坑,后来发现别死磕chunk size,先看文档结构。Markdown本身有标题层级,直接用markdown header做切分比固定大小稳得多,代码块和正文分开处理效果会好很多。 overlap其实不用太纠结,10%左右够用了,真正影响大的是检索策略,比如先按标题粗筛再细切,或者用父子chunk。你可以试试把table、代码单独拎出来,这样混合内容时互相干扰会少很多。 另外建