pytorch-custom-cuda-tutorial
pytorch-custom-cuda-tutorial 是一份专为 PyTorch 开发者编写的实战教程,旨在指导用户如何从零构建自定义的 CUDA 函数。在早期版本的 PyTorch 中,框架原生不支持高效的“广播求和”操作,开发者通常需要先显式扩展张量维度再进行计算,这不仅消耗额外内存,还增加了不必要的计算开销。本教程通过一个具体的广播求和案例,演示了如何编写底层的 CUDA 内核代码,避免数据复制,从而实现更高效的内存访问与运算。
教程内容循序渐进,涵盖了从编写 CUDA 核心算法、封装 C++ 接口、对接 PyTorch 后端数据结构,到最终生成 Python 可调用的共享库的全过程。尽管现代 PyTorch 版本已原生支持广播机制,不再需要专门为此编写算子,但本教程所揭示的自定义算子开发流程依然具有极高的参考价值。它非常适合希望深入理解 PyTorch 底层机制、需要定制高性能专用算子的研究人员和高级开发者。通过学习该项目,用户能够掌握将自定义 GPU 加速逻辑无缝集成到 PyTorch 生态中的关键技能,为处理特殊模型结构或优化特定计算瓶颈打下坚实基础。
使用场景
某计算机视觉团队在训练大规模图像分割模型时,需要频繁执行高维特征图与低维偏置向量的逐元素相加操作。
没有 pytorch-custom-cuda-tutorial 时
- 内存浪费严重:由于早期 PyTorch 不支持自动广播求和,开发者必须使用
expand_as显式复制小张量以匹配大张量维度,导致显存占用成倍增加。 - 计算效率低下:多余的内存分配和数据拷贝操作占用了宝贵的 GPU 带宽,拖慢了整体训练迭代速度。
- 开发门槛极高:团队缺乏编写自定义 CUDA 内核及将其封装为 Python 可调用的 C/C++ 扩展的经验,难以手动优化底层算子。
- 代码维护困难:硬编码的变通方案使得代码逻辑复杂且难以移植,一旦 PyTorch 版本更新极易引发兼容性问题。
使用 pytorch-custom-cuda-tutorial 后
- 显存占用骤降:通过教程指导编写的自定义 CUDA 内核,直接在 GPU 线程层面实现广播相加,彻底消除了临时张量的内存开销。
- 训练速度提升:去除了冗余的数据拷贝环节,数据流更加顺畅,显著缩短了每个 Epoch 的训练时间。
- 快速落地定制算子:教程提供了从 CUDA 内核编写、C 语言包装到 Python 接口暴露的全流程模板,让团队能迅速构建高效的
broadcast_sum函数。 - 架构清晰易扩展:基于标准的 CFFI 或 C++ 扩展机制构建,代码结构规范,便于后续集成更多自定义底层操作。
pytorch-custom-cuda-tutorial 的核心价值在于它打通了算法原型与高性能底层实现之间的壁垒,让开发者能以极低的成本释放 GPU 的全部算力。
运行环境要求
- Linux
必需 NVIDIA GPU(代码基于 THCudaTensor),需安装与 PyTorch 版本匹配的 CUDA Toolkit,具体显存大小未说明
未说明

快速开始
PyTorch 自定义 CUDA 内核教程
本仓库包含一个用于为 PyTorch 编写自定义 CUDA 函数的教程代码。该代码基于 PyTorch 的 C 扩展示例。
免责声明
- 2019年1月2日:我撰写了 另一份更现代的教程,介绍如何使用 Makefile 构建 PyTorch C++/CUDA 扩展。相关 Git 页面位于 https://github.com/chrischoy/MakePytorchPlusPlus。
- 2018年12月9日:PyTorch CFFI 现已弃用,取而代之的是从 PyTorch 1.0 开始提供的 C++ 扩展。
本教程是在 PyTorch 尚不支持广播求和时编写的。现在 PyTorch 已经支持广播求和,因此你可能不再需要自己实现广播求和函数,但仍然可以按照本教程来构建带有自定义 CUDA 内核的自定义层。
在本仓库中,我们将构建一个简单的基于 CUDA 的广播求和函数。当前版本的 PyTorch 不支持 广播求和,因此我们必须手动扩展张量,例如使用 expand_as 方法,这会创建一个新的张量并占用额外的内存和计算资源。
例如:
a = torch.randn(3, 5)
b = torch.randn(3, 1)
# 下面这行代码会报错
# a += b
# 将 b 扩展成与 a 相同的维度
b_like_a = b.expand_as(a)
a += b_like_a
在本文中,我们将构建一个可以直接对 a 和 b 进行广播求和而无需显式扩展 b 的函数。
mathutil.broadcast_sum(a, b, *map(int, a.size()))
编写 CUDA 内核
首先,我们编写一个 CUDA 内核,它可以在不复制张量 b 的情况下将 b 加到 a 上。
__global__ void broadcast_sum_kernel(float *a, float *b, int x, int y, int size)
{
int i = (blockIdx.x + blockIdx.y * gridDim.x) * blockDim.x + threadIdx.x;
if(i >= size) return;
int j = i % x; i = i / x;
int k = i % y;
a[IDX2D(j, k, y)] += b[k];
}
编写 C 语言封装器
编写好 CUDA 内核后,我们需要用 C 语言对其进行封装。不过,此时我们尚未使用 PyTorch 后端。请注意,输入参数已经是设备指针。
void broadcast_sum_cuda(float *a, float *b, int x, int y, cudaStream_t stream)
{
int size = x * y;
cudaError_t err;
broadcast_sum_kernel<<<cuda_gridsize(size), BLOCK, 0, stream>>>(a, b, x, y, size);
err = cudaGetLastError();
if (cudaSuccess != err)
{
fprintf(stderr, "CUDA kernel failed : %s\n", cudaGetErrorString(err));
exit(-1);
}
}
将 PyTorch 后端与 C 语言封装器连接
接下来,我们需要将 PyTorch 后端与我们的 C 语言封装器连接起来。我们可以使用 THCudaTensor_data 函数来暴露设备指针。指针 a 和 b 都是设备指针(位于 GPU 上)。
extern THCState *state;
int broadcast_sum(THCudaTensor *a_tensor, THCudaTensor *b_tensor, int x, int y)
{
float *a = THCudaTensor_data(state, a_tensor);
float *b = THCudaTensor_data(state, b_tensor);
cudaStream_t stream = THCState_getCurrentStream(state);
broadcast_sum_cuda(a, b, x, y, stream);
return 1;
}
编写 Python 封装器
现在我们已经构建了 CUDA 函数和 PyTorch 函数,接下来需要将这些函数暴露给 Python,以便在 Python 中使用它们。
首先,我们将使用 nvcc 编译生成共享库。
nvcc ... -o build/mathutil_cuda_kernel.so src/mathutil_cuda_kernel.cu
然后,我们将使用 PyTorch 的 torch.utils.ffi.create_extension 函数,它会自动添加适当的头文件并构建一个可加载的 Python 共享库。
from torch.utils.ffi import create_extension
...
ffi = create_extension(
'mathutils',
headers=[...],
sources=[...],
...
)
ffi.build()
测试!
最后,我们可以通过构建项目来测试我们的函数。在 README 中,我省略了许多细节,但你可以看到一个可运行的示例。
git clone https://github.com/chrischoy/pytorch-cffi-tutorial
cd pytorch-cffi-tutorial
make
注意事项
该函数仅接受 THCudaTensor 类型的数据,即 Python 中的 torch.FloatTensor().cuda()。
相似工具推荐
openclaw
OpenClaw 是一款专为个人打造的本地化 AI 助手,旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚,能够直接接入你日常使用的各类通讯渠道,包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息,OpenClaw 都能即时响应,甚至支持在 macOS、iOS 和 Android 设备上进行语音交互,并提供实时的画布渲染功能供你操控。 这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地,用户无需依赖云端服务即可享受快速、私密的智能辅助,真正实现了“你的数据,你做主”。其独特的技术亮点在于强大的网关架构,将控制平面与核心助手分离,确保跨平台通信的流畅性与扩展性。 OpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者,以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力(支持 macOS、Linux 及 Windows WSL2),即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你
stable-diffusion-webui
stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面,旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点,将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。 无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师,还是想要深入探索模型潜力的开发者与研究人员,都能从中获益。其核心亮点在于极高的功能丰富度:不仅支持文生图、图生图、局部重绘(Inpainting)和外绘(Outpainting)等基础模式,还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外,它内置了 GFPGAN 和 CodeFormer 等人脸修复工具,支持多种神经网络放大算法,并允许用户通过插件系统无限扩展能力。即使是显存有限的设备,stable-diffusion-webui 也提供了相应的优化选项,让高质量的 AI 艺术创作变得触手可及。
everything-claude-code
everything-claude-code 是一套专为 AI 编程助手(如 Claude Code、Codex、Cursor 等)打造的高性能优化系统。它不仅仅是一组配置文件,而是一个经过长期实战打磨的完整框架,旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。 通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能,everything-claude-code 能显著提升 AI 在复杂任务中的表现,帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略,使得模型响应更快、成本更低,同时有效防御潜在的攻击向量。 这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库,还是需要 AI 协助进行安全审计与自动化测试,everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目,它融合了多语言支持与丰富的实战钩子(hooks),让 AI 真正成长为懂上
ComfyUI
ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎,专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式,采用直观的节点式流程图界面,让用户通过连接不同的功能模块即可构建个性化的生成管线。 这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景,也能自由组合模型、调整参数并实时预览效果,轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性,不仅支持 Windows、macOS 和 Linux 全平台,还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构,并率先支持 SDXL、Flux、SD3 等前沿模型。 无论是希望深入探索算法潜力的研究人员和开发者,还是追求极致创作自由度的设计师与资深 AI 绘画爱好者,ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能,使其成为当前最灵活、生态最丰富的开源扩散模型工具之一,帮助用户将创意高效转化为现实。
gemini-cli
gemini-cli 是一款由谷歌推出的开源 AI 命令行工具,它将强大的 Gemini 大模型能力直接集成到用户的终端环境中。对于习惯在命令行工作的开发者而言,它提供了一条从输入提示词到获取模型响应的最短路径,无需切换窗口即可享受智能辅助。 这款工具主要解决了开发过程中频繁上下文切换的痛点,让用户能在熟悉的终端界面内直接完成代码理解、生成、调试以及自动化运维任务。无论是查询大型代码库、根据草图生成应用,还是执行复杂的 Git 操作,gemini-cli 都能通过自然语言指令高效处理。 它特别适合广大软件工程师、DevOps 人员及技术研究人员使用。其核心亮点包括支持高达 100 万 token 的超长上下文窗口,具备出色的逻辑推理能力;内置 Google 搜索、文件操作及 Shell 命令执行等实用工具;更独特的是,它支持 MCP(模型上下文协议),允许用户灵活扩展自定义集成,连接如图像生成等外部能力。此外,个人谷歌账号即可享受免费的额度支持,且项目基于 Apache 2.0 协议完全开源,是提升终端工作效率的理想助手。
markitdown
MarkItDown 是一款由微软 AutoGen 团队打造的轻量级 Python 工具,专为将各类文件高效转换为 Markdown 格式而设计。它支持 PDF、Word、Excel、PPT、图片(含 OCR)、音频(含语音转录)、HTML 乃至 YouTube 链接等多种格式的解析,能够精准提取文档中的标题、列表、表格和链接等关键结构信息。 在人工智能应用日益普及的今天,大语言模型(LLM)虽擅长处理文本,却难以直接读取复杂的二进制办公文档。MarkItDown 恰好解决了这一痛点,它将非结构化或半结构化的文件转化为模型“原生理解”且 Token 效率极高的 Markdown 格式,成为连接本地文件与 AI 分析 pipeline 的理想桥梁。此外,它还提供了 MCP(模型上下文协议)服务器,可无缝集成到 Claude Desktop 等 LLM 应用中。 这款工具特别适合开发者、数据科学家及 AI 研究人员使用,尤其是那些需要构建文档检索增强生成(RAG)系统、进行批量文本分析或希望让 AI 助手直接“阅读”本地文件的用户。虽然生成的内容也具备一定可读性,但其核心优势在于为机器