Skip to content

feat: add PrivateUse1 backend extension support - #206

Open
chen2021673 wants to merge 3 commits into
fix/backend-independent-correctnessfrom
refactor/privateuse1-backend
Open

feat: add PrivateUse1 backend extension support#206
chen2021673 wants to merge 3 commits into
fix/backend-independent-correctnessfrom
refactor/privateuse1-backend

Conversation

@chen2021673

@chen2021673 chen2021673 commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

背景

InfiniTrain 原有设备体系只包含 CPU 和 CUDA。接入新后端时,需要在核心框架中增加厂商专属的设备枚举、runtime、CCL、kernel、测试和模型入口判断,导致核心代码与具体厂商耦合。

本 PR 引入通用的 DeviceType::kPrivateUse1 扩展槽位。外部 Provider 可以注册自己的运行时和算子实现,MACA 后端则通过独立仓库接入,公共 CMake 中不包含 MACA SDK 或厂商构建选项。

主要改动

PrivateUse1 注册接口

新增 PrivateUse1BackendRegistrationRegisterPrivateUse1Backend(),统一完成:

  • 注册厂商名称,例如 maca
  • 声明默认 autocast dtype,目前支持 FP16 或 BF16
  • 注册 DeviceGuardImpl
  • 注册 backend kernels
  • 可选注册 CclImpl
  • 校验 runtime、CCL 和基础 kernel 是否注册完整
  • 限制一个进程最多注册一个 PrivateUse1 Provider

Provider 名称仅允许小写 ASCII 字母、数字和下划线,且不能占用 cpucuda

继续复用 REGISTER_KERNELINFINI_TRAIN_REGISTER_DEVICE_GUARD_IMPLINFINI_TRAIN_REGISTER_CCL_IMPL。注册宏同时修正了唯一符号生成和未使用变量告警。

PrivateUse1 Provider 至少需要提供:

  • Cast
  • Fill
  • NoOpForward
  • NoOpBackward

Provider 必须暴露可显式调用且幂等的注册入口,不能只依赖静态库中的文件级初始化。DeviceGuardImpl::Initialize() 改为首次使用时调用,允许 Provider 延迟初始化硬件 runtime。

设备解析与模型入口

新增统一的 Device::ParseType()

  • cpu 映射到 kCPU
  • cuda 映射到 kCUDA
  • privateuse1 映射到 kPrivateUse1
  • 已注册的厂商名称映射到 kPrivateUse1

Device::ToString() 使用注册后的厂商名称。AutocastGuard 根据 Provider 注册信息取得 PrivateUse1 的默认计算类型,CPU 和 CUDA 的现有行为保持不变。

GPT-2、Llama 3 和 Mixtral 使用 Device::ParseType() 解析设备。外部工程可通过编译定义注入 Provider 头文件和注册入口,并在 gflags 校验 --device 前完成注册。并行模型使用用户选择的 accelerator backend,不再固定为 CUDA。

运行脚本新增 DEVICE_BACKEND,默认值仍为 cuda

GPT-2 和 Llama 3 暂时保留少量仅在 Provider 名称为 maca 时启用的同步和进程退出 workaround,并保留 FIXME;这些逻辑不会影响其他 PrivateUse1 Provider。

构建与静态注册

新增并明确以下 CMake 接口:

  • InfiniTrain::infini_train:供库和 Provider 使用的核心接口
  • InfiniTrain::cpu_kernels:CPU kernel target
  • InfiniTrain::infini_train_executable:最终可执行文件的完整链接接口

最终可执行文件通过 archive group 和 --whole-archive 保留 DeviceGuard、CCL 和 kernel 的静态注册对象。Provider 可以通过自己的 executable interface 或 EXTRA_ARCHIVES 加入 Provider 注册 archive。

InfiniTrain 作为 submodule 使用时不再构建自身 examples 和 tools,并隔离 glog 的测试选项,避免污染上层工程。

测试复用

公共测试的 suite 声明与设备实例化分离,每个测试二进制只实例化一个设备。CMake 为目标注入设备类型、GTest 前缀和 DEVICE_INDEX,其中设备序号默认是 0

新增 infini_train_add_privateuse1_test_suites(),允许外部 Provider 复用全量公共测试:

  • Provider 构建要求 USE_CUDA=OFF,冲突时直接报错
  • 保留 InfiniTrain 原有 CPU、fake Provider 和 CPU-only 测试
  • 追加 test_*_<BACKEND_NAME> Provider 测试
  • Provider 注册入口由共享 test_main 在测试环境初始化前显式调用
  • 删除 ONLY_CUDA,copy 等测试改为通用 accelerator 测试

Provider 测试使用厂商名作为 CTest label,例如 MACA 使用 ctest -L maca;不提供 ctest -L privateuse1 标签。

新增无需真实硬件的 fake PrivateUse1 测试,覆盖注册校验、名称解析、默认 autocast dtype、延迟 runtime 初始化和基础 kernel 调度。

Test

image image

@JYMiracle305
JYMiracle305 self-requested a review August 17, 2026 07:17
auto hook = std::make_unique<infini_train::autograd::AllReducePostAccumulateHook>(
function::ReduceOpType::kAvg, ddp_pg_);
const auto reduce_op
= ddp_config.average_in_collective ? function::ReduceOpType::kAvg : function::ReduceOpType::kSum;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

关于 reduce_op 类型和架构后端实现不是强相关的,是不是单独提一个PR

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已单独提交PR #214

} else {
bucket.work = ddp_pg->AllReduce(bucket.contents, function::ReduceOpType::kAvg, true);
const auto reduce_op
= ddp_config_.average_in_collective ? function::ReduceOpType::kAvg : function::ReduceOpType::kSum;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上

@@ -143,18 +145,11 @@ void DeviceGuardImplRegistry::Register(Device::DeviceType type, std::unique_ptr<
LOG(FATAL) << std::format("DeviceGuardImpl for type {} already registrered", static_cast<int>(type));
}

@JYMiracle305 JYMiracle305 Aug 18, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

删除单加速器后端限制后,Tensor::To(Device) 中原有的跨后端复制路径就可以覆盖到了, tensor.cc::161 存在一个问题,第二步 H2D 复制根据 buffer_device获取impl,本来应该使用目标 device来获取tmpl。这里comment作记录,可以另外PR修复,加单元测例覆盖一下。

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InfiniTrain 现在只允许 CPU + 一个 PrivateUse1 provider,应该还不涉及跨后端,但这里确实有潜在问题,留 FIXME 记录

Comment thread CMakeLists.txt
# ------------------------------------------------------------------------------

add_library(infini_train STATIC ${SRC})
add_library(InfiniTrain::infini_train ALIAS infini_train)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

新增的 InfiniTrain::infini_train alias 是不是给外部 provider 直接链接使用的?目前 runtime、CCL 和 kernel 都依赖静态注册,而保证这些注册代码不被链接器裁掉的 --whole-archive 只加在 link_infini_train_exe() 里。如果外部工程直接 target_link_libraries(... InfiniTrain::infini_train),没有调用 link_infini_train_exe(),运行时报 runtime 或 kernel 未注册

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不是给外部 provider 直接链接使用的,provider 必须用 RegisterBackend(),我加一下约束注释。

void RegisterFakeRuntime() {
CHECK_EQ(core::GetPrivateUse1BackendName(), "fake");
CHECK_EQ(Device(Device::DeviceType::kPrivateUse1, 0).ToString(), "Device(fake, 0)");
INFINI_TRAIN_REGISTER_DEVICE_GUARD_IMPL(Device::DeviceType::kPrivateUse1, FakePrivateUse1GuardImpl)

@JYMiracle305 JYMiracle305 Aug 19, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unused variable ‘__infini_train_device_guard_registered__COUNTER__’ [-Wunused-variable]
  236 |     static const bool __infini_train_device_guard_registered##__COUNTER__ = []() {                                     \
      |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

这里会有一个告警,因为之前加了-Wunused 编译选项,是不是在 Register 宏里加一下[[maybe_unused]]。
同时也发现了一个问题,在宏里 __COUNTER__直接接触 ##,没有展开成数字,在此记录一下,后续另提PR修改。

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已增加,同步修改宏展开。

@@ -143,18 +145,11 @@ void DeviceGuardImplRegistry::Register(Device::DeviceType type, std::unique_ptr<
LOG(FATAL) << std::format("DeviceGuardImpl for type {} already registrered", static_cast<int>(type));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

registrered 这里有个拼写错误

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

于单独PR中修改。

@chen2021673
chen2021673 force-pushed the refactor/privateuse1-backend branch 2 times, most recently from 0c5953b to 4b1042c Compare August 25, 2026 09:44
- add a provider-neutral PrivateUse1 device type and registration API
- validate runtime, kernel, and optional CCL backend registrations
- initialize external device runtimes lazily on first use
- support provider names in device parsing and display
- require explicit autocast dtype for PrivateUse1 devices
- allow examples to register an external backend before flag parsing
- honor average_in_collective consistently across DDP paths
- expose embeddable CMake targets and add fake backend tests
- separate test suite declaration from CPU, CUDA, and provider instantiation
- support provider-injected registration, linkage, target names, and CTest labels
- add provider-defined default autocast dtype and backend-neutral test helpers
- generalize accelerator copy tests and remove the ineffective CUDA optimizer test
- fix Exp/Add backward, CUDA bias reduction, and DDP device validation
- scope runtime workarounds to the registered MACA backend
- document external backend test integration and usage
@chen2021673
chen2021673 force-pushed the refactor/privateuse1-backend branch from 4b1042c to 66cc91e Compare August 27, 2026 05:39
@chen2021673
chen2021673 changed the base branch from master to fix/backend-independent-correctness August 31, 2026 08:18
@chen2021673
chen2021673 force-pushed the refactor/privateuse1-backend branch from 66cc91e to 54dc847 Compare August 31, 2026 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants