Arganzheng's Blog

stay hungry, stay foolish

PyTorch 深度实践:从 Tensor 到深度学习运行时(总纲)

Deep Dive into PyTorch, from Tensor to Deep Learning Runtime

内容简介 《PyTorch 深度实践:从 Tensor 到深度学习运行时》是一组共十篇的系列文章,面向有后端工程经验、尤其是 Java 背景、准备进入 AI-Infra 方向的工程师,系统梳理 PyTorch 从 Python API 到 C++、CUDA、编译器、性能分析和分布式运行时的主要机制。 它同时是《AI 算法工程师学习地图》 L1 工具箱的深入篇:算法侧的《算法工程师的工具箱》讲 PyTorch 的”用”——五个对象、二十行训练循环、显存的账——本系列讲”改”:Dispatcher、Autograd 引擎、编译、分布式。两张地图共享本系列,算法方向的读者按需读。 这个系列不是 PyTorch API 速查表,也不是机器学习算法教程,而是试图回答一个...

C++ 在 AI-Infra(09):系列总结与通关自测

C++ for AI-Infra: Series Recap and Final Self-Test

八篇正文回答了一个问题:PyTorch 和 vLLM 的 C++ 源码里,这段代码为什么这样写。第一篇讲一个 .cpp 怎么变成 .so、import torch 拉起哪几个库;第二篇讲 at::Tensor 为什么是一个 8 字节的句柄、数据什么时候释放;第三篇讲 AT_DISPATCH 里的 scalar_t 从哪里来;第四篇讲 Dispatcher 用什么机制调到 kernel;第五篇讲算子怎么在没有任何显式调用的情况下登记进 torch.ops;第六篇讲 no_grad 为什么对其他线程不生效;第七篇讲一个 Tensor 跨过 Python/C++ 边界经过了什么;第八篇讲一个改动从写完到能提 PR 要跑哪些东西。八篇合起来,是总纲开篇那段 scale_sh...

C++ 在 AI-Infra(08):构建、调试与测试工具链

Build, Debug and Test Toolchain

PyTorch 的 CI 测试脚本 .ci/pytorch/test.sh 里有一段很奇怪的代码。在 ASan 构建下,它先设置一堆环境变量,然后故意让 Python 进程崩溃四次: if [[ "$BUILD_ENVIRONMENT" == *asan* ]]; then export ASAN_OPTIONS=detect_leaks=0:symbolize=1:detect_stack_use_after_return=true:strict_init_order=true:detect_odr_violation=1:detect_container_overflow=0:check_initialization_order=true:debug=...

C++ 在 AI-Infra(07):与 Python 之间——pybind11、Python C API 与 ABI

pybind11, the Python C API and ABI

torch.Tensor 在 Python 里是一个再普通不过的对象:能 isinstance、能子类化、能 t.foo = 1 挂属性、能被 gc 收集。但它在 C++ 里的定义,在 torch/csrc/autograd/python_variable.h 开头: // Python object that backs torch.autograd.Variable struct THPVariable { PyObject_HEAD // Payload at::Tensor cdata; // Hooks to be run on backwards pass (corresponds to Python attr // '_backw...

C++ 在 AI-Infra(06):并发、内存模型、TLS 与守卫

Concurrency, Memory Model, TLS and Guards

with torch.no_grad(): 大概是 PyTorch 用户最早学会的几个写法之一。它在 Python 侧是一个上下文管理器,__enter__ 调 torch.set_grad_enabled(False),__exit__ 把旧值设回去。顺着 torch._C._set_grad_enabled 往下追,会落到 torch/csrc/autograd/init.cpp 里的这段 C++: static PyObject* set_grad_enabled( PyObject* _unused, PyObject* args, PyObject* kwargs) { HANDLE_TH_ERRORS static Py...

C++ 在 AI-Infra(05):宏、静态注册与代码生成

Macros, Static Registration and Code Generation

vLLM 的 CPU 后端把所有自定义算子登记到 PyTorch 的代码在 csrc/cpu/torch_bindings.cpp 里,形状是这样的: #include "cache.h" #include "ops.h" #include "core/registration.h" #include <torch/library.h> // ... TORCH_LIBRARY_EXPAND(TORCH_EXTENSION_NAME, ops) { // vLLM custom ops // ... // Activation ops // Activation function used in SwiGLU. ops.d...

C++ 在 AI-Infra(04):多态与类型擦除——运行时如何选择实现

Polymorphism and Type Erasure

在 Python 里写 torch.add(a, b),如果 a 在 CPU 上就跑 CPU kernel,在 GPU 上就跑 CUDA kernel。这个”按参数选实现”的动作在 C++ 层叫 dispatch,做这件事的类叫 c10::Dispatcher。它的核心调用路径在 aten/src/ATen/core/dispatch/Dispatcher.h 里(本文引用的 PyTorch 源码以 v2.10.0 为准),删掉调试和 profiler 分支后只剩这几行: template <class Return, class... Args> C10_ALWAYS_INLINE_UNLESS_MOBILE Return Dispatcher::c...

C++ 在 AI-Infra(03):模板与泛型编程

Templates and Generic Programming

打开 aten/src/ATen/native/cpu/Activation.cpp,log_sigmoid 的 CPU kernel 里有这么一段(log_sigmoid_cpu_kernel 的 else 分支,删节): AT_DISPATCH_FLOATING_TYPES(input.scalar_type(), "log_sigmoid_cpu", [&] { using Vec = Vectorized<scalar_t>; scalar_t* output_data = output.data_ptr<scalar_t>(); scalar_t* buffer_data = buffer.data_ptr&l...

C++ 在 AI-Infra(02):值、引用与所有权——对象模型与 RAII

Value Semantics, Ownership and RAII

打开 aten/src/ATen/core/TensorBase.h,at::Tensor 的基类是这样定义的(类定义开头和结尾): class TORCH_API TensorBase { public: TensorBase() = default; explicit TensorBase( c10::intrusive_ptr<TensorImpl, UndefinedTensorImpl> tensor_impl) : impl_(std::move(tensor_impl)) { TORCH_CHECK(impl_.get(), "TensorImpl with nullptr is not supp...

C++ 在 AI-Infra(01 下):工程布局——命名空间、库的分层与 CMake

Project Layout: Namespaces, Library Layering and CMake

上篇讲的是一个翻译单元怎么变成一个 .so:预处理、编译、汇编、链接四个阶段,声明与定义、ODR、符号与可见性、动态链接。PyTorch 有几千个翻译单元,最终编成的不是一个 .so 而是十几个——libc10.so、libtorch_cpu.so、libtorch_cuda.so、libtorch.so、libtorch_python.so、torch/_C.cpython-*.so……本篇讲几千个翻译单元怎么组织成几个库:靠什么划分层次(命名空间)、每一层编成什么(库的分层)、谁来描述这些规则(CMake),以及自己动手搭一个同样结构的最小骨架。 Java 工程师在这里要放弃的直觉是“一个包就是一个 jar”。Java 里 package、目录、.jar 三者...

×