技术 2026-10-03 5 min 阅读

我们能把 CPU 的极限推到多远?

不要满足于臃肿的框架和对 GPU 的依赖。探索 pdefa——一个从零构建的推理引擎,可直接在 CPU 上运行深度学习模型。

Hasan Arda Acar
Hasan Arda Acar Founder of pdfduty.com
我们能把 CPU 的极限推到多远?

我们能把 CPU 的极限推到多远?

多年来,对于“运行深度学习”的答案一直是一样的:买一块 GPU。但这个答案忽略了一个根本问题——我们实际使用了多少硬件,又有多少浪费在了框架开销上?

为了摆脱外部库的臃肿软件,以最高效率充分发挥硬件的全部能力,我分享我的工程历程和开源项目:pdefa (hasnard/pdefa)。

什么是 pdefa?

pdefa 是我使用 C++20 和 AVX2 SIMD 架构从零开始构建的深度学习推理引擎,可直接在 CPU 上运行模型——无需 GPU,无需重型运行时,无需在运行单个推理之前解开依赖树。

我的核心动机很简单:体验如何以绝对效率管理系统资源,并将这种超轻量级架构以 AGPL-3.0 许可证带入生态系统,毫不妥协地忠于真正的开源哲学。

为什么要费心使用 CPU 推理?

因为大多数实际部署并没有专用 GPU 的奢侈。边缘设备、嵌入式系统、CI 流水线、小型 VPS 实例、工厂机器和学术集群都运行在 CPU 上。在这些环境中,每一兆字节的框架开销和每一个不必要的依赖都是成本——内存、启动时间、部署复杂性。

一个 300 MB 的框架,引入十几个共享库,并不是“免费”的。这是你在每次部署时都要缴纳的税。

关键技术亮点:

- 超轻量级尺寸
编译后的原生二进制文件只有 320 KB。没有数兆字节的臃肿,没有必须先安装的运行时——只有运行推理所需的东西。

- 零外部依赖
Python 接口仅依赖内置的 ctypes 模块。无需 pip install,没有版本冲突,没有虚拟环境体操。

- 硬件优化
使用 AVX2 指令集最大化向量化处理能力,并直接控制线程数——因此你可以根据你运行的 CPU 精确调整。

- 广泛的架构支持
开箱即用,能够运行 YOLO(v8 到 v12)、ResNet、MobileNet、EfficientNet 和 DeepLabV3 架构。

- 内置图像处理
拥有自己的 PNG/JPEG 加载器和内置的 YOLO 后处理算法,完全绕过了对 OpenCV 等重型库的需求。

- 灵活的转换工作流
将现有的 PyTorch 模型导出为标准 ONNX 格式,然后使用引擎的内置转换器将它们无缝转换为 pdefa 自定义的低延迟 .engine 格式。

Ekran görüntüsü 2026-10-03 094610

output_bus

开发路线图:

我很快将发布 pytorchtoengine 工具,它将允许 PyTorch 用户完全绕过 ONNX 中间步骤,直接将模型转换到引擎的原生格式。少一跳,少一件需要调试的事情。

适合谁:

我希望这能成为在资源受限服务器、边缘设备或轻量级系统上工作的开发者的强大替代方案——任何曾经想过“我只需要运行这个模型,我不需要整个生态系统”的人。

从这里往哪里走:

仓库是开放的。关于代码架构的反馈非常欢迎——尤其是来自构建过类似系统或遇到过同样障碍的人。如果这引起你的共鸣,一颗星对支持这个项目大有帮助。

Github

$code = @'
 import pdefa
 import cv2

 model = pdefa.load('D:/PROJE/yolov8s.engine')
 img_path = 'D:/PROJE/bus.jpg'
 boxes = model(img_path, conf_thres=0.75)
 img = cv2.imread(img_path)

 class_names = {0: 'person', 1: 'bicycle', 2: 'car', 3: 'motorcycle', 5: 'bus', 7: 'truck'}

 for b in boxes:
    cls = int(b['cls'])
    conf = b['conf']
    x1, y1 = int(b['x1']), int(b['y1'])
    x2, y2 = int(b['x2']), int(b['y2'])

    names_attr = getattr(model, 'names', {})
    cls_name = class_names.get(cls, names_attr.get(cls, f'cls_{cls}'))

    label = f'{cls_name} {conf:.2f}'

   cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
   cv2.putText(img, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2, cv2.LINE_AA)

print(f'{cls_name} | conf={conf:.3f} | box=[{x1}, {y1}, {x2}, {y2}]')

cv2.imwrite('D:/PROJE/output_bus.png', img)
'@

PDFDUTY AI

Groq Cloud • Llama 3

菜单

首页

所有工具

编辑器

编辑文本和形状

博客

技巧与指南

研究

学术论文与研究

新

主题

语言

最近操作

Lokal Geçmiş