ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

统一内存跑大模型为何狂写盘?内存换页排查与优化实战

统一内存跑大模型为何狂写盘?内存换页排查与优化实战 先说个让人血压飙升的事我手头这台 Strix Halo 平台锐龙 AI Max 395128GB LPDDR5X 统一内存配的是一块 2TB NVMe跑了一天 qwen3.8 flash next第二天起来看统计磁盘累计写入飙升了 256GiB。256GiB 是什么概念相当于你睡觉这一晚系统往硬盘里倒了接近一块 256GB SSD 的总容量。这个量级放在任何机器上都很吓人尤其是我本来打算把它当长期本地模型服务器用的。这问题不解决下一步大概率就是 SSD 先走一步或者推理时卡到怀疑人生。这篇记录不是劝退帖也不是炫耀贴而是一份比较完整的排查日志为什么一台号称随便跑大模型的统一内存机器反而会疯狂写盘以及我最后到底怎么把它治住的。无论你用的是 Strix Halo、Mac 这类大统一内存设备还是普通 PC 上挂了个大模型服务端只要跑的是千问系这种长上下文模型这套排查思路基本都能直接抄。1. 机器的诱惑和一夜之间被写掉的 256GiB1.1 Strix Halo 看着就是为本地大模型量身定做的先说机器本身。Strix Halo 这一代最吸引人的点就是把 CPU、GPU、内存全部塞进同一个物理封装里内存直接给到 128GB LPDDR5X带宽跑到 256GB/s 左右GPU 部分有 40 个 RDNA 3.5 计算单元。对比一下传统独显哪怕 24GB 显存的卡想跑 70B 参数的量化模型也只能挤牙膏而 128GB 统一内存在容量上直接把约束解开了。所以当我拿到机器第一件事就是把最新的 qwen3.8 flash next 拉下来跑。这个叫法我不去纠结具体是哪个 repo 的构建版本本质上就是基于千问 3.8 量级模型的一套本地推理流程。它的吸引力很简单模型体积不大、指令跟随能力不错、上下文还特别长正好适配这种大统一内存平台。跑起来的那一刻你确实会觉得这才是本地 AI 该有的硬件。1.2 但磁盘写入数据不会骗人问题就出在第二天早上。我看了一眼nvme smart-log吓一跳——累计写入值往上跳了 256GiB。更准确的说法是从当天零点到我睡醒这十几个小时里主机平均每秒往 NVMe 写了差不多 3MB看着不高对吧但这是平均实际观测时 swapd 一开动就是几百 MB/s 的脉冲而且它不是一次性写入是断断续续、持续不断地写。我一开始还怀疑是模型下载或者量化转换产生的临时文件但查了日志那些操作早就结束了写入集中在深夜到凌晨。这说明背后一定有个机制在持续把内存里的东西往磁盘倒腾而不是正常的一次性写文件。这里还要补充一个判断NVMe 的write_totals属性反映的是主机发出来的逻辑写量256GiB 的涨幅实打实。有些人会说闪存有写放大、有垃圾回收但那是物理层的事smart-log 里逻辑写就已经涨了这么多说明系统是真的发了一大票写请求出来不是固件在后台自嗨。2. 统一内存不是免死金牌换页机制才是写盘真凶2.1 显存内存的另一面是内存操作系统说了算Strix Halo 的宣传话术是显存即内存内存即显存听起来很完美但实际操作上没那么浪漫。GPU 会通过 BIOS 或者驱动在物理内存里划走一块固定区域当 VRAM剩下的才是系统可用内存。你如果 BIOS 里把 UMA 分配设成 96GB那 128GB 机器开机后系统里看到的可用内存可能只有 28GB 左右剩下的都在 GPU 手里。模型推理时权重、KV cache、激活值这些大头一部分住在设备内存里一部分住在主机系统内存里。操作系统不关心你跑的是什么 AI 模型它关心的是页够不够用。一旦系统内存吃紧内核就会把长期不访问的匿名页从内存里扔到交换空间也就是 Linux 的 swap 或者 Windows 的 pagefile。这一扔就变成了实实在在的磁盘写入。2.2 KV Cache 和上下文窗口才是真正的内存大户很多人有个错觉8B 模型Q4_K_M 量化之后也就 5.2GB128GB 内存怎么可能不够问题不在权重在 KV Cache 和上下文。千问系列现在的 token plan 动辄号称几十万 token 上下文听着很爽但 KV Cache 和上下文长度是严格成正比的。我按 Qwen3-8B 这个量级的典型结构粗略算过一笔账36 层 Transformer、8 个 KV Head、head_dim 128半精度下每个 token 的 KV 大约是 72KB。那么 128K 上下文就是 9.4GB512K 上下文直接飙到 37.6GB。如果 KV 用 FP32 保存还得再翻一倍。再加上模型权重 5-8GB、推理时的激活值和计算图 1-2GB、系统后台服务加浏览器 10GB 起步你算算128GB 里扣掉 UMA 预留剩下的系统内存还能撑多久更别提有人会同时开几个会话或者同一个模型跑两个实例上下文一叠加内存直接击穿。我把这几项放在一起做了个估算表供参考内存去向典型占用模型权重8B Q4_K_M约 5.2GB模型权重8B BF16约 16GBKV Cache128K 上下文FP16约 9.4GBKV Cache512K 上下文FP16约 37.6GB推理激活值/计算图约 1-2GB系统桌面环境浏览器约 8-15GB2.3 内存看着大不代表可以随便透支关键点在于操作系统允许应用超额申请内存。Llama 系引擎在启动时会根据你设置的上下文大小一次性申请一大块 KV Cache申请归申请真正物理分配要到实际访问页面才发生。于是白天你看着内存还有富余晚上浏览器开了几十个标签模型又把整段上下文填满系统内存水位一上去内核就开始默默地把最冷的内存页换到 swap 里。Windows 上对应的是 pagefileLinux 上是 swapfile 或 swap 分区。交换空间只要存在内核就会用。哪怕你没有主动设置太高系统还是会根据压力自动调整。我这次遇到的情况八成就是上下文拉满 页面文件在 NVMe 上导致一整晚都在做这种内存不够、磁盘来凑的搬运工作。这也解释了一个反直觉的现象内存越大的机器用户越敢开大上下文反而越容易踩进换页坑。3. 完整排查链路我到底是怎么锁定它的3.1 第一步先确认写入确实落在系统盘上排查这种问题最忌讳拍脑袋。我先把谁在写、写在哪、什么时候写全部用数据拉出来。先看磁盘级统计iostat -dx 1w_await和wkB/s能告诉我写请求来自哪条块设备路径但还不能看到进程。接着用iotop -ao按累计写入排序注意-a参数必须加否则你看到的永远是瞬时速率很容易漏掉半夜的脉冲。sudo iotop -ao结果很明确排在写入榜前列的不是模型下载程序也不是日志服务而是内核的kswapd0和几个跟页面回收相关的内核线程。到这里方向基本清楚了十有八九是内存换页。3.2 第二步把内存压力和 swap 使用量抓出来然后我盯了一轮内存和 swap 的实时数据free -h vmstat 1 10 cat /proc/pressure/memoryvmstat输出里的si和so两个字段是关键so表示从内存换出到磁盘的页面量。在写入高峰段so数值飙到每秒几万 KB和磁盘写速率完全对上。再配合/proc/pressure/memory能看到内存压力已经频繁亮红灯。接着找具体是哪个进程占着 swapgrep -E VmSwap|Name /proc/[0-9]*/status 2/dev/null | awk /Name:/{name$2} /VmSwap:/{if ($2 0) print name, $2} | sort -k2 -n结果毫无悬念排在前面的是推理引擎进程VmSwap 已经到了几十 GB 的量级后面跟着的是浏览器和一堆桌面服务。至此谁干的已经基本坐实。3.3 第三步反向验证一下别让数据骗了你为了确认不是日志轮转、病毒扫描这类偶发因素我做了个控制变量实验把上下文窗口从原来的 512K 调回 32K加上内存锁定重启推理引擎跑了一夜第二天看nvme smart-log写入增量还不到 2GiB基本全是系统正常后台写入。然后再把上下文调回 512K、去掉锁定同样的负载跑几个小时写入曲线肉眼可见地陡增。这个实验做下来两个结论跑不掉写入来自内存换页机制不是应用主动写文件。触发换页的直接原因就是过大的 KV Cache 抢占系统内存导致内核持续把冷数据倒腾到 swap。3.4 顺便排除几个容易误伤的对象排查时我还顺手排除了几个常见的干扰项journald 日志量大不大抽查了/var/log大小和增长正常水平。是不是模型文件反复重新下载看了家目录缓存没有增量下载的痕迹。是不是杀毒/索引服务在扫盘这类服务的写模式一般是均匀小 IO不至于一个晚上睡出 256GiB而且线程对不上。内存换页是唯一同时满足写入量大、持续、发生在低负载时段、由内核线程驱动的解释。4. 止血实测三档优化我挨个做了4.1 第一档改引擎参数立刻止损既然根子是上下文太大导致内存不够最直接的做法就是把上下文压下来同时让引擎别把内存页交出去。我用的启动命令大致长这样llama-server \ -m /models/qwen3.8-flash-next-q4_k_m.gguf \ -c 32768 \ -b 512 \ --mlock \ --no-mmap \ --swap 0 \ -ngl 999几个参数的作用说清楚-c 32768上下文砍到 32K。我日常对话根本用不了 512K硬撑那个数字就是给 swap 送业绩。--mlock把模型和相关内存页钉在物理内存里不让内核置换出去。这是最直接的反换页手段。--no-mmap避免模型文件以 mmap 方式映射到地址空间减少页缓存被回收导致的额外 IO。--swap 0显式告诉引擎不要在磁盘上做自己的 swap 空间。-ngl 999尽可能把所有层都放在 GPU 侧执行减少主机内存里的搬运。注意一个搭配坑--mlock开了以后如果系统内存真的不够内核可能会走向 OOM Killer可能直接把推理引擎干掉。所以这套配置必须和合理的上下文窗口、合理的量化精度配合而不是无脑锁内存。4.2 第二档系统层面加 zram给换页一个缓冲垫有些场景确实需要长上下文比如离线总结一个几百页的文档。这时候光靠压上下文不现实于是我在系统层面加了 zram。zram 就是在内存里划一块区域压缩后当作 swap 用。内核要换页时先进 zram而不是直接写 NVMe。压缩后的匿名页可能只剩原来的三分之一到四分之一磁盘写入几乎归零代价是 CPU 要多干一点压缩活。Strix Halo 上开 zstd开销可以忽略不计。Linux 下用 systemd 的 zram-generator 配置最简单# /etc/systemd/zram-generator.conf [zram0] zram-size ram / 4 compression-algorithm zstd然后启用systemctl daemon-reload systemctl start systemd-zram-setupzram0.service启用之后把内核的 swappiness 调高一些让匿名页更愿意进 zram 而不是磁盘sysctl -w vm.swappiness100有人会问为什么不干脆把 swap 禁用我也试过。禁用 swap 的后果是内存一旦压力上来直接 OOM模型进程被杀服务不可用。我的结论是完全禁用不如保留一个小容量的 zram 当保险既能吸收突发压力又不会落到 NVMe 上。4.3 第三档检查 BIOS 里的 UMA 分配给系统内存让路参数优化完还剩一个容易被忽略的层面BIOS 里给 GPU 预留的内存大小。Strix Halo 的 BIOS 里一般有 UMA 或类似命名的选项可以指定给显卡的专用内存。我一开始是 Auto系统实际可用内存比 128GB 小不少。后来发现推理引擎主要在 GPU 侧跑我给显卡预留 48GB 足够装下 8B 模型的权重加一大段 KV Cache剩下的统统还给系统。检查当前分配可以直接看内核日志dmesg | grep -i amdgpu | grep -i VRAM或者在 ROCm 环境下看内存池信息rocminfo把 UMA 从 96GB 调到 48GB 之后系统可用内存多了 40 多 GBswap 压力肉眼可见地下降。如果你的目标是跑 70B 以上模型再考虑把 UMA 调回去但 8B 量级真用不了那么多显存预留。4.4 验证结果写入量从 256GiB 降到 2GiB三档都做完我重新跑满 48 小时做了验证。结果如下配置阶段24 小时磁盘写入增量初始配置512K 上下文无锁定swap 指向 NVMe约 256GiB压上下文 mlock 锁定约 3GiB压上下文 mlock zram 缓冲约 2GiB压上下文 mlock zram UMA 调优约 1.5GiB最后的写入量绝大部分还是系统日志、容器 overlay 这类正常开销已经不具备威胁。推理时延也比优化前稳定很多之前那种跑着跑着突然卡一下的毛刺基本消失。5. 最终配置和该养成的习惯5.1 我现在日常跑的稳定配置经过这一轮折腾最终定下来的一套配置就三句话模型用 Q4_K_M 或者更低的 IQ2_M 量化档8B 权重控制在 5-8GB别用 BF16 去和内存过不去。上下文按需开日常 32K偶尔处理长文档才临时开到 128K 以上用完立刻收回来。系统层面保留一个小容量 zram swap把 UMA 预留调到实际够用的程度剩下的内存尽量归还给系统。进程层面的启动参数就是我前面贴的那组命令没什么花哨的东西全部都是围绕别让内核产生磁盘换页这一条主线。5.2 SSD 寿命和写入监控养成本能反应这次经历之后我给自己定了两个监控习惯。第一个是每周看一次 SSD 累计写入nvme smart-log /dev/nvme0 | grep -E data_units_written|percentage_used第二个是每次启动完推理引擎先跑一遍内存压力检查vmstat 1 5重点是看so这一列只要出现持续的换出就说明配置有问题趁早停掉排查别等一个晚上再来看 256GiB 的账单。SSD 寿命这种事单看 256GiB 其实不会立刻写死一块盘真正伤的是长期这么干一年下来一百多 TB 写入普通 TLC 盘两三年就走完一大半寿命而且换页抖动带来的延迟毛刺比寿命问题更影响日常体验。5.3 一点复盘心得Strix Halo 那 128GB 统一内存本质上是把你从显存不够的焦虑里解放出来但这并不是一张可以无限透支的信用卡。内存池再大操作系统这张账本依然按物理页记账上下文开多大KV Cache 就占多大系统内存被抢光之后swap 照样会把你的 SSD 当救生圈。如果你也想在 Strix Halo 或者类似统一内存平台上长期跑千问系模型我的建议就一条不要和上下文窗口较劲。千问的长上下文能力是给你偶尔处理长文本用的不是让你 24 小时开着的默认选项。把上下文压到够用范围再辅以一个 zram 缓冲这台机器才能真正跑着不吃力睡一觉也不心慌。
返回列表