Skip to content

feat: add PrivateUse1 backend extension support - #206

Open
chen2021673 wants to merge 1 commit into
masterfrom
refactor/privateuse1-backend
Open

feat: add PrivateUse1 backend extension support#206
chen2021673 wants to merge 1 commit into
masterfrom
refactor/privateuse1-backend

Conversation

@chen2021673

@chen2021673 chen2021673 commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

背景

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

本 PR 引入通用的 DeviceType::kPrivateUse1 扩展槽位,使外部厂商后端可以在不修改 InfiniTrain 核心设备枚举和模型逻辑的情况下注册自己的实现。MACA 后端将作为独立仓库使用该接口接入。

主要改动

PrivateUse1 注册接口

新增 PrivateUse1BackendRegistrationRegisterPrivateUse1Backend(),统一编排以下注册流程:

  • 注册厂商可见名称,例如 maca
  • 注册 DeviceGuardImpl
  • 注册 backend kernels
  • 可选注册 CclImpl
  • 校验基础 runtime 和 kernel 是否注册完整
  • 限制一个进程最多注册一个 PrivateUse1 provider

保留并复用现有三个注册宏:

  • REGISTER_KERNEL
  • INFINI_TRAIN_REGISTER_DEVICE_GUARD_IMPL
  • INFINI_TRAIN_REGISTER_CCL_IMPL

PrivateUse1 后端至少需要提供以下基础算子:

  • Cast
  • Fill
  • NoOpForward
  • NoOpBackward

设备名称解析

新增统一的 Device::ParseType()

  • cpu 映射到 kCPU
  • cuda 映射到 kCUDA
  • privateuse1 映射到 kPrivateUse1
  • 注册后的厂商名称,例如 maca,映射到 kPrivateUse1

Device::ToString() 同样使用注册后的厂商名称展示设备。

Example 外部后端入口

GPT2、LLaMA3 和 Mixtral example 支持在解析 --device 前调用外部 backend registrar,同时不直接依赖任何厂商头文件。
外部仓库可以注入:

  • backend 声明头文件
  • backend 注册函数

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

} 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修复,加单元测例覆盖一下。

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 未注册

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修改。

@@ -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 这里有个拼写错误

- 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
@chen2021673
chen2021673 force-pushed the refactor/privateuse1-backend branch from 2d8e754 to 0c5953b Compare August 20, 2026 08:38
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