前两天把 Strix Halo 平台带回家,本意是顺顺当当跑一轮qwen3.8 flash next的本地推理测试。结果一天下来,没被显存温度难住,倒是被主盘写入量吓了一跳:24 小时左右,NVMe 盘的主机写入量狂飙了 256GiB 上下。听起来像是老式硬盘在烤机,可我手上的盘明明是一块健康的 PCIe 4.0 NVMe 固态盘。问题到底出在哪,今天把完整的排查过程、根因分析和调优思路摊开讲。
1. 一天写掉256GiB,先把现场还原出来
不要一上来就甩锅给“大模型本来就很吃盘”。LLM 推理确实要读权重、写日志、落缓存,但正常持续推理不会按这种速度刷盘。先把现场数据抓出来,再谈怎么修,不然很容易被各种“硬盘修复工具”带偏。
1.1 从 S.M.A.R.T 数据到 iotop 抓现行
这台机器装的是 Linux,磁盘设备名很典型:/dev/nvme0n1p5。第一次看到这个路径的人容易懵,拆开说就是:nvme0代表第 1 个 NVMe 控制器,n1代表该控制器下的第 1 个 namespace,p5代表这块盘上的第 5 个分区。所以它的意思确实可以理解为“第一块 NVMe 硬盘的第五个分区”。排查写入问题时,不建议只看整个分区,直接对整块设备看信息更清晰。
我习惯先看一遍 S.M.A.R.T 数据:
smartctl -x /dev/nvme0n1重点关注这几项:
Data Units Written:主机往 NAND 里写的累计单位数Percentage Used:按官方寿命模型估算的磨损百分比Available Spare:备用块剩余比例Temperature:温度异常也会加速颗粒老化
实测在跑qwen3.8 flash next之前,Data Units Written还算正常。跑完一轮持续生成任务后再看,数值换算后已经多出几十 GB 级的写入,而且Percentage Used往上跳了一个点。这种写入量,如果每天都这么跑,一块普通 TLC 盘的寿命会肉眼可见地缩水。
但 S.M.A.R.T 只能告诉你“写了很多”,不能告诉你“是谁在写”。继续上工具:
iotop -d 2 -o-o参数只显示有 I/O 的进程。看了一会儿,发现高耗 I/O 的不只是模型进程,还有系统日志进程、容器运行时、以及一个在疯狂读旧进程页面的 swap 后台线程。也就是说写入来源不止一个,而是由内存压力引发的一连串反应。
1.2 真实根因:显存咬掉内存,swap 来凑
Strix Halo 这种平台最强的地方是整合了大规模图形/计算单元和统一内存架构,跑模型时可以给核显分配大块显存。但这恰恰是个坑:很多主板默认会让核显吃掉不少系统内存,如果再手抖把显存固定成一个大值,留给操作系统的可用内存就会变得很紧张。
我当时为了“给模型多留点 AI 算力”,在 BIOS 里把显存预留调得偏高。模型加载时,权重要 mmap 进地址空间,KV cache 又要申请大量内存,剩余内存不够时,系统就会把匿名内存页换到 swap。swap 如果落在 SSD 上,写入量立刻起飞。
于是现场就变成了:
- 模型进程大量申请内存,系统触发内存回收
- 匿名页被写回 swap 分区
- swap 写入走 NVMe,主机写入量暴涨
- 模型后续访问这些页时,又从 SSD 读回来,形成大量读写
- 日志和缓存还在持续追加,进一步加大写入量
这就是“一天 256GiB”最直接的解释。问题核心不是qwen3.8 flash next本身,而是它的运行环境没有把内存和磁盘策略处理好。
1.3 先做临时应急,别等盘写废了再处理
发现原因后,我第一时间不是去优化模型参数,而是先做止损:
# 查看当前 swap 设备,确认是不是占用 SSD swapon --show # 临时关掉 swap,避免继续写入 swapoff -a同时把日志输出临时改成内存 tmpfs,避免 journald 继续往 NVMe 写无关紧要的日志。确认写入曲线降下来后,再慢慢做长期调优。注意,swapoff -a只是应急,如果内存确实紧张,反而可能触发 OOM。更合理的做法是用 zram 之类的压缩交换设备,后面细说。
2. 闪存盘的耐力vs机械盘的“填充习惯”
很多人第一次看到这种写入量,会忍不住想:硬盘是不是要准备“重新格式化”或者“刷一下固件”了。先别急,搞懂 SSD 的写入机制,你才知道哪些操作有意义,哪些操作只是给数据恢复公司送钱。
2.1 空盘写入时,数据到底在怎么“填”
热词里有一条很有意思:“空硬盘写入数据填充磁道和扇区的顺序是什么?”如果问的是机械硬盘,那确实存在物理磁道和扇区。早年整盘格式化时,固件会按 LBA 从 0 开始递增,尽量让数据连续落在磁道上,写满一个磁道再换下一个。从操作系统视角看,这是一种相对“有序”的填充方式。
但 SSD 没有磁道概念,NAND 的最小单位是页,擦除单位是块。你看到的sector其实已经是被 FTL(Flash Translation Layer)映射过的逻辑扇区。闪存控制器会把逻辑地址映射到物理块,写入时还会做磨损均衡,故意让不同块的擦写次数尽量平均。所以“填磁道”这套机械时代逻辑,在 SSD 上完全不管用。你以为在写连续的逻辑地址,实际颗粒里可能在东一块西一块地找空闲块。
还有一个关键点:擦写放大。数据要覆盖旧位置的页时,SSD 往往得先把一整个物理块里的旧数据搬出来,写新数据,再整体擦除。写入量在逻辑层是 1,到了物理颗粒层可能就是 2 倍甚至更高。如果一个系统频繁产生小块随机写,写入放大更明显,S.M.A.R.T 里看到的“主机写入量”还是偏乐观的,颗粒真实磨损可能更高。
所以,不要拿机械盘时代“低格一下恢复状态”的思路套固态盘。“低格”对 SSD 来说是大量擦写操作,除了带来无谓磨损,不会让盘变得更快。包括搜索词里提到的“smr硬盘低级格式化操作”,对叠瓦式机械盘也没有真正焕发新生的作用,反而可能因为反复重写邻近磁道拖慢整个盘。
2.2 SATA、M.2 与 NVMe 的耐久差异
现在台式机主流盘是 M.2 NVMe,但也还有不少人机箱里挂着一块 SATA SSD,甚至一块旧的机械盘。它们坏的特性其实是不同的。
我整理过一张便于自测的对照表:
| 盘体类型 | 常见接口形式 | 主要磨损因素 | 监控方式 |
|---|---|---|---|
| SATA SSD | 2.5 寸 SATA 口 | 重复写小文件、垃圾回收、固件 bug 导致写放大 | smartctl -a /dev/sda |
| M.2 NVMe SSD | M.2 PCIe 通道 | 高随机写、swap、日志、数据库提交 | smartctl -x /dev/nvme0n1 |
| 机械硬盘 | SATA 3.5/2.5 寸 | 磁头归位、坏道扩散、震动 | smartctl -a,Victoria 扫描 |
| SMR 机械盘 | SATA 或 USB 盒 | 随机小幅写入时触发搬运 | smartctl + 避免频繁小写 |
SATA SSD 和 M.2 NVMe 在寿命模型上都看写入量,但 NVMe 的突发带宽更高,短时间“狂写”的破坏力表现更明显。如果只是跑模型,我更建议把日志、临时缓存放到一个不太重要、便宜、大容量的盘上,不要把模型权重和高频写入全压在系统主盘上。
2.3 如果组 RAID6,会不会更稳
另一个搜索词是“raid6硬盘要求”。这里多说一句:不要一听 RAID6 就觉得数据安全又提升。RAID6 确实能容忍两块盘同时失效,但它需要至少 4 块盘,而且每次写入都要计算并写入双重校验数据。在 LLM 这种大连续读、小高频写的场景下,RAID6 的校验写入会让 SSD 的实际盘内写入进一步放大。
如果一定要上 RAID,尽量用 RAID1 保证可用性,或者对日志盘做 RAID0 提速但对数据及时备份。真拿 4 块 NVMe 做 RAID6 跑模型缓存,第一周可能没什么感觉,跑一个月再看 S.M.A.R.T,磨损差距是很明显的。对个人服务器来说,重要模型权重用独立备份盘比做 RAID6 更实在。
3. 止损调优记录:关 swap、调缓存、改日志
排查完理论原因,接下来给出一套可复现的调优流程。这套操作我在新跑模型时都会来一遍,能有效把每天的写入量从几百 GB 压到几十 GB 甚至更低。
3.1 给系统上 zram,而不是直接“没有 swap”
很多教程会直接说“关掉 swap 就好”。但机器内存一旦吃紧,没有 swap 会触发 OOM Killer,模型进程被杀更烦。正确做法是把落盘 swap 换成 zram,让交换区走内存压缩,不碰 SSD。
我用的方案是:
modprobe zram num_devices=1 zramctl --find --size 16G mkswap /dev/zram0 swapon -p 100 /dev/zram0-p 100是给予较高优先级,让系统优先用 zram,而不是原来的磁盘 swap。同时修改vm.swappiness:
sysctl -w vm.swappiness=10此时内存压力大时,系统会先把匿名页压缩进 zram,只有 zram 满了才考虑落盘。虽然 zram 会吃掉一部分 CPU 做压缩解压,但对 Strix Halo 这种核心数量充足、CPU 冗余明显的平台,完全值得。
还要注意把原始磁盘 swap 从启动中挪走,去/etc/fstab把对应的 swap 行注释掉,否则下次开机又回来了。
3.2 把日志和模型缓存迁移到 tmpfs
排除了 swap,还得处理日志。跑模型时 Python 进程、推理框架、系统 journald 都可能频繁写日志。尤其有些框架开 debug 后,每生成一个 token 都写一行 trace,一天下来日志可能比模型文件还大。
我是这样处理的:
mkdir -p /var/log/qwen mount -t tmpfs -o size=2G tmpfs /var/log/qwen把推理框架日志目录指到这个 tmpfs 里,日志写满 2G 后自动无内容,也不伤 SSD。journald 也值得限一下:
journalctl --vacuum-time=1d如果长时间跑实验,可以在/etc/systemd/journald.conf里把Storage=volatile,让日志直接落在/run的内存文件系统里。机器一重启日志就没了,对排查本地模型问题完全够用。
3.3 确认 TRIM 和 discard 是否生效
经过上面的调整,写入量会明显降下来,但长期用还得保持固态盘的回收效率。NVMe SSD 删除文件后,如果没有按时发 TRIM 指令,主控就不知道该把块标记为空闲,后续写入时垃圾回收会拖后腿,也会放大写入。
检查 TRIM 最简单的方式:
fstrim -v /如果返回结果不是 0 B,说明系统在正常回收可用空间。最近几代内核还支持discard=async挂载选项,在 Ext4 或 Btrfs 上都能用:
# 挂载示例,下面的参数请结合自己的分区情况 mount -o discard=async /dev/nvme0n1p5 /mnt/data对长期跑大模型的人来说,开机后用fstrim.timer定期整理就够,不用实时 discard 每两次删除都发指令。
4. 常用工具和问题速查表
这一节把这些年攒下的检测与恢复经验整理成速查,方便大家遇到类似写入异常时少走弯路。尤其是“固态硬盘开卡”“量产工具”“硬盘免费恢复”这些词,经常误导新人。
4.1 健康检测工具怎么选
| 使用场景 | 合适命令/工具 | 注意点 |
|---|---|---|
| NVMe 写入量、温度、备用块查看 | smartctl -x /dev/nvme0n1 | 看Data Units Written和Percentage Used |
| SATA/SAS 硬盘坏道扫描 | Victoria 或badblocks -sv | Victoria 适合 HDD,对 SSD 意义有限 |
| 文件系统层面排查崩溃日志 | dmesg -T,journalctl -p err | 先看内核日志,别急着拆盘 |
| 文件删除后空间不释放 | lsof +L1 | 找到被删除但仍被进程占用的文件 |
| 查看某路径实时被写文件 | fatrace | 能定位到具体文件路径,很直观 |
遇到“写入异常”时,先做“看、测、改、观察”四步:看 S.M.A.R.T,测 I/O,改系统参数,观察一周内的写入曲线。不要一上来就用开卡工具,那基本属于医疗级手段,放到最后再说。
4.2 S.M.A.R.T 变“坏”会影响安装系统吗
搜索词里有人问“硬盘:s.m.a.r.t坏影响安装系统吗?”。我的答案是:S.M.A.R.T 本身只是个报告系统,不是拦截器。大多数安装程序即使看到 SMART 告警,也不会强制阻止安装。但如果盘已经出现大量读取错误、坏块漂移,继续往里装系统就是给未来埋雷。你装了一半,系统在写引导程序时遇到坏块,重装多少次都会失败。
建议在安装前跑一次:
smartctl -a /dev/sda尤其注意Reallocated_Sector_Ct和Current_Pending_Sector。只要有一项异常,就别让这块盘承担系统盘角色。至于“固态硬盘文件或目录损坏”,优先做映像备份,再用fsck或者对应文件系统工具修,不要马上量产。文件系统错误和颗粒物理损坏是两回事。
4.3 PVE 直通硬盘、SATA 盘与 M.2 盘怎么分清
如果你和我一样用虚拟化平台,比如 PVE,那么还需要注意直通模式对监控的影响。pve 直通硬盘如果只是把/dev/sdb转给虚拟机,宿主机上的smartctl很可能看不到盘的真实状态,因为它把整个设备权限移交给了 guest。更建议用 PCIe 直通把 NVMe 控制器直接交给虚拟机,然后在虚拟机内部跑smartctl,这样 SMART 信息仍然可见。
至于 SATA 盘和 M.2 盘,不要只看外观。有些 M.2 槽只支持 SATA 协议,槽位上的颗粒形状一样,但走的是 AHCI。买盘前看准规格,安装系统时也注意别把两个 M.2 通道搞混,跑模型时读写瓶颈经常就是这么来的。
4.4 关于“固态硬盘开卡”和“免费恢复”的冷水
“固态硬盘开卡”听起来很技术流:主控重新初始化、重新映射坏块、恢复出厂状态。但现实是,开卡工具必须严格匹配主控型号和闪存颗粒型号,颗粒参数、坏块表、固件版本一个都不能错。多数情况下你拿到的量产工具根本不知道颗粒的具体 ID 参数,硬开只会把原有坏块表清掉,盘可能直接变砖。
SSD 出现“只能读取无法写入”之类的问题,优先考虑并查备用块是否耗尽,再看固件是否触发写保护。数据没备份前不要做破坏性操作。“免费恢复软件”对简单误删有一点参考价值,但别指望在掉盘断电后还能靠它救命。普通用户最靠谱的策略只有两个:定期备份,以及购买有完整断电保护机制的企业盘。
5. 最后再提个醒
现在这台 Strix Halo 跑qwen3.8 flash next已经平稳多了。我把显存预留调回动态分配,swap 全部换成 zram,日志和中间缓存放到 tmpfs,再给数据盘加了fstrim.timer。同样跑一整天的持续生成任务,盘面新增写入量基本回到可接受范围。
我个人的习惯是:每次要连续跑模型前,先看三样东西——swap 开没开、日志写哪、临时缓存目录是否在 NVMe 上。另外,别再迷信“空盘按磁道顺序填数据”这种老概念了,固态盘的寿命管理早就交给了 FTL 和主控。遇到一天几百 GiB 的写入,第一时间找 swap 和日志,别急着换盘或开卡,大多数问题出在系统配置而不是硬盘本身。
补充一点,如果你在跑模型后感觉“系统响应变慢、磁盘活动时间 100%”,也用同样思路查。先看内存压力,再看 swap 设备,最后才怀疑盘本身故障。这几个排查动作不花多少时间,但能避免很多没必要的 SSD 磨损和数据风险。