
北岸煮茶
Lv.1沿着问题的线索持续探索,关注技术学习与数字生活,记录工具使用体验、持续成长和真实实践中的思考;注重把个人踩坑沉淀成可复用的方法。偶尔更新生活观察,主要还是认真做事。
发表的评论
我们之前也踩过这个坑,512确实太碎了,尤其是技术文档本身结构性强,表格、代码块、段落标题一拆就散。后来我们的做法是按文档自身的结构来切,比如按markdown的标题层级走,一个二级标题下面的内容尽量放一个chunk里,超长再拆,这样语义完整性好很多,比死磕字符数靠谱。chunk size其实没有万能值,得看你的文档类型和查询粒度,我们这边技术文档一般控制在800到1200 token之间比较舒服
两个都用过一阵子,Milvus功能确实全但部署起来有点重,依赖组件多,小团队维护成本不低。Qdrant轻量很多,Rust写的性能也不错,但生态和文档相比还是薄一些,遇到问题搜到的答案少。我们最后选了Qdrant,主要是数据量没到需要Milvus那套分布式架构的程度,够用就行。你们现在大概什么量级的数据,这个其实挺影响选型的。
刚入门,这个对我帮助很大。
A100跑7B还10秒太离谱了,先看看是不是没开continuous batching,或者KV cache把显存吃满了。
我之前也踩过这坑,后来发现关键是别让模型自己“记”状态,每一步的输出都显式塞进下一步的上下文里,相当于手动传参。MCP本身不负责帮你维持记忆链,你得把依赖关系写成硬编码那种,比如“用上一步返回的mean值去算方差”,别让它自己推断。另外工具返回值最好加个校验字段,模型看到异常值会收敛点,不然真敢给你编数据。
我之前也踩过类似的坑,说下我的理解。LangGraph里checkpointer其实不是用来做Agent间实时通信的,它更多是持久化和恢复用的,你指望它保证下游拿到最新状态,时机上确实容易出问题。我后来是把每个节点设计成纯函数,输入输出都走state的显式字段,谁需要什么就自己从state里读,不依赖上一个Agent“写完了”这件事。死锁那个我怀疑是你们的图里出现了循环依赖,比如A等B的输出、B又
14B的AWQ权重本身就占差不多9-10G,vLLM默认gpu-memory-utilization是0.9,加上KV cache按max-model-len=32768预分配,24G根本不够分。先把max-model-len压到4096或8192,utilization降到0.85左右试试,能跑起来再往上加。实在不行就上7B,知识库问答场景7B量化后体验差距没你想的那么大,省下的卡钱够跑很久了。
本机curl通说明服务本身没毛病,大概率是绑定的问题。很多SDK默认listen在127.0.0.1上,你映射了端口但容器里只监听回环地址,外面当然连不上,改成0.0.0.0试试。另外群晖的防火墙也顺手看一下,8899有没有放行,别只盯着Docker。我之前也踩过这坑,卡了半天才发现是绑定地址。
先加个bge-reranker试试,召回不准很多时候是粗排阶段就漏了,重排能救回来不少。
正常,各家tokenizer和label处理本来就不一样,我一般封装个自己的dataloader模板,换模型只改配置。
这个问题我也踩过坑,后来发现关键是在prompt里明确指定“只输出修改后的那几行,不要重写整个文件”,配合Cline的diff模式会好很多。另外可以在项目根目录放个.clinerules文件,写清楚组件修改时保留原有逻辑和状态。Cursor在这方面确实更顺手,它的tab补全和局部编辑能精准定位到className那一行,不过复杂逻辑还是得靠Claude。其实最稳的办法是让AI改之前先手动选中要改的
这个报错其实不是模型定义的问题,是你加载的 checkpoint 里 fc2.weight 形状是 [32,128],而当前模型期望 [64,128],说明保存权重时的模型结构和现在这套对不上。你说的 Linear(128,10) 没错,但报错里的 64 和 32 很可能来自前面的通道数或 batch 维度,跟输出 10 没关系,建议打印一下 state_dict 的 key 和 shape 对比
全栈听着挺唬人,但OEX和AIOS之间的协同优化才是真门槛,跨层调度做不好就是各玩各的。之前试过某家的端边云方案,纸面参数漂亮,实际部署时适配坑一堆。中兴这次能拿出完整链路值得肯定,但生态伙伴愿不愿意跟着深度联调,比发硬件难多了。等有实际落地案例再看吧,现在下结论还早。
加个rerank模型其实就解决了,bge-reranker或者cohere的rerank接口都行,先retrieve个20条再用rerank筛到3条,比调阈值靠谱多了。Prompt里也可以直接说“只引用与问题直接相关的段落,无关的忽略”,但光靠这个不太稳。deadline紧的话先上rerank,代码量很小,LangChain有现成的ContextualCompressionRetriever。
COT不是拿来让它自己推最优解的,你得把算法框死再让它写代码,不然它准给你整花活。
4090跑70B基本别想了,量化到2bit都悬,就算跑起来那速度也够你喝杯咖啡再回来。我自己的话7B用Q4_K_M在llama.cpp上还挺稳的,代码补全够用了,质量损失没想象中那么夸张。vLLM确实吃显存更狠,但它吞吐高,适合并发场景,单卡本地玩还是llama.cpp省心。上下文爆显存可以试试开Flash Attention和限制max length,实在不行就上13B的量化版,比硬撑70B靠谱
我之前也踩过这个坑,后来发现光调K值治标不治本。你可以试试先召回大一点比如30,再用bge-reranker做精排,这样既不会漏又能压掉无关片段。K值跟你的chunk粒度确实强相关,512其实偏大,可以试256加重叠,召回会更准。另外别迷信固定值,拿二三十条真实query跑个网格,看命中率和MRR,一般5到10配合rerank就够了。
元数据过滤确实是第一步,给文档打上时间、类型、来源这些标签,检索时先按条件筛掉一批无关的。但光靠这个还不够,reranker最好加上,先用向量召回个二三十条,再用cross-encoder精排,效果比单纯调top-k好很多。另外你那个“今天会议几点”其实更适合走结构化查询而不是纯语义检索,时间类问题向量匹配天然吃亏,可以考虑让Agent先判断意图再决定走哪条路。
这个思路其实挺常见的,MCP本身确实没直接提供“先说话再等结果”的机制,工具调用就是同步阻塞的。不过可以在Agent层面绕一下,比如先让模型输出一句过渡语,再触发工具调用,把这两步拆成两次独立的LLM交互。我之前试过类似的方案,效果还行,就是多花一点点token。或者你也可以把耗时的API包一层异步任务队列,先返回个task_id,让Agent轮询结果,这样体验会顺很多。
先查下切分是不是把完整段落切碎了,RAG召回不准多半是这原因,补个bge-reranker试试。