2026-06-12 20:00:00
回看 DeepSeek 从 V3 到 V4 的这一年里,如何降低长上下文的开销一直是研究的一个重点。从 V3.2 开始,DeepSeek 引入了 DSA,直接把 V3.1 的价格降低了 50%。这个技术在 V4 中也得到了延续,并成为实现 1M 上下文的关键技术之一。这里会谈一下我对 DSA 思路的理解。
原始的 Attention 计算需要计算每个 Token 和它之前所有 Token 的相关性,得出当前 Token 在当前上下文的一个向量值,因此随着输入输出序列不断增加,整个 Attention 计算的复杂度趋近于 O(n^2)。
这也就意味着随着序列增长,总计算量会平方增长,这成为了一个主要的性能瓶颈,也是很多模型在超过一定序列长度后价格大幅上升的原因。为了解决 Full Attention 的二次方计算问题,就出现了很多 Sparse Attention 机制,试图避免成本的快速上升。
为了避免二次方的 Attention 计算,一个很直接的想法就是只选择和当前 Token 关系最大的一批 Token 计算 Attention。这个想法不仅很符合直觉,在 Attention 的实际计算中也会发现序列里大部分 Token 和当前 Token 的关系计算值是接近于 0 的,我们在预测下一个 Token 时,很多时候只要看序列里的关键信息就可以了。
一个很直接的思路就是滑动窗口只计算附近 K 个 Token 的 Attention,这个方法的好处是简单,计算复杂度稳定,但是局限性也很明显,那就是会丢失长距离的信息。
为了解决长距离丢失的情况,还有一种分层的注意力机制,使用一部分 Token 作为全局 Token,再加上局部滑动窗口的 Token,用全局 Token 来弥补长距离的信息。但是这就带来了新的问题:这些少数的全局 Token 应该如何选择?随着序列变长、任务目标发生变化,全局 Token 是不是又该重新调整?
不管是滑动窗口还是分层的注意力其实都是通过简单的局部性策略选择 Token,并不是真正根据 Token 实际的相关性来选择 Token。其实 Attention 的计算过程中就会计算出 Token 之间的相关性分数,我们直接取其中的 Top-K 作为选择的 Token 是否可行呢?
当然可以,但此时 Attention 的计算已经完成了,再做 Top-K 已经没有多少优化的意义了。但是如果我们可以通过计算复杂度更低的方式来快速选择出 Top-K 再进行 Attention 计算就有意义了,这就是 DSA 试图做的事情。
DSA 的核心组件是一个 Lightning Indexer 的选择器,它会根据当前 Token 给上下文的所有 Token 打一个分数,然后选择 Top-K 进入后续的 Attention 的计算。
而这个 Indexer 的分数计算就是去预测 Attention 计算的相关性分数。而它的结构也和 Attention 的结构很相似,Attention 是有 QKV 三个向量矩阵,而 Indexer 使用 WQK 三个向量矩阵,计算过程也是基本类似的。这就带来了一个新的疑问,这个 Indexer 其实是在模拟 Attention 的行为,那它的复杂度难道不应该和 Attention 是一致的吗?
按照我的理解,其实复杂度确实是一致的,还是 O(n^2),但是这个 Indexer 由于任务简单可以使用更少的特征,更低的精度,ReLU 这样更高效的算子,在工程上把复杂度的常数部分大幅降低。这有点类似于用同样的股票预测模型结构,Attention 是要预测股票第二天的价格,Indexer 是要预测股票第二天涨跌的概率,把上涨概率最高的 Top-K 选择出来给 Attention 做价格预测。尽管结构上相似,但是预测涨跌概率的难度要比预测价格低很多,可以选择更少的参数和更快速的算法。由于 Indexer 是根据 Attention 结果来训练的,也可以粗略地理解为 Indexer 是从 Attention 蒸馏出来的。
DSA 的本质是在 Attention 的计算前加了一个选择器,这个选择器需要尽可能精确地预测出哪些 Token 和当前 Token 相关,又需要尽可能低的计算复杂度避免选择器的复杂度接近 Attention 的复杂度。DSA 的做法是使用了和 Attention 类似的结构,使用更少的参数量和更高效的算子,以及只预测大小关系而不是预测具体分数来降低选择器的复杂度。尽管整体复杂度还是 O(n^2),但是通过把常数项降低数十倍,实现了在不牺牲模型性能的情况下成本大幅下降。
2026-05-26 18:00:00
Claude Code 在 2.139 版本引入了 Agent View,可以在一个界面里直接浏览多个项目下所有运行中和已结束的 session,方便更好地进行 session 管理和并行开发,在单个 terminal tab 下就能完成大量并发工作。

在我看来,这是一个 Agent 交互体验模式的重大提升,现阶段人们对它的重要性是大大低估了。
尽管这不是一个模型或者能力层面的更新,但这种用户体验的重新组织,极大提升了并行开发的效率。我之前其实已经回退到了线性开发的模式,因为我发现自己很难在多个任务之间进行快速的切换和响应。但是用了 Agent View 之后,我发现我可以开始大量并发工作了。
多 session 无法快速并发。 之前如果想并发,需要不断地开窗口、开 Claude Code 再执行任务。但这个流程普通人很难适应。在我的意识里,开窗口是个很重的操作,而且当下发一个任务后,模型很快就开始输出了,注意力很自然就被吸引过去了,很难不去看直接开下一个窗口。而在 Agent View 里,任务默认是异步的,输入完 prompt 后直接后台执行,留下的输入框是给下一个任务准备的,不会有当前任务的干扰,很自然地就过渡到了下一个任务。避免了窗口的创建,对心智成本是一个很大的下降,把”启动”这一步变得容易了。
多 session 难以管理。 我之前为了并行处理,甚至写了个简单的 hook 让 Claude 每次执行完发铃声并且弹窗让我知道状态,但在多窗口的情况下还是很容易错过消息,忘记哪个窗口现在是什么状态。现在的 Agent View 里可以按状态展示 session,很轻松地看到哪个 session 等待我的输入,哪个还在工作,哪个已经完成。同样在一个窗口里快速浏览状态进行下一步操作,避免了窗口的切换。
git worktree 管理困难。 其实之前也可以通过 git worktree 来实现并发代码修改的隔离,但是 git worktree 的使用模式和普通开发流程还是有区别,并且还要求每次启动 Claude Code 的时候添加对应的参数,增加了额外的心智负担。而且之前的 session 是和 worktree 绑定的,很容易出现找不到的情况。在 Agent View 里的 session 如果涉及更改会自动启用 worktree 做隔离,对于使用者来说完全不知道有 worktree 的存在,极大降低了使用门槛。
多个项目并发管理困难。 现在直接在输入框 @ 项目名,就可以在项目目录下执行 Claude Code 操作,会直接使用对应目录的 Claude Code 配置,同样无需开窗口切换项目,减少了对人类上下文切换的开销。
此外 Claude Code 还设计了一系列快捷操作来让 Agent View 更加方便。比如非 Agent View 管理的 session 可以通过 /bg 命令直接加入到 Agent View;通过键盘 <- 快速切换回 Agent View;通过 Space 展示 session 最近的会话并快速回复。一切的设计其实都是希望用户尽可能停留在 Agent View 页面,而不是进入到具体的某个 session 里。
这个设计理念很值得注意,它不是在现有模式上加一个管理面板,而是在尝试重新定义人与 Agent 的交互方式:从一个对话窗口变成一个有状态的任务面板。
当然,我也发现了它存在的几个问题:
这些问题不影响我对这个方向的判断,Agent View 这种交互模式未来会成为标配。人们的注意力也会逐渐从当个 session 的管理,转移到更多工作的编排。
2026-03-16 00:03:00
最近一周基本都在和肾结石作斗争了,记录一下过程,有想体验的小伙伴可以来看看。
这次肾结石的前两天我一直以为是深蹲拉伤,主要原因是我对肾的位置理解一直是错的。我一直以为肾是在下腹部的位置,其实后背部肋骨下方就是了。之前看人体器官图几乎从来没看过背面,但凡看过就能发现后腰从上到下只有一个泌尿系统,但凡后腰疼大概率是肾的问题。

上周五的时候站着站着毫无征兆的腰就感觉和被扎了一下疼起来,当时就直接倒在床上吱哇乱叫了,从肋骨下方一直到骨盆半个腹部都开始抽搐起来,时间持续了大概五分钟才慢慢消失。现在想来应该是肾结石刚脱落,一下子卡到输尿管了,没卡住一会儿又掉回到肾里了。
好了之后发现一旦坐起来或者走一会儿路就会再这么来一下,躺着不动就没事,人就不敢动了,就按腰部拉伤来处理了。静养了一天感觉还不错,周日的时候觉得差不多了,就开始不怎么躺着了,结果一下来了个大的。
这次是坐着的时候感觉有点不舒服就躺下去了,然后疼痛不断升级,半个腹部感觉都拧在一起,接下来半边身子都麻了,舌头都动不了只能靠嗓子发声,然后另半边身子也开始发麻,眼睛里都是星星,眼看整个人就动不了了。而且这次完全没有消退的迹象,第一波刚好了一点还没缓过来第二波就又来了,每次都是半个腹部扭在一起全身发麻,一波一波的连绵不绝。我一度担心自己会不会半身不遂,疼的开始想生死的问题了,十来分钟后果断叫 120 把自己搬走了。
现在想起来应该是前几天活动比较少,肾结石都是刚卡到输尿管就掉下来了,周日活动多了一些彻底卡进输尿管掉不回去了,所以就一直疼下去不可能再恢复了。
我们这边是老小区,机动的救护车还比较多,感觉十分钟都没有救护车就到了,说一下你要去哪个医院就行,感觉和打车也差不多。
由于一开始我一直以为是锻炼拉伤,直接去了骨科,大夫觉得我疼的位置不太对转到了胸外科,胸外科拍了个 CT 大概两个小时出了结果,发现肋骨没问题,但是扫到了肾说是能看到有两个结石,于是把我转到了泌尿科。
由于我当时对肾的位置还有理解错误,还纳闷肋骨扫描怎么能扫到肾,想自己借着 AI 看 CT 结果,发现 CT 拍了 600 多张片子于是作罢。
泌尿科开了个腹部 CT 、血常规和尿常规,结果就是白血球高有炎症,尿红蛋白高有血尿,左侧输尿管卡了一个 6 毫米一个 4 毫米两块结石。由于 6 毫米是自然排出上限,大夫的建议是先等自然排出,一周后还有症状的话再看是超声波碎石还是微创手术取出来。
最后就是开了止疼药和消炎药,让我多喝水多蹦,疼的受不了就吃止疼药,一周后再看。我看有的疼痛等级指数介绍肾结石已经是最高级了,能和自然分娩坐一桌,想到可能还有一周整个人是崩溃的。当时都想直接去手术取出来了,不过想了想手术还是有创伤,理智战胜了冲动,还是打了针止痛回家了。
由于结石已经卡住了,不疼是不可能了,我发现蹦跶一阵疼痛会缓解一些,就只能在疼痛刚起来的时候赶快去蹦一阵,不然一旦疼劲上来就又动不了了。整个晚上基本上就是疼的时候就赶快去蹦,不疼了就闭眼躺一会儿,等再疼了再去蹦,最后到四点后才睡了一会儿,六点多疼起来就是循环继续。
这个过程中应该是结石划伤了输尿管伴随着炎症开始低烧,由于排尿管被堵住了明显感觉排尿偏少,而且肚子里有一大坨水,蹦的时候能感觉甩来甩去。
这样蹦了两天感觉疼痛点从肋骨慢慢往骨盆转移了,然后就不会那么疼了,但是还会有一波波的酸痛,应该是伤口被摩擦的感觉。蹦了两天后,基本也抬不起脚了,发烧和没睡觉的乏力感也上来了,后面两天一直在睡觉,等到这个周五的时候才基本不疼了,排尿也基本正常,肚子里也没一大坨水了。下周约个时间去医院再做一次 CT 看看结石是排出去了还是掉到膀胱里了,还有没有其余的没脱落的结石。
这次肾结石后立刻就老实了,我是从来没想到过可以这么疼。查了一些资料,主要原因应该还是喝水太少了,尿液沉积形成的。其他一些可能的诱因有含糖饮料可能会提升尿液浓度,可乐里的磷酸(有糖无糖都含有)会导致磷酸盐析出,茶叶里的草酸也会导致草酸盐析出。
所以想来普通的腰疼其实也有概率是肾结石排出的原因,只是没堵那么长时间,体积也没那么大。我现在看到可乐就开始腰疼,有想体验的小伙伴可以考虑可乐和浓茶当水喝,看看多久可以体验到这种感觉。
2026-01-27 23:23:51
看了下 DeepSeek OCR 2 的论文,以我二把刀的知识分析一下。
这次是一个视觉模型编码器架构上的创新,主流的视觉模型编码器的方式是把图片分成一个个小块,变成一个个 token,然后按照从左上到右下逐行扫描的顺序一个个输入给模型。这其实和现在的 LLM 工作原理很像,只不过 LLM 是一串文本的 token,这里是一个个图片块的 token。然后还是 attention 那套两两比较,计算出每个 token 之间的关联关系,这样就可以通过不同 token 之间 attention 的权重关系得出不同图像块之间的关联,模型也就理解了整个图片。
看上去这个思路很好,统一了图片和文本的处理方式,但是图片和文本有个显著的区别,文本可以看做是一个一维的表现形式,你从左到右按顺序读,文本的逻辑大概率也是按照这个方向展开的。但是图片是个二维的表现形式,图片的逻辑并不是按照从左上到右下,图片里可能有斜线有曲线甚至有螺旋线,还是按照从左上到右下拆成的一维顺序是不是最有效的?至少人类看图片是不遵循这个顺序的。
虽然通过位置编码的方式可以把位置信息也加入到 attention 的计算,但是主流的位置编码也是基于文本一维顺序做的,是不是能很好的对图片这种二维表现形式进行位置编码呢?
DeepSeek OCR 2 的架构创新就在这里,他们在编码器里附加了一个小型的 LLM 可以推理出图片之间各个块的因果关系,然后按照关联关系对 token 进行重排序。可以认为模型是按照逻辑顺序去看图片而不是无脑的从左上到右下,这个逻辑顺序也会更接近人看图片的顺序。
性能提升,开销下降这属于 DeepSeek 的常规操作这里就不提了。我在想有没有可能视觉模型才是能力更强的模型的方向?
论文里提到这个模型主要作用还是读文档来生成语料,给 V 系列的语言模型用,但有没有可能把 OCR 系列和 V 系列直接融合。一方面图片里其实包含了文本里无法体现的内容信息,另一方面图片还比文本更节约 token。
按照 DeepSeek 一贯喜欢融合模型的作风,我觉得可以期待一下 V4 是个有初步视觉能力的模型了。
2026-01-12 02:49:00
最近迷上了补看电视剧,又看了《人民的名义》和《亮剑》,但是由于先看的《潜伏》难免会做一些对比。看了后两部更显得《潜伏》的节奏紧凑,台词没有废话,所有的演员都处在很高的水平,编剧也是自始至终的优秀。
《人民的名义》的节奏就有点拖,一个事情好几集都绕着转,换成《潜伏》一集可能三四个重要事情都过去了。里面老演员的演技还是不错的,年轻演员感觉都在用力过猛,两边一旦同场景搭戏就让人看着很尴尬。
看《亮剑》里的平安县争夺战拍出了看三大战役的感觉,还是很过瘾的,不过后面的剧情就急转直下,给人一种烂尾的既视感。
另外这两部剧很多时候都是靠喊台词来表现人物特点,《潜伏》在这方面就很收敛,更多是通过表情和动作来塑造人物。
引体向上现在站在台阶上不用跳可以拉上去了,不过全程还是拉不上去。
最近做动作膝盖和肩关节的弹响越来越明显了,看了些视频一方面要加强后侧肌肉的训练,还要专门练习一下肩胛骨的活动度。
睡眠对力量训练的影响还是很大的,稍微一熬夜大重量拉起来就很费劲了。研究一下说是力量除了和肌肉相关也和神经募集能力相关,如果睡眠不足会导致神经无法募集足够的肌肉来发力,从这个角度看健身可能比写代码更费脑子。
Kubernetes 的 managedFileds 在 Informer 缓存的时候可以删掉来节省 client 端的内存占用。我之前一直以为这时候再根据缓存做对象的 Update 操作会出问题,经同事指点其实 APIServer 会在 Update 和 Patch 时忽略没有 managedFileds 的情况,具体可以参考 Server Side Apply: clearing managedFields
之前为了标记生成的 Go 二进制对应的是代码的哪个 commit 会在 build 的时候把这个参数传进去,但是 Go 在 1.18 之后的 runtime 里其实默认就带了 VCS 的相关信息,只需要使用 go version -m xxx 就可以从二进制文件里直接获取构建信息了,更多参考 Go 1.18 debug/buildinfo features
发现了两个适合让 codex 来做的任务:
最近在做数字骨灰盒时发现其实大部分厂商都提供了视频理解的 LLM,但是 GLM 和 Qwen 只支持 public_url 方式传入视频,对非公开视频不是很友好。而 Gemini 是支持上传文件后再引用文件 ID 的,国内貌似只有 DouBao 支持类似的功能。
2025-12-29 16:25:00
居家办公三周后莫名其妙的得了痔疮,前几天都只能躺着了。查了下资料说现代人可能是因为长时间坐马桶导致的,可是我并没有。稍微好一些之后发现只要坐平时办公坐的椅子就会疼,仔细观察发现这个椅子由于长时间胶皮老化中间凹下去了,所以坐起来就类似一个马桶两边高中间低,换成个平板椅子就好多了。
对着上周看的 Performance Hints 里的一条unnecessarily-nested-maps,拿着锤子找钉子,去 Prometheus 里看看有没有什么蹭 PR 的机会。最终发现这个优化方法还是有很多细节要考虑的,并不是完全没有副作用,尤其在 Prometheus 的场景里有时候完全不适用还会导致性能严重下降,之后可能会单写一个博客来说明。不过好在 Prometheus 里还有一处是完美适合这个优化的,提交了一个 PR perf(promql): update matchedSigs to a flat map reduce memory by 97% for GROUP_LEFT,能优化一个常见场景 13% 的 CPU 和 97% 的内存分配。
看了How uv got so fast,和第一直觉认为的 Rust 比 Python 快,所以 uv 才能这么快不同,uv 的快主要还是来自实现架构层面的选择。一方面是 Python 的包管理出了更高效的标准,另一方面 uv 选择放弃了大量的历史兼容性,专注于标准路径的优化。此外还有很多语言无关的优化,比如并行下载,硬链接等等其实是其他语言的依赖管理都有的功能,只是 pip 的历史包袱太大了,一直都没有这方面的优化。
在逛 Prometheus Issues 时发现一个 WIP: tsdb: persist series metadata to Parquet files 需要找时间看一下 Parquet 是个什么存储。
周末和孩子去了城市农场,一开始以为是个什么网红景点,去了后发现是个正经的科研机构,中国奶牛的育种就是从这里开始的。里面都是些看上去六七十年代的老房子,有科研人员专门负责讲解,体验还是很不错的。另一方面想到自己小时候没有盒装奶还都是牧场每天早上和报纸一块送的鲜牛奶要拿回家去煮。
里面有从刚出生到三四岁的奶牛,可以自己去喂,小孩抱着草料来回跑喂了快一个小时。
