
前端学习簿
Lv.1主要整理前端工程相关的学习笔记与工程经验,内容覆盖浏览器原理、性能优化。喜欢从问题、方案到复盘形成完整闭环,希望把复杂问题讲清楚、把实践步骤写完整。
发表的评论
LangChain确实重,我后来直接拿它的core模块加自己写的状态机,清爽多了。
5000条数据做LoRA其实够了,问题可能出在lr太高,2e-4对7B来说容易把预训练能力冲掉,试试降到5e-5或者1e-4。错别字被学进去基本就是数据没清干净,这个锅数据得背,业务对话里那些口语化噪声最好过滤一遍。另外LoRA本身不用冻embedding,它只更新低秩矩阵,但如果你还加了embedding的adapter那另说。垂直任务不一定非要先SFT,但指令数据格式得对齐,不然模型不知道你要
Q4_K_M量化对7B模型的影响其实挺明显的,尤其是指令遵循这块会打折扣。你试试把prompt写得更具体点,比如直接说“只要代码不要注释,不需要错误处理”,比泛泛地让它写函数效果好很多。另外Ollama默认的temperature和top_p可能不太适合代码任务,调低一点会稳不少。官方演示大概率用的是FP16或者Q8,本地量化版有差距也正常。
我之前也踩过这个坑,全局dict绝对不能用,并发下必炸。后来我是把状态抽到一个带TTL的session store里,用session_id关联,MCP这边只传id不传状态,推理层自己去取。MCP的Resource其实挺适合挂这种状态快照的,但别指望它帮你做生命周期管理。纯函数化最干净,代价是每次要序列化反序列化,延迟会上去一点,看你能不能接受。
几十万切片其实不算大,Chroma 和 Milvus 都不是唯一解,你可以看看 Qdrant 或者 LanceDB,前者单机部署比 Milvus 轻不少,后者直接嵌进应用里连服务都不用起。查得不准大概率不是向量库的锅,Chroma 默认的 HNSW 参数和距离度量你得确认下,cosine 和 l2 选错结果会差挺多。另外 embedding 模型对中文知识库影响真的很大,bge-m3 或者 gte
我现在的做法是折中,全局system prompt只管角色设定和整体输出风格,每个步骤的prompt只写这个步骤独有的约束和增量信息,那些跨步骤共享的格式定义抽出来做成模板变量注入进去,这样就不会每个步骤都重复解释一遍。你提到的规划输出格式到选工具又得重新说,本质上是没有把中间数据结构定死,我一般会先定义好一个类似JSON schema的中间表示,规划步骤只负责填这个结构,后面步骤直接消费,不用再
应用开发直接上vLLM就行,torch.compile坑多收益不稳,别折腾。
24G卡跑7B的LoRA,batch size开到2就爆其实挺常见的,尤其你序列长度要是拉到512甚至1024,激活值占的显存比想象中猛。我一般会把per device batch size压到1,然后靠gradient accumulation把等效batch凑到16或32,这样显存稳很多。不过gradient accumulation steps调大本身不会直接拖慢收敛,真正的问题是你等效ba
V100不支持AWQ,换GGUF跑llama.cpp吧,16G稳得很,就是慢点。
我之前也踩过这个坑,后来发现是chunk切太碎,检索出来的段落各自为政,模型拼不到一块儿就开始自己脑补。你可以先把检索到的chunk原文打印出来,人工读一遍,如果连你自己都觉得逻辑接不上,那基本就是切分粒度的问题。另外prompt里别光写“仅基于上下文”,最好加一句“若上下文不足以回答,请明确说明”,给模型一个退路,它反而不会乱编。定位的话,可以先固定检索结果,换几个不同prompt跑一遍,看生成
这个问题其实挺典型的,核心在于MCP的context window和训练时的sequence length根本就是两套账。MCP那边算的是推理时的token预算,包含系统prompt、工具定义、对话历史还有工具返回结果,全都塞在那个窗口里;但你微调时的sequence length是样本拼接后的实际长度,跟MCP那套计数逻辑没直接关系。你在server里调max_tokens只是控制了生成侧的上限
10万条片段这个量级其实挺尴尬的,说大不大说小不小,但我觉得你完全没必要在IVF和HNSW之间死磕。我自己搭过类似的本地知识库,最后是用FAISS的HNSW配合量化做的,PQ或者SQ8把内存压下来,召回也没掉多少,efSearch调到64到128之间基本够用了。IVF的坑在于nlist和nprobe要一起调,nlist一般取sqrt(N)的几倍,但你这数据量聚类本身就不稳定,召回波动大是正常的。H
我们团队半年前也踩过这个坑,当时图省事直接把sqlite-vec塞进MCP server里跑,几十个人用确实爽,零运维成本。但后来有两个点差点把我坑哭:一是并发稍微上来点,SQLite的写锁直接让整个server卡住,AI响应从秒级掉到十几秒;二是索引文件跟MCP server的进程生命周期绑太死,有次容器OOM重启,索引文件写了一半直接损坏,只能全量重建。百万级数据倒不是最致命的,真正要命的是备
int4量化到12G只是权重,kv cache才是OOM真凶。你max_num_batched_tokens设256有点小,但关键得看gpu_memory_utilization和max_model_len,默认0.9加长上下文直接把剩余显存吃光。把max_model_len压到2k以内、gpu_memory_utilization调到0.85试试,还崩就上张量并行或者换Qwen2.5-7B,它同
7B做多步工具调用确实容易崩,我一般只保留最近两轮结果,老的直接扔。
几千篇用bge-small的512维就挺稳,几万篇再考虑换bge-base,别死磕维度。
这个坑我也踩过,而且我觉得问题大概率不在embedding阈值上,而是出在MCP那层tool调用的“信息损耗”。你想想,query一旦要经过模型去决定调哪个tool、传什么参数,其实中间就多了一次有损压缩,模型会按它的理解把原始意图重新表述一遍,多轮上下文里的指代和省略很容易在这步被抹平。我们后来是把查询改写和检索拆开,MCP只负责路由到哪个知识库或工具,真正的query改写还是走原来那条链路,不
检索粒度调细治标不治本,试试在MCP server里加个重排压缩,把chunk按相关度砍到窗口内再喂。
代码场景下按固定长度切确实容易把调用链切碎,可以试试基于语法结构来分块,比如用tree-sitter按函数或类做边界,保证一个语义单元完整。另外检索阶段别只塞原始代码,可以同时召回函数签名和docstring,让模型先知道接口长啥样,再按需拉具体实现。embedding的话可以看看jina-code或者voyage-code,比通用模型在代码检索上强不少。
这个问题我们也踩过,后来发现关键不是“存哪”,而是“什么时候存、存什么粒度”。纯向量库存对话记忆听着美好,但“昨天那个订单”这种指代一旦被embedding,相似度检索经常拉回一堆无关的客服话术,反而更乱。我们现在是短期窗口保留最近几轮原文,超出部分按实体和意图抽成结构化槽位,比如订单号、时间、诉求,塞进一个轻量的state里,而不是纯文本摘要。Agent多步调工具的时候,摘要确实容易崩,因为每步