本地 CPU 推理时 mmap 文件被锁导致无法加载模型的解决方法

文章导读
遇到本地 CPU 推理时模型加载失败,错误提示里出现 mmap 或文件被锁,通常不是模型损坏,而是操作系统层面认为文件正被另一个进程使用,或文件系统挂载方式不支持映射锁定。先不要急着重下权重文件,按下面的顺序排查,大多数情况可以定位到具体占用来源并恢复加载。
📋 目录
  1. A 先区分错误类型,确认是哪一种锁
  2. B 定位占用进程,先看是谁锁住了文件
  3. C 绕开锁的两种做法:复制文件或禁用 mmap
  4. D 验证到位后再做长期预防
A A

遇到本地 CPU 推理时模型加载失败,错误提示里出现 mmap 或文件被锁,通常不是模型损坏,而是操作系统层面认为文件正被另一个进程使用,或文件系统挂载方式不支持映射锁定。先不要急着重下权重文件,按下面的顺序排查,大多数情况可以定位到具体占用来源并恢复加载。

模型文件被锁多因同一文件已被其他进程以读写方式占用,或挂载目录的锁语义异常。先读错误码,再用 lsof/fuser 查占用进程;确认后终止占用的推理进程或备份程序即可释放锁。若无法终止,可在支持该参数的框架下关闭 mmap 加载,或把模型复制到本地磁盘再试。此方案只针对文件锁问题,模型文件损坏或内存不足会表现为另外的错误。

先区分错误类型,确认是哪一种锁

同样表现为“加载失败”,锁冲突的消息可能不同。常见的有:Permission denied、Resource temporarily unavailable(EAGAIN)、Text file busy(ETXTBSY)。前两种多半是文件正在被其他进程读写,后一种常见于文件被当作可执行程序或共享库映射且正被执行。模型推理中更常见的是前两种,但不要跳过确认环节。直接看完整错误输出,能省下很多重复排查。

适用场景:本地或单机环境,AI 推理程序加载权重文件时被操作系统拒绝。操作动作:记录错误中提到的文件路径和错误码。验证方式:确认错误确实反复指向同一个文件。风险边界:如果错误来自权限或磁盘空间,按文件锁处理无法解决。

定位占用进程,先看是谁锁住了文件

最直接的判断方式是用 lsof 或 fuser 查看文件被谁打开。建议先跑 lsof:

lsof /path/to/model.bin

如果输出为空或系统没有 lsof,再用 fuser:

本地 CPU 推理时 mmap 文件被锁导致无法加载模型的解决方法
fuser -v /path/to/model.bin

输出会列出进程 PID、用户和访问方式。看到有进程在读写这个文件,基本就找到了锁的来源。常见占用者是同类模型的另一个推理进程、还未退出完毕的 python / python3 进程、备份程序、文件索引服务或编辑器的临时文件保留。

操作动作:确认 PID 所属进程后,确认不是正在执行的重要任务,再终止它:

kill <PID>

验证方式:终止后再执行一次模型加载,能成功代表锁已释放。风险边界:杀进程前要确认该 PID 是否属于数据库、正在写日志的服务或其它关键程序;强行结束可能造成数据不一致。如果占用的进程是推理服务本身,建议先停掉旧实例再启动新实例,不直接用 kill -9。

绕开锁的两种做法:复制文件或禁用 mmap

如果已经定位到占用进程但无法停止,或挂在网络文件系统上找不到明显占用者,可以绕开锁继续加载。两条路:把模型复制到本地磁盘,或让推理程序不用 mmap 方式读文件。

本地 CPU 推理时 mmap 文件被锁导致无法加载模型的解决方法

复制文件是最容易验证的方式:

cp /mnt/nfs/model.bin ~/models/model.bin

然后改为加载 ~/models/model.bin。适用于所有框架,操作动作简单。验证方式是看新路径能否正常加载。风险边界是模型较大的时候需要额外磁盘空间;但能够判断锁是否与挂载目录相关。

如果复制后仍失败,说明问题可能不在文件系统层级,这时再考虑关闭 mmap 加载。不过这依赖于具体推理框架是否暴露这一开关,需要结合所用框架的版本和文档确认。可以先用一个最小脚本测试,加载一个小模型看参数是否生效,再应用到实际模型。以 llama.cpp / GGML 为例,加载时通常有 `--no-mmap` 参数;transformers 及 safetensors 不同版本对 mmap 的处理方式不同,有些版本可以临时关闭,有些版本只能通过先加载到内存再交给模型的方式绕开。

本地 CPU 推理时 mmap 文件被锁导致无法加载模型的解决方法

适用场景:文件锁来源不明确,或占用进程无法终止时使用。操作动作:先复制文件测试,再考虑禁用 mmap。验证方式:用修改后的加载方式成功完成一次推理。风险边界:禁用 mmap 会显著提高内存占用,CPU 推理时要确保物理内存足够;复制文件也只是临时手段,仍需找到根因。

验证到位后再做长期预防

完成上述操作后,不能只看文件加载成功就结束。至少要跑一次推理并确认输出正常。若第一次推理正常,再决定后续使用方式。如果多次出现在同一路径上,应当回到锁占用和挂载方式上继续排查,而不是每次加载前都手动杀进程。

几个可以长期保持的做法:

  • 模型文件单独放目录,不和日志、临时文件混用。
  • 启动推理前先用 lsof 检查模型路径是否被旧进程占用。
  • 团队共用机器时约定同时只启动一个加载同一路径的实例。
  • 网络文件系统上的模型,先同步到本地再加载。

如果这些步骤都做过了但加载仍然失败,就不要再局限于锁问题。换一台机器或换一个目录加载同一份文件,仍失败就检查文件完整性和权限;如果只有特定用户能加载,要看程序运行账户是否对路径有读权限。这些问题不在锁的范畴内。