HunyuanOCR-ncnn —— int8 模型(混合精度)
本目录是 HunyuanOCR 的 int8 量化 ncnn 推理模型。采用混合精度策略,在尽量 压缩体积的同时保证识别精度稳定。
量化策略(为什么是混合的)
| 子模型 | 精度 | 大小 | 理由 |
|---|---|---|---|
vision_encoder |
fp16 | 844M | 实测 int8 在中文/复杂图上特征损坏,导致 decoder 退化(输出乱码、耗时暴涨 10×),故保持 fp16 |
embed |
int8 | 118M | 单输入词表查找,量化安全 |
lm_head |
int8 | 118M | 输出投影头,量化安全且对最终文字无影响 |
decoder / decoder_prefill / decoder_decode |
fp16(实际 fp32 计算) | 809M | LLM 输出对精度敏感,且为静态序列图、校准复杂,保持高精度 |
projector / perceptron_weights / pos_embed_32x32 |
fp16 | — | 直接复用 fp16 目录 |
实际计算路径由每一层权值的数据类型决定,运行时全局开启
use_int8_inference是安全的:int8 权值层走 int8,fp16 权值层走 fp16。
体积
总体积约 2.0 GB(相对 fp16 的 2.2 GB 再减约 200MB,主要来自 embed/lm_head
的量化;相对 fp32 的 5.9 GB 缩减约 66%)。
精度验证
- 与 fp16 / fp32 模型在英文
En.png、中文qikai.png上输出逐字节一致。 - 推理耗时与 fp16 基本持平(瓶颈在 809M 的
decoder,其走 fp32;embed/lm_head的 int8 节省有限)。
文件清单
与 ../hunyuan_ocr_ncnn_fp16/ 结构完全一致,仅 embed / lm_head 为 int8 权重:
| 文件 | 大小 | 说明 |
|---|---|---|
vision_encoder.ncnn.param / .bin |
844M | 视觉编码器(fp16,未量化) |
perceptron_weights.bin |
118M | 感知机/投影前权重(fp16) |
pos_embed_32x32.bin |
4.5M | 位置编码 |
projector.ncnn.param / .bin |
2.1M | 投影层(fp16) |
decoder.ncnn.param / .bin |
809M | 主解码网络(fp32 计算) |
decoder_prefill.ncnn.param |
75K | prefill 子图 |
decoder_decode.ncnn.param |
78K | decode 子图 |
embed.ncnn.param / .bin |
118M | 词嵌入层(int8) |
lm_head.ncnn.param / .bin |
118M | 输出头(int8) |
model.json / vocab.txt / merges.txt |
— | 配置与词表 |
image_begin.bin / image_end.bin / image_newline.bin |
4K | 图像占位符 token embedding |
运行方式
./build-cpu/hunyuan_ocr.exe \
--model assets/hunyuan_ocr_ncnn_int8 \
--image source/En.png \
--prompt "请识别图片中的文字内容" \
--quant int8 \
--threads 8 \
--max-tokens 4096
--quant int8:运行时启用 int8 计算路径(见src/quant_opt.h的g_quant_mode)。- 注意:
--quant仅影响运行时计算路径;本目录文件本身已经是混合精度权重, 即使--quant fp16也会按文件内各层实际类型计算(结果相同)。
关于「全 int8」实验版(不推荐)
转换脚本 tools/convert_int8.py 支持 INT8_VIT=1 环境变量,可进一步把
vision_encoder 也转为 int8,体积可压到约 1.6 GB。但实测在中文/复杂图上
输出乱码、耗时暴涨,仅英文简单图碰巧可用。默认已关闭,除非你明确只跑英文
且能接受风险,否则请勿使用。
INT8_VIT=1 python tools/convert_int8.py # 生成 1.6GB 全 int8(中文不可靠)
复现
# 校准数据(calib/raw 下 18 张图的真实激活张量,由运行时 dump 得到)
# 转换管线:
python tools/convert_int8.py
转换要点(已记入项目记忆,可复用):
ncnn2table的shapes=为嵌套格式:shapes=[N]解析为[[N]];read_npy按 flat float 重解释为该 shape,再靠网络内部 Reshape 修正 layout, 因此直接喂展平张量即可(vit 用(1228800,)对应cpp_pixels的in0)。ncnn2int8参数顺序:[inparam] [inbin] [outparam] [outbin] [table](table 是第 5 个)。embed层的权重量表由权重 absmax 计算(非激活),且ncnn2int8必须读到表中embed_0_param_0项,故embed也需跑ncnn2table。
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support