三公算账机器人 Fable 5.1 操刀,内存腰斩,外星科技——SimdPaddleOCR 1.4 发布!

这篇是博客园今天(2026-09-21 08:50)最热门的文章,稳坐"最多推荐"榜首,由 .NET骚操作 发布。[citation:50.4][citation:50.11][citation:50.12]


---

Fable 5.1 操刀,内存腰斩,外星科技——SimdPaddleOCR 1.4 发布!

2026 年 9 月 21 日 | 作者:.NET骚操作


---

项目定位


SimdPaddleOCR 是一个纯 C# 实现的 PP-OCRv6 推理引擎。它不需要 Paddle Inference,不需要 ONNX Runtime,也不依赖 OpenCV 原生库——从模型加载到矩阵运算,全部用 C# + SIMD 手写。核心 API 只接收 8-bit BGR/RGB 内存数据,图像解码交给上层自由选择(ImageSharp、SkiaSharp、OpenCvSharp 皆可)。[citation:50.1][citation:50.13]

做这个项目只为回答一个问题:如果以我能达到的最高标准,打造出最强的 C# PaddleOCR 引擎,它能达到什么效果?1.4 版本就是我给出的答案!


---

性能与内存:碾压式的提升

1.4.2 vs 1.3 纵向对比


测试环境:Ryzen 7 5800X(AVX2,无 AVX-512),64GB 内存,.NET 10.0.11。[citation:50.13]


| 模型 | 1.3 耗时 | 1.4.2 耗时 | 耗时比 | CER 字符错误率 | 峰值内存 |

|:----:|:--------:|:----------:|:------:|:-------------:|:--------:|

| tiny net10 AVX2 | 86.0 ms | 63.1 ms | 0.73× | 2.78% → 2.37% | 804 → 515 MB |

| tiny ns2 | 203.1 ms | 96.5 ms | 0.48× | 同上 | 766 → 522 MB |

| small net10 | 222.1 ms | 200.0 ms | 0.90× | 0.60% → 0.41% | 1195 → 674 MB |

| small ns2 | 432.1 ms | 303.0 ms | 0.70× | 同上 | 1277 → 684 MB |

| medium net10 | 628 ms | 585 ms | 0.93× | 0.67% → 0.14% | 2489 → 1206 MB |

| medium ns2 | 1606 ms | 874 ms | 0.54× | 同上 | 2663 → 1218 MB |


亮点:

tiny 模型 ns2 路径耗时 腰斩(203→96 ms),内存从 766 MB 降至 522 MB

medium 峰值内存从 2.5 GB → 1.2 GB,直接腰斩

工作集增量(Δ WS)在 tiny 场景下从 389 MB → 113 MB

对比 C 语言引擎


拉来 C 版引擎(lw.PPOCR.C)同台对比:[citation:50.13]


| 模型 | SimdPaddleOCR 1.4.2 | C 引擎 | 优势 |

|:----:|:-------------------:|:------:|:----:|

| tiny 耗时 | 63.1 ms | 201.9 ms | 3.2× 吞吐量碾压 |

| medium CER | 0.14% | 0.24% | 准确率反超 C 引擎 |

| 峰值内存 (tiny) | 515 MB | 541 MB | 更低 |

纯 C# 写的 OCR 引擎,在吞吐量和准确率上双双反超纯 C 版——这在 .NET 生态里几乎是"不可能"的事。

对比 PaddleOCRSharp


| 模型 | SimdPaddleOCR | PaddleOCRSharp | 倍数 |

|:----:|:-------------:|:--------------:|:----:|

| tiny 耗时 | 66.5 ms | 270.6 ms | 4.07× |

| small 耗时 | 195.4 ms | 505.9 ms | 2.59× |

| medium 耗时 | 585.9 ms | 1284.0 ms | 2.19× |

| 峰值内存 (tiny) | 515 MB | 993 MB | 约一半 |


---

核心进化揭秘

内存管理大瘦身


三项关键改进:移除输入 LayoutConvert 阶段的第二份缓冲 → NHWC 工作集引入别名机制 → F32 常量池不再使用"原始字节 + 解码拷贝"的笨重模式。峰值内存直接腰斩。[citation:50.13]

CLS 正确率两连跳:从 98% 干到 100%


1.3 版本的分类型(CLS)预处理使用了 PaddleX 的拉伸逻辑(强行拉成 160×80,使用 ImageNet RGB),导致细长拉丁文字行被极度拉伸后频繁误判 0 度与 180 度。


1.4 先改回 PaddleOCR 原生的 ClsResizeImg——高度固定 80,宽度按比例拉伸(封顶 160),右侧用 -1 pad。这一步让 medium 的 CER 从 0.67% 降到 0.26%。


1.4.2 更精妙——对于长行,将原图宽度按高度的 4 倍裁剪,保留左侧部分再拉伸。不引入额外内存分配和性能开销,转换一气呵成。最终 CLS 正确率达到 1022/1022(100%)。[citation:50.13]

图级 NHWC 全路径制霸


1.3 只有 AVX2+FMA 吃到了图级 NHWC(通道最后布局)的红利。1.4 将这一优势扩充到了所有路径:[citation:50.13]


| 路径 | 改进 | 效果 |

|:----:|:----:|:----:|

| netstandard2.0 (Vector) | NCHW → NHWC | 性能大幅提升 |

| x64 scalar | 软件模拟 → 专用 NHWC 标量 tile | 改善 |

| net10 AdvSIMD (ARM) | NCHW → 手写 NHWC NEON tile | CI 上 tiny 241→180ms (0.75×) |

| avx512 | NCHW → 手写 NHWC AVX512 tile | 社区反馈性能提升 45% |

原生支持 RGB/RGBA,告别 BGR 转换


1.4 的 Run 方法可以直接接收 Rgb24、Bgra32、Rgba32 格式,通道交换在 resize 或 warp 时就地完成,不需要额外分配内存。不再需要先转 BGR 再传 OCR。[citation:50.13]


// ImageSharp + Rgba32 直接传入

using Image<Rgba32> image = await Image.LoadAsync<Rgba32>("sample.jpg");

image.DangerousTryGetSinglePixelMemory(out Memory<Rgba32> memory);

PaddleOcrResult result = ocr.Run(

 MemoryMarshal.AsBytes(memory.Span),

 image.Width, image.Height,

 format: ImagePixelFormat.Rgba32 // 原生支持!

);


---

数据集开源,欢迎打擂


为了方便社区做引擎对比,作者将测试集开源:[citation:50.13]

HuggingFace: simdpaddleocr-dataset-v1

ModelScope: simdpaddleocr-dataset-v1

Apache-2.0 协议,100 张 JPEG,约 26456 个中英文混排字符,20% 竖排,25% 180 度倒转


三项官方指标:

Exact lines:预测与真值无序字符串全匹配

Exact CLS:DET 纠偏后的 0/180 分类正确率

CER:非 Exact 行取最小编辑距离除以总字符数


---

一句话总结

SimdPaddleOCR 1.4 用纯 C# 写出了一个让 C 语言引擎都汗颜的 OCR 引擎——吞吐量 3.2 倍于 C 版、峰值内存腰斩、CLS 正确率 100%。 作者借 Fable 5.1 之力重构了全链路的 SIMD 算子(NHWC 铺到所有 CPU 路径),配合精细到逐字节的内存管理和 CLS 预处理优化,硬生生在托管环境中榨出了 C 级乃至超越 C 的性能。GitHub 已开源,Apache-2.0 协议,NuGet 包名 Sdcb.SimdPaddleOCR[citation:50.13]。


0 评论

发表评论