Surya 2 用 vllm 后端时如何通过 --max-num-seqs 和 --max-num-batched-tokens 提升吞吐量?
【免费下载链接】suryaOCR, layout analysis, reading order, table recognition in 90+ languages项目地址: https://gitcode.com/GitHub_Trending/su/surya
在 NVIDIA GPU 上用 Surya 2 批量跑 OCR、版面分析或表格识别时,吞吐量由推理后端决定:layout / OCR / table_rec 共享同一个 VLM,而 vllm 服务端能同时处理多少页,上限就卡在--max-num-seqs(最大并发请求数)和--max-num-batched-tokens(单批最大 token 数)这两个服务端参数上。README 的 Performance tips 明确建议:用 vllm 时"raise--max-num-seqs/--max-num-batched-tokens(或客户端侧的SURYA_INFERENCE_PARALLEL)to keep more pages in flight"。这篇文章给出两条提升路径——自管 vllm 服务器直接写参数,以及理解自动拉起服务器的默认值怎么算——并说明如何核对生效值与结果。前提是 NVIDIA GPU,以及 Docker 加 NVIDIA Container Toolkit(vllm 后端的前置要求)。
两个参数与客户端并发如何配合
调参前需要先分清两侧的职责:
- 服务端:
--max-num-seqs/--max-num-batched-tokens决定 vllm 服务器并发处理请求的上限,是吞吐的主杠杆; - 客户端:Surya 发往后端的并发请求数由
SURYA_INFERENCE_PARALLEL控制。不设置时,vllm 后端取min(服务端 max_num_seqs, 96)(见 vllm 后端 中的MAX_AUTO_PARALLEL = 96与_client_parallel())。
为什么客户端并发要封顶在 96:源码注释记录了在 B200(max_num_seqs=240)上测 layout 吞吐的结果——并发从 48 提到 96 提升 28%,从 96 提到 240 只提升 5%,因为超过约 96 个并发后 GPU 已进入 compute-bound,多出来的请求只是在排队。结论是:只堆客户端并发不会带来线性收益,服务端两个参数才是主路径,两侧要配套着看。
准备条件
- NVIDIA GPU;vllm 后端需要 Docker 和 NVIDIA Container Toolkit(README "Inference backend prerequisites")。
- 安装:
pip install surya-ocr- 精度注意:
VLLM_DTYPE默认bfloat16,需要 Ampere 及以上(compute capability >= 8.0)的显卡;在 T4 / Turing 等旧卡上 vllm 会拒绝以 bf16 启动,需把VLLM_DTYPE设为float16(settings.py 中的注释说明)。
路径 A:自管 vllm 服务器,显式指定两个参数
仓库自动拉起服务器时使用的命令在 vllm.py 中拼装。照着这条命令自己起服务器,就能把两个参数写成想要提升的值:
docker run --rm -d --name surya-vllm-self \ --runtime nvidia --gpus device=0 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ -p 8000:8000 \ --ipc=host \ vllm/vllm-openai:v0.20.1 \ --model datalab-to/surya-ocr-2 \ --no-enforce-eager \ --max-num-seqs <按显存自行提高的值> \ --dtype bfloat16 \ --max-model-len 18000 \ --max-num-batched-tokens <按显存自行提高的值> \ --gpu-memory-utilization 0.85 \ --enable-prefix-caching \ --mm-processor-kwargs '{"min_pixels": 3136, "max_pixels": 6291456}' \ --speculative-config '{"method": "mtp", "num_speculative_tokens": 2}' \ --served-model-name datalab-to/surya-ocr-2几个必须注意的点:
- 除两个待调参数外,其余取值都是 settings.py 里的默认值(
VLLM_DOCKER_IMAGE、SURYA_MODEL_CHECKPOINT、VLLM_MAX_MODEL_LEN、VLLM_GPU_MEMORY_UTILIZATION、VLLM_MTP_TOKENS等); - 两个
<...>占位符由你根据所用 GPU 的显存给出,文档没有给出"每 GB 显存对应多少"的公式,只能自行调整并观察服务器是否能正常加载; --served-model-name必须保持datalab-to/surya-ocr-2:Surya attach 时会探测服务器报告的模型名,不一致会抛SpawnError("Model mismatch",见 spawn.py);--speculative-config是 MTP 配置(VLLM_ENABLE_MTP默认开启),不用 MTP 可以删掉这一行;- 如果 8000 端口被占用,换其他端口并同步修改下面 attach 的 URL。
然后按 README "Inference Backends" 一节把 Surya 指向这个已运行的服务器:
export SURYA_INFERENCE_BACKEND=vllm export SURYA_INFERENCE_URL=http://127.0.0.1:8000/v1 # 可选:显式指定客户端并发;不设置时自动取 min(服务端 max_num_seqs, 96) # export SURYA_INFERENCE_PARALLEL=96 surya_ocr DATA_PATHDATA_PATH可以是图片、PDF 或图片/PDF 文件夹。attach 前 Surya 会先探测/health,不可达会直接报 "not reachable at /health"。
路径 B:自动拉起服务器时,默认值是怎么算出来的
不自己管服务器时,Surya 首次使用会自动docker run一个容器(名字surya-vllm-<port>),两个参数没有独立的 settings 键,而是由VLLM_GPU_TYPE按公式推算(vllm.py 中的_gpu_settings):
- 基线(24 GB 显存):
--max-num-batched-tokens 8192、--max-num-seqs 32; - 实际值 = 基线 ×(该卡 VRAM / 24):batched-tokens 向下取 2 的幂(最小 1024),max-num-seqs 向下取 8 的倍数(最小 8);
- VRAM 表覆盖
b300(270)、b200(180)、h200(141)、h100(80)、a100(80/40)、l40s(48)、a10(24)、l4(24)、5090(32)、4090(24)、3090(24)、t4(16); VLLM_GPU_TYPE默认4090。跑在 5090 上却仍设 4090 的话,拿到的就是 8192/32 这组偏小的基线值;按代码公式,VLLM_GPU_TYPE=5090会得到 8192 / 40(此为按仓库公式的计算值)。
所以自动路径下"提升"的做法是先把VLLM_GPU_TYPE设成真实卡型;如需再叠加其他 vllm 启动参数,VLLM_EXTRA_ARGS会被逐词追加到 docker 命令末尾。若VLLM_GPU_TYPE不在表内,会直接抛SpawnError并列出可用卡型。
如何验证
- 生效值:自管路径下参数就是你自己写的;自动拉起路径下,命令输出中 INFO 级别的
Spawning:日志行会打印完整的 docker run 命令,从中核对实际的--max-num-seqs/--max-num-batched-tokens。 - 功能验证:命令完成后打印
Wrote results to ...,输出目录(默认results/surya/<文件名>/)下生成results.json,其中blocks含label、html、polygon、confidence等字段,可抽样检查识别内容是否完整。 - 吞吐对比:改动前后用同一批数据各跑一次,比较处理速度。README "Throughput" 一节给出的官方基准(文档示例,不是必须复现的数值):RTX 5090(32 GB)+
vllm/vllm-openai:v0.20.1,96 DPI 全页 OCR(平均每页约 2,400 输出 token),客户端并发 128 时 5.35 页/s、12,884 tokens/s,p50 18,915 ms、p95 42,538 ms。 - 对比测试时建议加
--keep_server:默认每条命令退出即拆掉服务器,连跑多条命令会反复支付启动和 GPU 上的模型加载成本,干扰速度对比;用完按 README 停止(docker stop对应的surya-vllm-*容器,或自管容器用docker stop surya-vllm-self)。
限制与相关项
- 客户端并发的收益有拐点:B200 实测从 96 提到 240 仅 +5%,服务端参数不够时单纯调大
SURYA_INFERENCE_PARALLEL意义有限。 - MTP 也影响延迟/吞吐,可在 settings 中调整(
VLLM_ENABLE_MTP、VLLM_MTP_TOKENS)。 - DPI 对吞吐影响显著:OCR 路径默认用 192 DPI 高清输入,README 建议尝试从 192 降到 96(
SURYA_INFERENCE_PARALLEL无关,通过环境变量SURYA_IMAGE_DPI_HIGHRES覆盖),在精度与速度之间自行取舍。 - 一处文档不一致需要留意:README 的设置表把
SURYA_INFERENCE_PARALLEL默认值标为 8,而当前 settings.py 中默认是未设置(None),未设置时由 vllm 后端自动选min(服务端 max_num_seqs, 96)。两处描述不一致,以代码行为为准。 - 本卡型不在 VRAM 表内、或 attach 的服务器模型名不匹配时,启动会直接失败并给出明确报错(
Unknown VLLM_GPU_TYPE .../Model mismatch ...),按提示修正VLLM_GPU_TYPE或服务器上的--served-model-name即可。
【免费下载链接】suryaOCR, layout analysis, reading order, table recognition in 90+ languages项目地址: https://gitcode.com/GitHub_Trending/su/surya
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考