Pytorch与C语言如何协同工作?

99ANYc3cd6
预计阅读时长 19 分钟
位置: 首页 C语言 正文

PyTorch 本身是用 C++ 和 CUDA(用于 GPU)编写的,然后用 Python 封装起来提供给我们使用。 当你说“PyTorch C语言”时,可能有以下几种理解:

pytorch c语言
(图片来源网络,侵删)
  1. 在 C/C++ 代码中调用 PyTorch 的功能(最常见的需求)
  2. 直接使用 PyTorch 的底层 C++ API(较少见,但性能最高)
  3. 理解 PyTorch 的底层实现(C++ 是其核心)

下面我们逐一详细解释。


在 C/C++ 中调用 PyTorch(最常用和推荐的方式)

对于大多数想在 C/C++ 环境中使用训练好的 PyTorch 模型的开发者来说,最佳实践是使用 TorchScriptLibTorch

核心思想: 将你的 Python 模型转换成一个优化的、独立于 Python 的表示(TorchScript),然后使用 PyTorch 提供的 C++ 库(LibTorch)来加载和运行这个模型。

为什么需要这样做?

pytorch c语言
(图片来源网络,侵删)
  • 性能: C++ 运行时比 Python 快,没有 GIL(全局解释器锁)的限制。
  • 部署: 将模型部署到没有 Python 环境的服务器、嵌入式设备或移动端。
  • 集成: 将模型推理无缝集成到现有的 C++ 应用程序中(如游戏引擎、桌面应用)。

具体步骤:

步骤 1:准备 Python 模型并导出为 TorchScript

你在 Python 中定义、训练并保存你的模型,你需要将它转换为 TorchScript 格式。

import torch
import torch.nn as nn
# 1. 定义一个简单的模型
class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.linear = nn.Linear(10, 2)
    def forward(self, x):
        return self.linear(x)
# 2. 实例化模型
model = MyModel()
# 3. (可选) 训练模型... (这里省略)
# 4. 将模型设置为评估模式
model.eval()
# 5. 创建一个示例输入
example_input = torch.rand(1, 10)
# 6. 导出模型为 TorchScript
# 方法一:追踪 (Tracing)
# scripted_model = torch.jit.trace(model, example_input)
# 方法二:脚本化 (Scripting) - 更推荐,能处理控制流
scripted_model = torch.jit.script(model)
# 7. 保存导出的模型
scripted_model.save("my_model.pt")
print("模型已成功导出为 my_model.pt")

你得到了一个 my_model.pt 文件,它包含了模型的结构和权重,并且可以被 C++ 代码直接加载。

步骤 2:在 C++ 项目中加载并运行模型

你需要从 PyTorch 官网下载 LibTorch,它是 PyTorch 的 C++ 前端,包含了头文件和库。

pytorch c语言
(图片来源网络,侵删)

下载 LibTorch: 访问 PyTorch 官网,选择 "Stable" 版本,然后找到 "Install for C++" 部分,根据你的操作系统和编译器下载对应的预编译包,下载 libtorch-cxx11-abi-shared-with-deps-2.1.0+cu121.zip

设置 C++ 项目环境: 假设你使用的是 CMake,你的 CMakeLists.txt 文件应该如下配置:

cmake_minimum_required(VERSION 3.10)
project(MyCppInference)
# --- 关键部分:设置 LibTorch 路径 ---
# 将下面的路径替换为你解压的 LibTorch 的路径
set(CMAKE_PREFIX_PATH /path/to/your/libtorch)
# 查找 PyTorch 包
find_package(Torch REQUIRED)
add_executable(my_app main.cpp)
# 链接 PyTorch 的库
target_link_libraries(my_app ${TORCH_LIBRARIES})

编写 C++ 代码 (main.cpp):

#include <torch/script.h> // One-stop header.
#include <iostream>
#include <memory>
int main(int argc, const char* argv[]) {
    // 1. 加载 TorchScript 模型
    torch::jit::script::Module module;
    try {
        // 使用 torch::jit::load 加载 .pt 文件
        module = torch::jit::load("my_model.pt");
    }
    catch (const c10::Error& e) {
        std::cerr << "Error loading the model\n";
        return -1;
    }
    std::cout << "模型加载成功!" << std::endl;
    // 2. 准备输入数据
    // 创建一个与 Python 示例输入形状相同的 Tensor
    // {1, 10} 表示 1 个样本,每个样本有 10 个特征
    at::Tensor input = torch::randn({1, 10});
    // 3. 模型推理
    // .to(at::kCPU) 确保在 CPU 上运行,如果你的模型是 GPU 模型,需要 .to(at::kCUDA)
    // 不需要手动调用 forward(),直接像函数一样调用模块即可
    at::Tensor output = module.forward({input}).toTensor();
    // 4. 处理输出结果
    std::cout << "模型输入形状: " << input.sizes() << std::endl;
    std::cout << "模型输出形状: " << output.sizes() << std::endl;
    std::cout << "模型输出值: " << output << std::endl;
    return 0;
}

编译和运行:

mkdir build
cd build
cmake ..
make
./my_app

你会看到输出,证明你的 C++ 程序成功加载并运行了 PyTorch 模型。


直接使用 PyTorch 的底层 C++ API

这是更底层的方式,通常用于构建新的神经网络算子或者对性能有极致要求的场景,它不使用 TorchScript,而是直接操作 C++ 的 torch::Tensortorch::nn 命名空间中的组件。

适用场景:

  • 你想从头开始用 C++ 实现一个复杂的神经网络层,而 Python 的灵活性不够。
  • 你需要编写自定义的 CUDA C++ 扩展。
  • 你在做一个全新的深度学习框架,想借鉴 PyTorch 的底层设计。

特点:

  • API 与 Python 高度相似: torch::nn::Linear, torch::optim::Adam 等在 C++ 中都有对应。
  • 无 Python 依赖: 所有操作都在 C++ 中完成。
  • 复杂度高: 需要你对 C++ 和 PyTorch 的内部机制有更深的理解。

示例代码片段:

#include <torch/torch.h>
#include <iostream>
int main() {
    // 创建一个 Tensor
    torch::Tensor tensor = torch::randn({3, 4});
    std::cout << "Random Tensor:\n" << tensor << std::endl;
    // 定义一个简单的线性层
    torch::nn::Linear linear(4, 2);
    std::cout << "Linear layer:\n" << linear << std::endl;
    // 前向传播
    torch::Tensor output = linear->forward(tensor);
    std::cout << "Output:\n" << output << std::endl;
    return 0;
}

这个例子直接在 C++ 中创建 Tensor 和层,并进行计算,这通常用于研究或开发新功能,而不是简单地部署一个已训练好的模型。


PyTorch 的底层实现(C++)

从架构角度看,PyTorch 的核心是 C++,它负责:

  • 张量计算引擎: ATen (A Tensor Library) 是一个强大的 C++ 模板库,提供了所有张量操作的底层实现。
  • 自动微分: C++ 实现了计算图的构建和反向传播逻辑。
  • 内存管理: 高效的内存分配和缓存机制。
  • 与 CUDA 的桥接: C++ 代码负责将计算任务调度到 GPU 上执行。

Python 的作用是提供了一个高级、易用的接口,通过 torch._C 模块与底层的 C++ 代码进行交互,当你调用 torch.tensor()model.backward() 时,实际上是调用了编译好的 C++ 函数。

总结与对比

方法 主要用途 优点 缺点 复杂度
TorchScript + LibTorch 部署训练好的模型 标准、简单、跨平台、性能好 需要先将 Python 模型转换 低(对于部署而言)
直接使用 C++ API 开发新算子、构建新框架 性能极致、无 Python 依赖 API 不如 Python 友好,文档较少
理解底层 C++ 实现 学习、研究、贡献 PyTorch 深入理解框架原理 非常复杂,不适合快速开发 极高

给你的建议:

  • 如果你是想在 C++ 应用中运行一个已经训练好的 PyTorch 模型,请选择 TorchScript + LibTorch,这是最标准、最推荐的路径。
  • 如果你是 C++ 开发者,想为 PyTorch 贡献新的算子,或者想用 C++ 从零实现一个神经网络,那么可以研究 直接使用 C++ API
  • 如果你想深入理解 PyTorch 为什么这么快,或者想参与 PyTorch 的核心开发,那么你需要去阅读它的 C++ 源码(主要在 atentorch/csrc 目录下)。
-- 展开阅读全文 --
头像
织梦banner调用怎么实现?
« 上一篇 04-11
织梦CMS dede如何快速搭建网站?
下一篇 » 04-12

相关文章

取消
微信二维码
支付宝二维码

目录[+]