MinerU 命令行参数进阶:推理引擎参数透传与多 GPU 设备配置实战
本文讲解 MinerU 命令行体系中两项进阶能力:将 vLLM / LMDeploy 官方支持的任意推理引擎参数直接透传给 mineru 系列命令,以及通过 CUDA_VISIBLE_DEVICES 环境变量在 pipeline 与 vlm 后端上精确控制 GPU 设备分配。读完本文,你可以理解参数透传的底层解析机制(从 click 的未知参数捕获到 vLLM CLI 的二次转发),并能完成双卡双服务、多卡路由等典型的多 GPU 部署方案。
推理引擎参数透传
参数传递说明
MinerU 的五个命令行入口——mineru、mineru-openai-server、mineru-gradio、mineru-api、mineru-router——都支持把 vLLM / LMDeploy 官方支持的参数原样通过命令行传递进去,而无需在代码中逐个声明。两个关键规则:
- 命令行参数同时支持
--foo value与--foo=value两种写法; - 透传参数以 vLLM / LMDeploy 官方参数文档为取值依据(分别可查阅 vLLM 的 CLI serve 文档与 LMDeploy 的 api server 文档)。
透传机制的源码解析
透传能力由两个环节共同实现:未知参数捕获与参数类型归一化。
第一个环节是 click 的命令配置。五个入口均使用了相同的声明:
@click.command(context_settings=dict(ignore_unknown_options=True, allow_extra_args=True))
@click.pass_context
分别位于 mineru/cli/client.py(mineru)、mineru/cli/fast_api.py(mineru-api)、mineru/cli/gradio_app.py(mineru-gradio)、mineru/cli/router.py(mineru-router)和 mineru/cli/vlm_server.py(mineru-openai-server)。ignore_unknown_options=True 让 click 不拒绝任何未声明的选项,allow_extra_args=True 让它们保留在 ctx.args 中等待后续处理。
第二个环节是 mineru/utils/cli_parser.py 中的 parse_unknown_args,它负责把捕获到的原始参数串解析成键值对:
def parse_unknown_args(args: Sequence[str]) -> dict:
"""Parse unknown click args into keyword arguments."""
extra_kwargs = {}
i = 0
while i < len(args):
arg = args[i]
if not arg.startswith("--"):
i += 1
continue
raw_option = arg[2:]
if "=" in raw_option:
param_name, raw_value = raw_option.split("=", 1)
extra_kwargs[param_name.replace("-", "_")] = _coerce_cli_value(raw_value)
i += 1
continue
param_name = raw_option.replace("-", "_")
next_index = i + 1
if next_index < len(args) and not args[next_index].startswith("--"):
extra_kwargs[param_name] = _coerce_cli_value(args[next_index])
i += 2
continue
extra_kwargs[param_name] = True
i += 1
return extra_kwargs
从这段实现可以读出几个实际行为:
- 两种写法等价:
--foo value(值取下一个非--开头的 token)与--foo=value(按第一个=切分)都会进入同一个字典,参数名中的连字符会统一替换为下划线(--max-model-len→max_model_len); - 自动类型推断:_coerce_cli_value 会按
true/false→ 布尔、整数 →int、浮点数 →float、其余 → 原字符串的顺序做类型归一化,因此--temperature 0.7传入的是浮点数而非字符串; - 无值参数视为标志位:后面没有取值(或紧跟另一个
--参数)的选项会被置为True。
以 mineru-api 为例,fast_api.py 的 main 入口 在解析后调用 arg_parse(ctx) 取出全部未知参数,再通过 split_service_and_model_config 把其中的服务级配置(目前为 enable_vlm_preload)剥离出来,剩余部分作为模型推理配置写入 app.state.config,供后续引擎初始化时使用。也就是说,你在 mineru-api 上多敲的任何 -- 参数,最终都会作为 kwargs 流入 VLM 引擎的初始化调用。
对于 mineru-openai-server,转发链更直接:vlm_server.py 先根据 --engine auto|vllm|lmdeploy 选择引擎(auto 模式优先尝试导入 vLLM,失败则回退 LMDeploy,两者都缺失时报错退出),然后把 ctx.args 拼回 sys.argv 并调用 mineru/model/vlm/vllm_server.py 的 main()。后者会先剔除用户显式传入的 --model(改由 auto_download_and_get_model_root_path 自动解析模型路径),为未指定的 --port 补默认值 30000、为未指定的 --gpu-memory-utilization 补一个按卡型计算的默认值,再把你透传的其余参数原样拼到 vllm serve <model_path> 之后,最终交给 vllm.entrypoints.cli.main.main()。这正是"vLLM 官方支持的参数都可透传"的完整证据链——MinerU 自身只是参数搬运工,语义由 vLLM CLI 解释。
GPU 设备选择与配置
CUDA_VISIBLE_DEVICES 基本用法
任何情况下,你都可以通过在命令行的开头添加 CUDA_VISIBLE_DEVICES 环境变量来指定可见的 GPU 设备:
CUDA_VISIBLE_DEVICES=1 mineru -p <input_path> -o <output_path>
这种指定方式对所有命令行调用都有效,包括 mineru、mineru-openai-server、mineru-gradio、mineru-api 和 mineru-router,且对 pipeline、vlm 后端均适用。原因在于 CUDA_VISIBLE_DEVICES 由 CUDA 运行时在进程启动时统一处理,发生在 Python 代码与任何推理框架加载 GPU 之前,因此与具体后端(PyTorch、vLLM、LMDeploy)或 MinerU 的解析逻辑无关——这是它比框架内设备参数更通用的根本原因。
常见设备配置示例
以下是一些常见的 CUDA_VISIBLE_DEVICES 设置示例:
CUDA_VISIBLE_DEVICES=1 # Only device 1 will be seen
CUDA_VISIBLE_DEVICES=0,1 # Devices 0 and 1 will be visible
CUDA_VISIBLE_DEVICES="0,1" # Same as above, quotation marks are optional
CUDA_VISIBLE_DEVICES=0,2,3 # Devices 0, 2, 3 will be visible; device 1 is masked
CUDA_VISIBLE_DEVICES="" # No GPU will be visible
需要注意两点:引号在 bash 下是可选的(0,1 不含空格时不会被 shell 拆分),但在某些 shell 中保留引号更安全;置空字符串("")等价于让进程完全看不到 GPU,适合验证纯 CPU 链路或避免误占显存。
实际应用场景
多卡双 openai-server 实例
如果有多张显卡,需要在卡 0 和卡 1 上各启动一个 openai-server 服务、分别监听不同端口:
# 在终端1中
CUDA_VISIBLE_DEVICES=0 mineru-openai-server --engine vllm --port 30000
# 在终端2中
CUDA_VISIBLE_DEVICES=1 mineru-openai-server --engine vllm --port 30001
这里 --port 是 vLLM serve 的子命令参数,经由上述透传机制进入 vLLM CLI;由于每个进程只能看到一张卡,vLLM 内部会以设备 0 编号来管理它,两个实例互不干扰。从 vlm_server.py 可以看到,--engine vllm 会强制走 vLLM 路径(跳过 auto 检测),避免环境中两种引擎同时安装时的歧义。
多卡双 fastapi 服务
如果需要在卡 0 和卡 1 上启动两个 fastapi 服务、分别监听不同端口:
# 在终端1中
CUDA_VISIBLE_DEVICES=0 mineru-api --host 127.0.0.1 --port 8000
# 在终端2中
CUDA_VISIBLE_DEVICES=1 mineru-api --host 127.0.0.1 --port 8001
--host(默认 127.0.0.1)与 --port(默认 8000)是 mineru-api 自身声明的选项,与透传参数分开处理。另外 mineru-api 还支持 --enable-vlm-preload 选项:开启后会在启动阶段通过 preload_vlm_model 用 ModelSingleton 提前加载本地 VLM 模型,避免首个请求的冷启动开销。
四卡 mineru-router 统一管理
如果有 4 张卡,需要通过 router 在这些卡上启动 fastapi 服务并统一管理:
CUDA_VISIBLE_DEVICES=0,1,2,3 mineru-router --host 127.0.0.1 --port 8002
router 进程能同时看到 4 张卡(对进程内它们被重新编号为 0~3),由其内部逻辑在多卡上拉起并调度后端服务,对外只暴露 8002 一个入口。mineru-router 与其余入口共享同一套 ignore_unknown_options 声明(见 mineru/cli/router.py),因此同样接受引擎参数透传。
使用前提与限制
- 引擎参数透传只对
vlm后端有意义:透传的参数最终流入 vLLM / LMDeploy 引擎,pipeline 后端的模型加载不走该引擎路径; - 透传参数名中的连字符会被规范化为下划线,类型按"布尔 → 整数 → 浮点 → 字符串"顺序推断,复杂类型(如嵌套列表)无法通过这种扁平方式传入;
- 未带取值的
--flag形式参数会被解析为True,如果该参数在引擎侧确实需要值,请显式写成--flag value或--flag=value; CUDA_VISIBLE_DEVICES在进程启动时即生效,运行中修改该变量不会影响已启动的服务,需要重启进程才能切换设备。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00