Unlimited-OCR 部署运行(13/13):长文档验证 + 端口冲突坑 + 完整使用指南

Unlimited-OCR 部署运行(13/13):长文档验证 + 端口冲突坑 + 完整使用指南

封面

这是部署运行篇的终篇,也是整个 14 篇系列的收尾。它做三件事:(1)long-horizon-ocr.gif 验证长文档 OCR 在修复后依然正确;(2) 记下两个 Windows 特有的运维坑(本机网络环境变量干扰 health check、端口 10000 被遗留服务占用);(3) 给你一份完整使用指南——怎么用 OpenAI 兼容 API 真正调用这个服务。如果你只想知道"我怎么用",直接跳到第四节。


一、长文档 OCR 验证(修复在长输入上依旧成立)

assets/long-horizon-ocr.gif 是 280 帧、1916×954 的长文档动画。验证脚本 test_long_horizon.py 用两种输入测 第 10 篇 的乱码修复在长文档上是否仍成立:

  • (A) 单帧(frame 0)elapsed=54.5s, out_len=2610,头部 header [8,20,79,40]Unlimited-OCR header... 连贯。
  • (B) 12 帧均匀采样拼接长图(resize 宽 1280 → 1280×7644,模拟长文档):elapsed=313.7s, out_len=42571,头部 header [0,0,999,11]Unit 1 Unit 2 Unit 3... 连贯长文档,无乱码 / 崩溃。

两者均输出结构化 OCR,证明第 10 篇的"3 文件还原"修复在长文档 / 多区域输入上依旧成立。

gundam 图像模式:base_size=1024, image_size=640, crop=True;处理器用 PIL 单图解码(GIF 只取 frame 0),多图仅 tiny/small/base 支持,模型本身不接受 GIF 多帧。所以长文档建议用"多帧拼接成一张高图"的方式,而不是把 GIF 多帧当多图。


二、运维坑①:本机网络环境变量干扰 health check(HTTP 000)

技术图1(流程/架构)

本机若设了 HTTPS_PROXY 指向某个本地转发端口,urllib / curl 会把 127.0.0.1:10000 也路由到该端口 → health 检查返回 HTTP 000(但 raw socket 能连、服务实际在跑)。排查时极易误判"服务没起来"。

解决:所有请求脚本开头必须清理该网络环境变量

import os
os.environ.pop("HTTPS_PROXY", None)
os.environ.pop("HTTP_PROXY", None)
os.environ.pop("ALL_PROXY", None)
os.environ["no_proxy"] = "127.0.0.1,localhost"

test_long_horizon.py / smoke_moe.py 已内置这段。哪怕你用 curl 手动测,也要先 set HTTPS_PROXY= 清空。


三、运维坑②:端口 10000 被遗留服务占用

技术图2(对比/要点)

多次启动会出现 [Errno 10048] address already in use——旧 worker 由 base conda python 启动且会重生,占着 10000。启动前先清理:

:: 定位占用 10000 的 PID
netstat -ano | findstr ":10000 " | findstr "LISTENING"
:: 杀掉(/T 连子进程一起杀)
taskkill /F /T /PID <占用PID>

infer.pystart_server() 已内置这段:启动时自动 netstat 找占用 PID 并 taskkill,再启动单一干净服务(详见 第 09 篇)。

冷服务首请求极慢:triton 对所有 kernel 做 JIT 编译,首请求可能 >300s。客户端超时要放宽(如 600s);服务不是卡死,是在编译 + 生成。热身后的请求回到 ~50–60s 级。


四、使用指南:怎么用这个 OCR 服务

技术图3(速查/清单)

服务按 第 09 篇 启动后,对外暴露 OpenAI 兼容的 /v1/chat/completions 接口(端口 10000)。你不需要懂 sglang 内部,像调 GPT 一样调它即可。

4.1 最小 Python 调用(单图 OCR)

import os, base64, json, urllib.request

# 关键:清掉会把 127.0.0.1 路由到本地转发端口的环境变量
os.environ.pop("HTTPS_PROXY", None); os.environ.pop("HTTP_PROXY", None); os.environ.pop("ALL_PROXY", None)
os.environ["no_proxy"] = "127.0.0.1,localhost"

def ocr(image_path: str, prompt: str = "document parsing.") -> str:
    with open(image_path, "rb") as f:
        b64 = base64.b64encode(f.read()).decode()
    payload = {
        "model": "Unlimited-OCR",
        "messages": [
            {"role": "user", "content": [
                {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{b64}"}},
                {"type": "text", "text": prompt},
            ]}
        ],
        "temperature": 0,
        "stream": False,
        "images_config": {"image_mode": "gundam"},   # Unlimited-OCR 专用图模式
    }
    req = urllib.request.Request(
        "http://127.0.0.1:10000/v1/chat/completions",
        data=json.dumps(payload).encode(),
        headers={"Content-Type": "application/json"},
    )
    with urllib.request.urlopen(req, timeout=600) as r:   # 首请求放宽到 600s
        return json.load(r)["choices"][0]["message"]["content"]

print(ocr("assets/baidu.png"))

输出示例:<|det|>title [14, 0, 999, 999]<|/det|>Baidu 百度

4.2 curl 调用

curl http://127.0.0.1:10000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Unlimited-OCR",
    "messages": [{"role":"user","content":[
      {"type":"image_url","image_url":{"url":"data:image/png;base64,'"$B64"'"}},
      {"type":"text","text":"document parsing."}
    ]}],
    "temperature": 0, "stream": false,
    "images_config": {"image_mode": "gundam"}
  }'

4.3 用项目自带脚本

# 单图
.venv\Scripts\python.exe infer.py --image_path "你的图片.jpg"
# 文件夹批量
.venv\Scripts\python.exe infer.py --image_dir "你的图片文件夹"
# 流式推理测试
.venv\Scripts\python.exe test_inference.py assets/baidu.png "document parsing."

infer.py 会自动:复用已有服务 / 清理占用端口 / 启动服务 / 发请求 / 停止服务。

4.4 长文档 / 多页建议

  • 把多页或长图拼接成一张高图(宽统一 resize 到 ~1280,高度按需),用 gundam 模式一次送进去(见第一节验证)。
  • --context-length 32768 已为长文档留足上下文;更长的文档可调大,但注意 --mem-fraction-static 要相应留足 KV cache。
  • 首请求慢属正常,把客户端超时设 600s,之后请求会快很多。

五、系列结语

14 篇写到这,整件事讲完了:

  • 编译移植篇(01–08):一个被广泛认为"Windows 装不了、只能上 WSL/Docker"的高性能推理框架,我们拒绝逃生,在原生 Windows 上从源码把它编译并跑通——横跨 FlashInfer 前置编译、环境、GCC→MSVC 方言、MSVC 语义严格性、架构裁剪、链接收尾,以及支撑这一切不散架的工程方法论。
  • 部署运行篇(09–13):编出来之后怎么真正跑起来——正确启动、两个经典排障(乱码根因 / 环境变量块崩溃)、MoE 性能调优、长文档验证,以及本篇的使用指南。

如果这个系列只留下一句话,我希望是:“官方没有提供”,从来不等于"做不到"。 缺的往往不是可能性,而是有没有人愿意、并且有方法,把那条没人走过的路,一步一个脚印、留着可复现的记录,走到底。

愿它对你自己的那场硬仗,有用。


系列导航(全 14 篇)

编译移植篇(怎么把 sglang 从源码编出来)

部署运行篇(怎么跑起来并排障)


参考资料与延伸阅读

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值