
终身学习写作成长记
Lv.1以项目为主线推进长期学习。当前重点关注技术写作,通过架构设计、开源工具使用持续提升能力;喜欢从问题、方案到复盘形成完整闭环,并把过程整理成可复用的学习记录。
发表的评论
这个其实挺典型的,多步agent里每步都保留计算图,backward一跑整个历史链就全被拉出来了,显存不炸才怪。gradient checkpointing只能省中间激活,对计算图本身的结构没辙,clip_grad_norm_更是只动梯度不动图,所以你感觉“都没用”是对的。关键问题是:你真的需要让梯度穿过整个对话历史吗?大多数agent场景里,前面几步的LLM调用结果其实可以当成环境反馈,不需要回
10万张图每epoch两小时,瓶颈大概率在IO和CPU预处理上。我建议先用LMDB或webdataset把图片和标签打包成二进制,读的时候直接内存映射,比小文件随机读快非常多。num_workers开到4内存炸,通常是每个worker都复制了一份数据或者transforms里有大缓存,可以试试persistent_workers加prefetch_factor,再把resize这类固定操作提前离线
我最近也在折腾这个,感觉prompt里加不加来源信息差别挺大的。之前我只给检索片段,模型经常把几段内容缝在一起,后来改成每个片段前面标个[1][2],让它引用编号,答案结构清楚多了,胡编也少了点。分点还是结论这个得看你场景,问答类我倾向于先给一句直接回答,再补依据,不然模型很容易开头就绕。温度我一般调到0.2到0.3左右,太高真的会自己加戏。还有个坑是检索片段别塞太多,超过上下文一半之后模型反而抓
你提到拼历史结果进prompt还是不稳定的情况,我这边也踩过类似的坑。7B在多跳场景下确实容易丢中间状态,但更关键的是prompt里工具返回的格式要跟调用格式严格对齐,不然模型会把结果当普通文本忽略掉。我后来改成每轮只保留最近两轮的工具交互,加上明确的“当前已知变量”清单,效果稳了不少。向量检索那套对短链路查询有点重了,先试试把中间结果结构化塞进system或者单独一轮user里?
这问题我太熟了,刚开始搭Agent的时候也卡在这上面好几天。GPT-3.5-turbo做工具调用确实不太稳,它本身function calling能力就比3.5-turbo-0613之后那些版本弱一些,你如果用的是老的base模型,那基本就是靠prompt硬凑,格式飘是正常的。先确认一下你绑定的模型版本,换成gpt-3.5-turbo-1106或者干脆上gpt-4o-mini,工具调用成功率会高一
我们线上也踩过这个坑,后来把意图识别单独拎出来做了一层,先判断当前问题是不是依赖上文,是的话再决定检索范围。历史对话直接拼query确实容易稀释语义,可以试试只把上一轮的关键实体抽出来注入检索,而不是整段对话塞进去。重排这块加个cross-encoder对候选切片按上下文相关性重新打分,成本比LLM改写低不少,效果也稳一些。
我踩过同样的坑,后来发现核心问题出在ReAct的thought解析上——模型输出格式稍微跑偏,parser就抓不到已完成的状态,自然就一直重试。换成OpenAI的function calling之后好了很多,因为工具调用和结果返回是结构化绑定的,模型能清晰看到“这个工具已经调过了”。不过手写循环确实更可控,我现在复杂任务都自己撸,LangChain只用来做原型验证。你可以先试试把中间步骤的obse
同感,我一般先用小样本测模型对标签词的注意力,再固定模板批量跑,比瞎调靠谱点。
我踩过类似的坑,后来发现问题真不在prompt上。你试试把top5改成top3加个rerank,人社这种领域条款之间太像了,向量召回经常把邻近条款混进来,prompt再怎么写也救不了。另外口语query建议先过一遍query改写,把“失业了能拿多少钱”转成“失业保险金申领条件及标准”再去检索,召回质量会好很多。system prompt只管边界就行,别指望它纠正检索错误,那是chunk和重排的活。
DDP和DeepSpeed其实不是非此即彼的关系,DeepSpeed的ZeRO Stage 2本质上就是在DDP基础上做了优化器状态分片,所以你完全可以从DDP起步,后面显存还不够再切过去。你说的loss曲线奇怪,大概率不是梯度同步的问题,DDP这块做得挺成熟了,更可能是学习率没随global batch size调、或者数据shuffle没设对,可以先把单卡和多卡的loss前几十步对比一下。De
12G显存跑bge-reranker-v2-m3其实没你想的那么恐怖,这模型是XLM-RoBERTa-base的底子,fp16大概1.1G左右,跟你的7B生成模型错开加载就行,LlamaIndex里rerank是在检索之后、生成之前跑的,不用同时占着显存。我自己的做法是检索阶段用bge-large-zh拉top20到30,然后rerank砍到top3再喂给Qwen,效果提升挺明显的,尤其是那种to
几百万条单机pgvector就够跑,真要上K8s再换Milvus也不迟,Qdrant扩展性其实没你想的那么弱。
这个问题我踩过类似的坑,说下我的理解。LangChain里Agent的工具调用顺序其实很大程度上取决于LLM自己的推理能力,ReAct那一套本质上就是让模型在thought里自己规划步骤,但它并没有强约束机制保证一定按你想的顺序来。你调temperature基本没用,因为这不是随机性的问题,而是模型对任务分解的理解问题。我后来发现几个比较有效的做法:一是把工具描述写得更明确,特别是写明“这个工具必
我本地跑Qwen2.5-7B做结构化抽取时也遇到过类似情况,温度0.3左右配top_p 0.8会稳不少,repetition_penalty设1.05到1.1之间能压住重复句子。不过要硬保JSON字段完整,其实最好直接上约束解码,比如outlines或者llama.cpp的grammar,比调参数省心。你试过把生成格式写进system prompt再配合few-shot吗?有时候模型不是随机性太高
我之前也踩过这个坑,最后发现是autograd的图没断干净。你虽然关了梯度,但Agent里如果有些tensor参与了requires_grad=True的运算,哪怕只是记录,计算图也会一直挂着不放。建议在每个step结束时手动把中间变量detach一下,或者用with torch.no_grad()把整个推理包起来。另外检查下有没有全局list或者dict在偷偷存tensor引用,那种最容易被忽略
显存慢慢涨多半是碎片化,试试torch.cuda.memory_summary看下分配情况,另外amp有时反而会多占显存。
你append的是啥?如果是把每批的输出张量直接存列表里,那显存肯定一直涨啊,把结果转成cpu的numpy或者python标量再存。另外DataLoader的num_workers多的话,worker里也可能留着cuda上下文,试试设成0排查一下。监控的话可以看看torch.cuda.memory_summary(),或者用py3的gc加weakref自己查引用,比啥工具都直接。
这问题太真实了,我上个月也刚被吐槽过一轮。后来发现Cursor的代码风格其实跟你项目里已有的文件关系特别大,它会偷偷“学习”你最近打开过的那些组件写法。我现在的做法是每次开新组件前,先手动把同类组件的头部import、类型定义和几个典型函数写个骨架,再让它往里填逻辑,风格就稳很多。另外useMemo和useCallback这个事,你可以在项目根目录放一个.cursorrules文件,直接写清楚“不
几百条就开始退化,感觉问题可能不在检索本身,而是你每轮把top-5全塞进prompt,相似对话越积越多,模型反而被噪声带偏了。我后来加了时间衰减权重,再对高分片段做一次去重合并,效果明显好不少。另外你换过embedding模型但没提有没有做metadata过滤,按session或话题先粗筛再检索,往往比单纯调top-k更管用。
我也遇到过这个问题,尤其是多轮对话里代词一多,检索基本就飘了。后来我的做法是把历史压缩成一个“检索用的query”,只保留实体和约束条件,比如“报销流程”+“电子发票”,而不是把整段对话塞进去。这样检索目标会清楚很多,也不会把无关轮次带进来。另外我加了一层轻量rerank,先召回大一点,再用cross-encoder或者LLM打分筛掉跟当前约束不匹配的chunk。还有个挺关键的点是,检索结果里最好