Unlimited-OCR 部署运行(11/13):环境变量块超限导致 spawn 子进程崩溃

Unlimited-OCR 部署运行(11/13):环境变量块超限导致 spawn 子进程崩溃

第 09 篇 给了"最稳的启动命令",其中第一条就是 unset ACC_PRODUCT_CONFIG_V3。本篇讲清楚为什么必须这样做 ------一个只在 Windows 上出现、且极具迷惑性的故障:服务日志停在 server_args 后完全无输出、GPU 显存不涨、worker 卡在 ~866MB CPU 内存,看似"模型加载慢",实则子进程已经崩了。


一、现象:日志停在 server_args,然后"静默挂起"

  • 日志打印完 server_args=...再无任何输出(没有 "Loading weights"、没有 JIT 进度)。
  • GPU 显存始终 ~532 MiB(模型权重没传到 GPU)。
  • worker 进程停在 ~866 MB CPU 内存、~11.5 CPU 秒、~49--52 线程,长时间无变化 → 硬挂起,不是慢加载。
  • /health 持续 DOWN;run_server.py 最终超时。

第一直觉是"模型加载慢 / JIT 编译卡住"。但监控(见 第 09 篇 第四节)显示 GPU 显存根本没动------这说明问题在模型加载之前


二、根因:Windows 环境变量块 ≤ 32,767 字符

SGLang 用 multiprocessing + spawn 拉起 tokenizer / worker 子进程。Windows 的 CreateProcess整个父进程环境块 传给子进程,而 Win32 对环境块大小有硬上限 32,767 字符

实测本机父进程(在某壳层 / IDE 下)继承了超大环境变量块:372,009 字符 ,远超上限。其中元凶是单个变量 ACC_PRODUCT_CONFIG_V3354 KB(由本机某壳层 / IDE 注入)。

超限后,spawn 出来的子进程在 import torch 阶段直接访问冲突崩溃(0xC0000005,父进程收不到任何子进程输出 → 表现为"日志停在 server_args 后无输出、GPU 显存不增长、worker 卡死"。

关键认知:父进程自己能跑、能打印 server_args,不代表子进程能起来 。spawn 子进程是一个全新的 CreateProcess,它要复制整个 env 块------父进程 env 块过大,子进程在最早阶段就崩了,连报错都传不回父进程。


三、为什么"之前能跑通"

同一份代码,之前曾生成 3554+ token 成功跑通。原因是:那时父进程环境块恰巧较小 (没被注入那个 354KB 变量)。后来环境被注入超大变量后,必然崩溃。这解释了"明明什么都没改,怎么突然起不来了"------你没改代码,但环境变了


四、修复 A:代码层兜底(_shrink_env_for_windows_spawn

sglang/srt/entrypoints/engine.py 新增 _shrink_env_for_windows_spawn(),在 _set_envs_and_config() 中调用(仅 sys.platform == "win32" 生效):

python 复制代码
def _shrink_env_for_windows_spawn():
    if sys.platform != "win32":
        return
    size = _win_env_block_size()          # 所有 k+v+2 的字符总和
    if size <= _WIN_ENV_BLOCK_BUDGET:     # 30000,留余量低于 32767
        return
    # 按"变量占用字符数"从大到小排序
    big = sorted(os.environ.items(), key=lambda kv: len(kv[0]) + len(kv[1]), reverse=True)
    for k, v in big:
        if _WIN_ENV_BLOCK_BUDGET - (len(k) + len(v) + 2) < 512:
            break                        # 单变量成本 < 512 就停手,避免误删小变量
        if k in _WIN_ENV_KEEP_EXACT or any(k.startswith(p) for p in _WIN_ENV_KEEP_PREFIXES):
            continue                      # 白名单保护
        del os.environ[k]
    # 若仍 > 32767,打印 ERROR 提示手动 unset
  • 白名单保护_WIN_ENV_KEEP_PREFIXESCUDA/NCCL/TORCH/TRITON/HF_/TRANSFORMERS/PYTHON/SGLANG/FLASHINFER/OMP_/MKL_ 等)与 _WIN_ENV_KEEP_EXACTPATH/TEMP/SYSTEMROOT/USERPROFILE 等)绝不删除------CUDA / torch / triton 相关变量被保留,子进程才能正确初始化。
  • 启动时会打印:Windows environment block was 372483 chars (limit 32767). Removed ACC_PRODUCT_CONFIG_V3 (354881 chars) to keep spawned subprocesses loadable.

五、修复 B(推荐):启动前先 unset 大变量

代码兜底能救场,但最稳的启动仍是在父进程侧先 unset 那个超大变量,让父进程 env 块本身就 < 32K:

bash 复制代码
cd K:\PythonProjects5\Unlimited-OCR
unset ACC_PRODUCT_CONFIG_V3
.venv\Scripts\python.exe -u -m sglang.launch_server --model C:/models/Unlimited-OCR ...

这样父进程 env 块干净,spawn 子进程从一开始就不会撞上限,连兜底逻辑都不需要触发。


六、监控与判定(不依赖日志)

再次强调:Windows 下子进程 stdout 经管道/重定向会严重缓冲,日志常为空。用客观信号判断:

bash 复制代码
# GPU 显存是否增长(模型传到 GPU 的标志)------本故障下它不涨
nvidia-smi --query-gpu=memory.used,memory.free --format=csv,noheader
# worker 是否推进(卡在 ~866MB 即疑似本故障)
powershell -Command "Get-Process python | Sort-Object CPU -Descending | Select-Object -First 5 Id,@{N='MemMB';E={[math]::Round($_.WorkingSet64/1MB)}},@{N='CPU';E={[math]::Round($_.CPU,1)}} | Format-Table -AutoSize"

修复 env 块超限后,模型从 C: SSD 冷启动 ~50--60s 内 完成加载并 fired up------印证根因就是它。


七、给你的避坑清单

  1. "启动即崩 / 日志停在 server_args"的第一反应 :查父进程环境块大小

    bash 复制代码
    python -c "import os;print(sum(len(k)+len(v)+2 for k,v in os.environ.items()))"

    若接近或超 32767,多半又是某个超大变量被注入------先 unset 它,或依赖 engine.py 的自动收缩兜底。

  2. 不要只盯日志文件:Windows 子进程日志缓冲会骗你"卡住了",用 nvidia-smi / 进程内存判断进度。

  3. 该修复是 第 09 篇 启动命令里 unset ACC_PRODUCT_CONFIG_V3 的依据;它与 第 10 篇 的 15 个 Windows 补丁共同构成"运行时与官方仅差有意的 Windows 适配"的结论。


八、小结与下一篇

本篇的故障只在 Windows 上存在 ,且根因不在 Python 代码、不在 CUDA,而在 Win32 CreateProcess 的环境块 32KB 上限 + 某个 IDE / 壳层注入的 354KB 变量。修法是双保险:代码层 _shrink_env_for_windows_spawn() 自动收缩(带白名单保护)+ 启动前 unset 大变量。

第 12 篇 转入性能调优:RTX 3090 上 SGLang 启动会打印 Using default MoE kernel config. Performance might be sub-optimal! 警告------讲清为什么不能盲拷 A100 的 autotune 配置(会运行时崩溃),以及如何为 3090 生成一份安全且有效的 MoE triton autotune config。


系列导航(全 14 篇) (同第 09 / 10 篇,略)

部署运行篇:09 正确启动 · 10 排障①乱码 · 11 排障②环境变量崩溃(本篇) · 12 MoE 性能调优 · 13 长文档验证与使用指南


参考资料与延伸阅读

以下为本文涉及的官方仓库、文档与规格站,建议发布前点一遍确认可达:

相关推荐
love530love3 小时前
Unlimited-OCR 部署运行(12/13):RTX 3090 MoE triton autotune config 消除性能警告
ocr
开开心心就好3 小时前
批量图片OCR识别重命名工具完全免费
随机森林·智能手机·ocr·电脑·word·音视频·最小二乘法
liferecords1 天前
HPD-Parsing: Hierarchical Parallel Document Parsing
人工智能·算法·ocr·idp·vlm
weixin_408099672 天前
2026 扑克牌识别 API 实战:识别牌值、花色、大小王(附 Python/Java/PHP 接入示例)
python·ocr·图像识别·api接口·接口开发·扑克牌识别·石榴智能
开开心心就好2 天前
内存清理工具定时自动清理开机自启动
java·开发语言·elasticsearch·ocr·excel·音视频·big data
王莎莎-MinerU2 天前
别让 Agent 重读 PDF:文档解析要交付可缓存资产
网络·数据库·人工智能·驱动开发·缓存·pdf·ocr
开开心心就好2 天前
电脑内存优化工具一键释放内存超简单
java·开发语言·macos·arcgis·ocr·excel·音视频
m0_726365833 天前
# Chrome纸牌游戏预测工具开发实战:Canvas图表识别、OCR与实时状态监控
chrome·python·游戏·贪心算法·ocr·线性回归·哈希算法
六月的翅膀3 天前
OCR:RapidOCR C++/C#
c++·ocr