Nougat(Neural Optical Understanding for Academic Documents)出自 Meta AI 的论文 arXiv:2308.13418,作者是 Lukas Blecher、Guillem Cucurull、Thomas Scialom 和 Robert Stojnic。它不走传统 OCR 的「版面检测 + 文本行识别」路线,而是 Donut 式的端到端视觉编解码器:Swin Transformer 把整页 896×672 的页面图像编码成视觉 token,mBART 解码器再自回归地吐出 Mathpix Markdown(.mmd 文件)。行间公式直接是 LaTeX,表格直接是 tabular 环境 —— 这是它在一堆更新的模型之间至今仍被大量论文流水线保留的核心理由。
两个官方权重都小得不像 2026 年的模型。facebook/nougat-base 是 0.3B 参数,mBART 解码器 10 层、d_model 1024、单页上下文 4096 token,safetensors 落盘 1.4GB;facebook/nougat-small 是 0.2B,解码器只有 4 层、单页 3584 token,落盘 990MB。仓库代码在 nougat/utils/device.py 里默认就把模型转成 bfloat16,所以 base 的权重驻留只有约 0.7GB —— 显存压力几乎全部来自 batch 里那一叠页面图像的激活,而不是权重本身。这也意味着你完全不需要为它去租大卡。
还要说清楚现状:nougat-ocr 在 PyPI 上停在 0.1.17,发布日期 2023-10-04;GitHub 主干最后一次提交是 2025-02-21 的一次依赖替换,而且那次修复从未发过新的 PyPI 包。Marker 今天的对比基线里已经换成 Chandra 2、Gemini Flash 3.5、MinerU、docling 这一批,Nougat 不在名单中;olmOCR v0.4.0 直接换成了 7B 的 olmOCR-2,README 写明至少要 12GB 显存。但如果你的语料就是 arXiv/PMC 风格的英文论文、要的就是公式和表格的 LaTeX,0.3B 的 Nougat 依然是显存占用最低、单卡就能拉满吞吐的那一档。
01 —
版本与权重:装哪个、下多大
两个官方 checkpoint、一个社区公式微调,外加你必须知道的发行版差异。
| 版本 | 参数量 | 显存 | 上下文 | 说明 |
|---|---|---|---|---|
| facebook/nougat-base(0.1.0-base) | 0.3B | fp32 权重 1.4GB / bf16 约 0.7GB | 单页 4096 token | 精度档默认选它。mBART 解码器 10 层、d_model 1024、词表 50000,长版面和密集参考文献页比 small 稳得多。HF 上这份是 GitHub release 里 0.1.0-base 的 transformers 转换版。 |
| facebook/nougat-small(0.1.0-small) | 0.2B | fp32 权重 990MB / bf16 约 0.5GB | 单页 3584 token | 解码器只有 4 层,速度更快、显存更省,代价是长公式和跨栏排版更容易丢内容。HF 月下载量约 2.77 万次,实际用的人比 base 还多。 |
| Norm/nougat-latex-base | 0.3B(从 base 微调) | 与 base 同档,bf16 约 0.7GB | 单条公式,不是整页 | 社区在 im2latex-100k 上从 facebook/nougat-base 微调出的公式专用版,只做「公式图 → LaTeX」,用自适应 padding 避免缩放把上下标糊掉。授权是 Apache-2.0,比官方权重宽松。 |
| nougat-ocr 0.1.17(PyPI 发行版) | 复用上述权重 | 不额外占显存 | 沿用所选权重 | 提供 nougat 命令行和 nougat_api 服务,2023-10-04 之后再没发过新版。依赖里 timm 被硬钉在 0.5.4,transformers 只写了 >=4.25.1、没有上界,这是今天装不上的主因。 |
| GitHub 主干(2025-02-21) | 与 0.1.17 同权重 | 同上 | 同上 | 最后一次提交把 python-Levenshtein 换成了 rapidfuzz(issue #255),但这个修复从未发到 PyPI。编译不过 Levenshtein 的机器只能从 git 直接装才拿得到。 |
02 —
显卡怎么选:0.3B 的模型别去租 H100
官方 CLI 自己会按显存推 batch,公式就写在 nougat/utils/device.py:int(总显存字节 / 1024 / 1024 / 1000 × 0.3)。
单篇到几十篇英文论文转 .mmd,走默认 bf16 路径
RTX 3090 24GB$0.193/卡·时
整个队列里最便宜的原生支持 bfloat16 的卡(Ampere 起才有),官方启发式在 24GB 上算出 batch 7,权重只吃 0.7GB,剩下全是页面激活的余量。
上千页批量转换,想把墙上时间压下来
RTX 4090 24GB$0.540/卡·时
同样是 batch 7,但 Ada 的解码吞吐明显高于 3090。Nougat 是逐页自回归、瓶颈在解码器而不是显存,页数一多总账反而更划算。
万页级流水线,nougat_api 常驻多并发
RTX A6000 48GB$0.817/卡·时
启发式在 48GB 上直接给到 batch 14,一张卡就能喂饱 8503 端口的批处理队列,不用拆成多进程互相抢显存。
预算压到最低,或流程被迫走 fp32
Tesla V100 32GB$0.188/卡·时
全队列最低价。Volta 没有原生 bf16,必须加 --full-precision 走 fp32,1.4GB 权重在 32GB 上依然宽裕 —— 代价是速度和 [MISSING_PAGE] 误判风险都要自己扛。
03 —
把 Nougat 跑起来:四步,含依赖坑
从开机到 8503 端口吐出 .mmd,下面的命令都能直接粘。
- 01
开一台支持 bf16 的卡,装 nougat-ocr 并锁住 transformers
在 NexGPU 控制台选 PyTorch 预置镜像,SSH 进去。别直接裸装 nougat-ocr —— 它的 transformers 依赖没有上界,pip 会给你解析到 transformers 5.x,而 0.1.17 的代码是 4.x 时代写的。timm 同时被硬钉在 0.5.4,务必用独立虚拟环境。如果机器上编译不过 python-Levenshtein,改成从 git 主干装:pip install "git+https://github.com/facebookresearch/nougat",那边已经换成 rapidfuzz。
pip install "nougat-ocr==0.1.17" "transformers<5" "timm==0.5.4" - 02
先用前 20 页量一遍速度,再决定批量策略
首次运行会自动从 GitHub release 拉 0.1.0-base 权重。-b 显式指定 batch,不给的话 CLI 按显存自己算:16GB 得 4、24GB 得 7、32GB 得 9、48GB 得 14、80GB 得 24。用 -p 只跑前 20 页把吞吐量出来,别一上来就整本 —— Nougat 逐页解码,页面越密集越慢,通用的「页/秒」数字对你没有参考价值。
nougat paper.pdf -o ./out -m 0.1.0-base -b 7 -p 1-20 - 03
起 HTTP 服务,把批量转换接进自己的流水线
nougat_api 会在 127.0.0.1:8503 起一个 FastAPI 服务,multipart POST 一个 PDF 上去就回 Markdown,start 和 stop 两个查询参数限定页码范围。它默认只监听本地,要从外部调用就走 SSH 隧道,别把 8503 直接暴露到公网。批量任务加 --recompute 可以丢弃上一轮的中间结果重跑。
nougat_api & curl -X POST -F "[email protected]" "http://127.0.0.1:8503/predict/?start=1&stop=20" - 04
或者绕开发行版,直接走 transformers 原生路径
如果你已经在 transformers 5.x 上,不必硬降级:Nougat 在 transformers 里有一等公民实现,NougatProcessor 加 AutoModelForImageTextToText 就能跑。注意 pipeline("image-to-text") 在 v5 里已经移除,必须直接加载模型。解码完记得调 processor.post_process_generation(),它会顺手修表格格式并调用 remove_hallucinated_references 清掉幻觉引用。
model = AutoModelForImageTextToText.from_pretrained("facebook/nougat-base", dtype="bfloat16", device_map="auto")
一笔真实的账:把 2,000 页论文转完要多少钱
先说句诚实话:Nougat 是逐页自回归解码、每页最多吐 4096 token,吞吐完全取决于版面密度,任何一个通用的「X 页/秒」都不可信 —— 用 -p 1-20 在你自己的样本上量一遍才算数。下面按墙上时间算账。假设你量出来在 RTX 3090 24GB($0.193/卡·时)上跑完 2,000 页要 4 小时:4 × $0.193 = $0.772。换 RTX 4090 24GB($0.540/卡·时),batch 同样是 7 但解码更快,假设只要 2 小时:2 × $0.540 = $1.08 —— 多花 $0.31,省下 2 小时墙上时间。要是把 RTX A6000 48GB($0.817/卡·时)的 batch 14 吃满,同一批活按 1.5 小时算就是 1.5 × $0.817 = $1.23。三条路的差价还不到一杯咖啡,所以选卡真正该看的是你等不等得起。存储另算:base 的 fp32 权重 1.4GB、small 990MB,加上 PDF 原件和 pypdfium2 的渲染缓存,开一个 20GB 卷是 20 × $0.414 = $8.28/月。输出的 .mmd 是纯文本,2,000 页也就几 MB,按 $0.0081/GB 的出网中位价基本可以忽略。计费按秒计量、按小时计价,没有起租量也没有开通费;实例一停计算费用立刻停止,存储费用则会一直算到你把卷销毁为止。
04 —
