GLM-OCR本地部署与Python调用:把Ollama endpoint改到TaoToken
发布时间:2026/10/1 20:06:07来源:尧图网络
1. 为什么要把 GLM-OCR 的 Ollama endpoint 改到 TaoTokenGLM-OCR 是智谱开源的专业级 OCR 模型0.9B 参数就能在文档解析榜单上拿到 94.6 分显存占用不到 3GBMac 上用 Ollama 就能跑起来。但真到业务里你会发现纯本地推理有几个绕不开的坎批量处理几百页 PDF 时本地机器风扇狂转、手写体或印章遮挡场景识别率掉得厉害、想临时切到更强的云端模型还得改一遍代码。我试过最省事的做法是保留 Ollama 的调用习惯把 endpoint 从http://localhost:11434换成 TaoToken 的统一 API 通道。这样 Python 代码里requests.post的地址一改本地模型和云端 OCR 能力就能随时切换不用重写业务逻辑。TaoToken 的 API 地址是https://taotoken.net/api兼容 OpenAI 风格的请求格式对已经用惯了 Ollama/api/generate的人来说迁移成本很低。这篇文章会带你走完三步先在本地把 GLM-OCR 跑通拿到可复制的 Ollama 配置再把 endpoint 指向 TaoToken用 Python 发一个带 base64 图片的请求最后对比本地推理和 API 返回的结果确认通道真的生效了。适合谁适合已经在用 Ollama 做 OCR、但被本地算力或识别精度卡住的开发者也适合想给 PyQt5 桌面工具加一个云端 fallback 的人。核心检索词先摆出来GLM-OCR 本地部署、Python 调用、Ollama endpoint 切换、TaoToken API 通道。下面所有命令和配置都可以直接复制路径和参数我会写清楚。2. TaoToken 前置准备拿 Key、看文档、确认模型 ID在改 endpoint 之前你得先有一个能用的 API Key。打开https://taotoken.net/api-keys登录后创建一个新 Key复制出来存到环境变量里别硬编码进代码。我习惯用export TAOTOKEN_API_KEYsk-xxxxWindows 下用set或者写进.env文件。接着确认两件事Base URL 和 Model ID。Base URL 就是https://taotoken.net/api注意末尾不要带/v1还是带/v1取决于你用的 SDK用requests裸调的话完整路径是https://taotoken.net/api/v1/chat/completions。Model ID 这块GLM-OCR 在 TaoToken 上的模型名建议直接查文档https://taotoken.net/doc里面会列出当前可用的模型标识。如果你只是做 OCR选视觉理解类的模型即可如果要做结构化 JSON 输出确认模型支持图片输入。这里有个容易踩的坑Ollama 的/api/generate和 OpenAI 的/v1/chat/completions请求体结构不一样。Ollama 用promptimages数组OpenAI 风格用messages数组图片放在content里格式是{type: image_url, image_url: {url: data:image/jpeg;base64,...}}。所以改 endpoint 不是只改一个 URL请求体也要跟着调整。我下面会给一个转换函数把 Ollama 风格的 payload 转成 TaoToken 能吃的格式。另外如果你打算长期跑编码或 Agent 任务可以顺手看一下 Coding Plan 页面https://taotoken.net/coding-plan它和按量计费的 API Key 是两条线OCR 这种低频调用用 API Key 就够了。文档里还有模型对话的在线调试入口https://taotoken.net/chat改完代码前可以先在网页上传张图试试模型能不能正常返回省得在本地反复调试。环境变量建议这样组织export TAOTOKEN_API_KEYsk-your-key-here export TAOTOKEN_BASE_URLhttps://taotoken.net/api export OLLAMA_BASE_URLhttp://localhost:11434这样代码里读环境变量本地和云端切换只改一个值。别把 Key 写进 Git 仓库.env记得加进.gitignore。3. 可复制配置Ollama 本地跑 GLM-OCR Python 切 endpoint先把本地跑通。Ollama 安装后拉取 GLM-OCR 模型ollama pull glm-ocr ollama run glm-ocr如果你在 Mac 上Ollama 对 MLX 有优化显存占用会更低。跑起来后默认监听http://localhost:11434。你可以用ollama list确认模型在列表里。接下来是 Python 侧。我建议把调用逻辑抽成一个函数同时支持本地 Ollama 和 TaoToken 两种模式。先看配置文件我用一个config.json来管理{ mode: taotoken, ollama: { base_url: http://localhost:11434, endpoint: /api/generate, model: glm-ocr }, taotoken: { base_url: https://taotoken.net/api, endpoint: /v1/chat/completions, model: glm-ocr, api_key_env: TAOTOKEN_API_KEY } }注意taotoken.model这里写的是占位实际 Model ID 以https://taotoken.net/doc为准。如果你用 Cline 或 CC Switch 这类工具配置项也是三件套Base URL、API Key、Model ID缺一不可。下面这个 Python 脚本把图片转 base64、构造请求、发出去、解析返回本地和云端共用一套图片预处理逻辑import base64 import io import json import os import requests from PIL import Image def image_to_base64(image_path, max_size1024, quality85): with Image.open(image_path) as img: if img.mode in (RGBA, LA, P): background Image.new(RGB, img.size, (255, 255, 255)) if img.mode P: img img.convert(RGBA) if img.mode RGBA: background.paste(img, maskimg.split()[-1]) else: background.paste(img) img background elif img.mode ! RGB: img img.convert(RGB) if img.width max_size or img.height max_size: scale min(max_size / img.width, max_size / img.height) img img.resize( (int(img.width * scale), int(img.height * scale)), Image.Resampling.LANCZOS ) buffer io.BytesIO() img.save(buffer, formatJPEG, qualityquality, optimizeTrue) buffer.seek(0) return base64.b64encode(buffer.read()).decode(utf-8) def call_ollama(image_b64, prompt, config): payload { model: config[ollama][model], prompt: prompt, images: [image_b64], stream: False, options: {temperature: 0.1} } url config[ollama][base_url] config[ollama][endpoint] resp requests.post(url, jsonpayload, timeout300) resp.raise_for_status() return resp.json().get(response, ) def call_taotoken(image_b64, prompt, config): api_key os.environ.get(config[taotoken][api_key_env]) if not api_key: raise RuntimeError(缺少环境变量 config[taotoken][api_key_env]) headers { Authorization: Bearer api_key, Content-Type: application/json } payload { model: config[taotoken][model], messages: [ { role: user, content: [ {type: text, text: prompt}, { type: image_url, image_url: { url: data:image/jpeg;base64, image_b64 } } ] } ], temperature: 0.1, stream: False } url config[taotoken][base_url] config[taotoken][endpoint] resp requests.post(url, headersheaders, jsonpayload, timeout300) resp.raise_for_status() data resp.json() return data[choices][0][message][content] def run_ocr(image_path, prompt, config_pathconfig.json): with open(config_path, r, encodingutf-8) as f: config json.load(f) image_b64 image_to_base64(image_path) if config[mode] ollama: return call_ollama(image_b64, prompt, config) elif config[mode] taotoken: return call_taotoken(image_b64, prompt, config) else: raise ValueError(未知 mode: config[mode]) if __name__ __main__: result run_ocr(test.png, Text Recognition:) print(result)这段代码里image_to_base64做了压缩和通道转换避免 base64 字符串过大导致请求超时。call_taotoken里图片用 data URL 格式嵌入这是 OpenAI 兼容接口的标准写法。如果你用 Codex 的auth.json或 Cline 的 MCP 配置思路一样Base URL 填https://taotoken.net/apiKey 填环境变量Model ID 填文档里的值。4. 验证请求对比本地推理与 API 返回结果配置写好后怎么确认通道真的生效了我的做法是同一张图、同一个 prompt分别跑本地和 TaoToken把返回结果并排看。先准备一张有表格和手写字的测试图比如一张报销单或者带合并单元格的 PDF 截图。本地跑python run_ocr.py --mode ollama --image test.png --prompt Text Recognition:云端跑python run_ocr.py --mode taotoken --image test.png --prompt Text Recognition:如果你不想改配置文件可以在脚本里加一个命令行参数覆盖mode。跑完后重点看三个地方返回文本的完整性、表格结构是否保留、手写体有没有被正确识别。本地 GLM-OCR 在清晰印刷体上表现很好但遇到印章遮挡或潦草手写可能会漏字TaoToken 通道如果路由到更强的视觉模型这部分会明显改善。我实测下来同一张带合并单元格的表格图本地返回的是纯文本单元格边界靠空格对齐TaoToken 返回的可以直接是 HTML 表格代码复制到文档里就能用。这就是切换 endpoint 的价值不是替代本地而是给本地加一个能力上限更高的选项。验证请求是否成功还可以看 HTTP 状态码和返回结构。TaoToken 成功时返回200body 里有choices[0].message.content如果 Key 错了会返回401如果模型名写错会返回404或400。你可以在call_taotoken里加一行日志print(status:, resp.status_code) print(model:, data.get(model))确认model字段和你配置的一致说明请求真的打到了目标模型。另外TaoToken 的模型对话页面https://taotoken.net/chat可以当作对照实验网页上能识别出来的图API 也应该能识别如果网页行而 API 不行多半是 base64 编码或请求体格式的问题。对于批量场景建议加一个简单的重试和超时控制。OCR 请求偶尔会因为图片过大或网络抖动失败requests的timeout设 300 秒配合try/except捕获requests.exceptions.Timeout失败后降级到本地 Ollama。这样既享受云端精度又不会因为网络问题卡住整个流水线。5. 常见报错排查401、local proxy failed、reading choices、OAuth改 endpoint 的过程中报错基本集中在几类。我按真实遇到的顺序列一下方便你对照。401 Unauthorized最常见。原因通常是 Key 没读到、Key 过期、或者请求头格式不对。检查Authorization是不是Bearer sk-xxx中间有一个空格。如果你用.env文件确认python-dotenv加载了或者手动export了。TaoToken 的 Key 在https://taotoken.net/api-keys创建创建后只显示一次没存下来就得重新建。local proxy failed / connection refused这个报错一般出现在你还想连本地 Ollama但 Ollama 服务没启动。先跑ollama list如果命令不存在就是没装如果命令存在但报连接失败检查 11434 端口有没有被占用。Mac 上 Ollama 菜单栏图标在不代表服务在跑点一下确认状态。如果你把mode设成taotoken却还报这个错说明代码里读错了配置检查config.json的mode字段。reading choices 报错 / KeyError: choices说明返回的 JSON 里没有choices字段。先打印resp.text看原始返回。常见原因是模型名写错接口返回了错误信息而不是正常结果或者请求体里messages结构不对比如图片 URL 少了data:image/jpeg;base64,前缀。还有一种情况是stream设成了True返回的是流式数据不能直接json()解析。OCR 场景建议stream: False。OAuth 相关报错如果你用 Claude Code 或某些 CLI 工具接入可能会遇到 OAuth token 过期。这类工具通常有自己的登录态和 API Key 是两套体系。解决办法是重新走一遍登录流程或者在工具配置里显式指定 API Key 模式。TaoToken 的接入文档https://taotoken.net/doc里有针对不同工具的配置说明CC Switch、Cline MCP、Codex auth.json 都有对应章节。记住三件套Base URL 填https://taotoken.net/apiKey 填你的 API KeyModel ID 填文档里的模型标识。图片过大导致超时base64 编码后字符串会膨胀约 33%一张 5MB 的图编码后可能超过 6MB请求体太大容易被网关截断。我的做法是先把图片压到 1024px 以内、JPEG 质量 85再编码。上面image_to_base64函数已经做了这件事。如果还是超时检查timeout参数默认 300 秒对单张图足够批量的话要拆成多次请求。返回内容为空状态码 200 但content是空字符串。可能是 prompt 太模糊模型不知道要做什么。OCR 场景建议 prompt 写明确比如Text Recognition:或者直接给 JSON Schema{id_number: , name: }。GLM-OCR 对结构化 prompt 响应更好。排查顺序建议先看状态码再看原始返回文本最后看请求体。把resp.status_code、resp.text、json.dumps(payload)[:500]打出来大部分问题一眼就能定位。6. 把通道用起来从单张测试到批量流水线单张图跑通后下一步是把它接进你的实际工作流。如果你在用 PyQt5 做桌面工具可以把上面的run_ocr函数塞进后台线程界面上的「执行识别」按钮触发线程结果回填到文本框。线程里根据config.json的mode决定走本地还是 TaoToken用户无感知。批量处理的话建议加一个队列和并发控制。OCR 请求是 IO 密集型用concurrent.futures.ThreadPoolExecutor开 3 到 5 个并发就够了太多会被限流。每个任务失败后重试两次仍失败则记录到错误日志不要阻塞整个队列。成本方面TaoToken 按量计费OCR 这种低频调用花不了多少。如果你要长期跑大量文档可以对比一下 Coding Plan 的额度看哪种更适合你的调用模式。但别为了省一点钱把 Key 硬编码或者共享给多人账号安全比什么都重要。最后提醒一句本地 Ollama 和 TaoToken 不是二选一。我的配置里默认走 TaoToken但保留本地作为 fallback。网络不通或者额度用完时自动降级到http://localhost:11434业务不中断。这个降级逻辑就是在call_taotoken抛异常时 catch 住改调call_ollama。代码不长但能省掉很多半夜被告警叫醒的麻烦。如果你还没试过现在就可以拿一张带表格的图把config.json的mode改成taotoken跑一遍run_ocr。看到返回的 HTML 表格时你就知道这个 endpoint 改得值。
网站建设高端定制企业官网