寒武纪PyTorch理事会席位背后:AI芯片软件栈适配与算子实现全解析
发布时间:2026/9/25 15:24:44来源:尧图网络
1. 从“同桌”这个词说起一个信号背后的技术分量“寒武纪拿下PyTorch最高席位与英伟达同桌”——这个标题我第一次看到的时候正在调一个模型训练脚本手边跑着的是一台装了消费级显卡的机器。说实话第一反应不是兴奋而是“终于”。因为做深度学习框架适配这行的人都知道PyTorch的技术治理结构里能进入核心决策层的企业从来不只是“贡献了几行代码”那么简单。PyTorch基金会PyTorch Foundation的治理架构是2022年从Meta手里剥离出来、交给Linux基金会托管之后逐步成型的。它的理事会Governing Board和技术咨询委员会Technical Advisory Council席位基本代表了全球深度学习框架生态里最有话语权的一批玩家。英伟达、AMD、Meta、Google、微软、亚马逊这些名字长期占据核心位置原因很直接它们要么是框架的主要贡献者要么是硬件后端的主要实现方要么是最大规模的使用方。寒武纪能拿到这个席位意味着它在PyTorch生态里的角色从“下游适配者”变成了“上游共建者”。这个转变的技术含量比很多人想象的要高得多。我见过太多人把“支持PyTorch”理解成“能跑起来就行”但真正做过框架后端适配的工程师都清楚从“能跑”到“进治理层”中间隔着的是对框架核心抽象的理解深度、对算子语义的精确实现、以及对整个编译栈的持续投入。这篇文章我想聊的不是新闻本身而是这个信号背后一个AI芯片公司的软件栈到底要具备什么样的能力才能走到这个位置。同时我也会把PyTorch环境搭建、芯片适配、算子实现这些实操层面的东西拆开讲清楚让不管是刚入门的新手还是正在做国产硬件适配的同行都能从中拿到能直接用的东西。2. PyTorch生态的“席位”到底意味着什么2.1 基金会治理结构里的技术话语权PyTorch基金会的理事会成员通常来自几个类别创始成员Meta、AMD、AWS、Google、Microsoft、NVIDIA等、一般成员、以及关联成员。每个席位背后对应的不只是资金赞助更重要的是技术方向的投票权和标准制定参与权。技术咨询委员会TAC的职责更偏工程侧负责审批新的后端接入方案、评审核心API的变更提案、协调跨厂商的算子语义一致性。一个硬件厂商如果只是“能跑PyTorch”它只需要维护一个torch.compile的后端或者一个PrivateUse1的设备扩展就行。但进入TAC或理事会意味着你要参与决定“下一个版本的PyTorch设备抽象层应该怎么改”“新的算子注册机制要不要兼容旧后端”这类问题。我举个具体的例子。PyTorch 2.x引入的torch.compile和TorchInductor对后端硬件提出了全新的要求。以前你只要实现一套ATen算子就能跑Eager模式现在还要考虑Dynamo的图捕获、Inductor的代码生成、以及不同后端之间的调度策略。如果一个芯片厂商在TAC里有席位它就能在Inductor的后端接口设计阶段就提出意见而不是等接口冻结了再去逆向适配。2.2 从“适配”到“共建”的技术门槛我接触过不少做国产芯片软件栈的团队大家普遍有一个误区觉得把PyTorch的算子库对着文档实现一遍跑通ResNet和BERT就算“支持PyTorch”了。这个标准在2019年可能还说得过去放到今天远远不够。现在的PyTorch生态一个合格的硬件后端至少要覆盖这几层ATen算子层这是最基础的几百个算子的语义要跟CUDA后端对齐包括各种边界条件、数据类型提升规则、广播语义。调度与内存管理层PyTorch的CUDACachingAllocator那套内存池机制在非CUDA设备上怎么复现直接影响到训练时的显存利用率和碎片化程度。图编译层Dynamo捕获的FX图要能被你的后端正确消费。Inductor生成Triton代码的那套流程如果你的硬件不支持Triton就得自己实现一套等价的代码生成路径。分布式训练层NCCL在CUDA生态里的地位不用多说非CUDA设备要接入PyTorch的分布式接口要么实现一套兼容NCCL API的通信库要么走Gloo的路线但性能会打折扣。量化与推理优化层INT8、FP8这些低精度格式的支持以及和torch.ao量化工具链的对接。寒武纪能进理事会说明它在这些层面至少拿出了让社区认可的方案。具体是哪些层面公开信息里没有完整披露但从它之前开源的torch_mluCambricon PyTorch扩展和catch寒武纪的PyTorch后端来看ATen算子覆盖和调度层是下了功夫的。2.3 对普通开发者的实际影响你可能会问一个芯片公司进理事会跟我一个天天写nn.Module的人有什么关系关系很直接。最明显的一点是以后你在PyTorch里用torch.mlu或者类似的设备抽象时它的行为会更接近torch.cuda。以前国产芯片的PyTorch适配经常出现“这个算子不支持”“那个dtype报错”的情况很大程度上是因为适配方没有参与上游设计只能被动跟着CUDA后端的实现走。有了席位之后设备抽象层的接口设计会更考虑多后端的通用性而不是默认以CUDA为唯一参考。另一个影响是文档和教程的覆盖。PyTorch官方教程里如果开始出现非CUDA设备的示例对新手来说学习成本会低很多。我见过太多人第一次接触国产AI芯片时卡在“怎么把.cuda()换成对应的设备调用”这一步上。3. 芯片适配PyTorch的完整技术路径拆解3.1 设备抽象层PrivateUse1机制怎么用PyTorch从1.13开始正式引入了PrivateUse1这个设备类型专门给非CUDA、非ROCm的第三方硬件用。它的设计初衷就是让芯片厂商不用改PyTorch核心代码通过扩展机制就能注册自己的设备。具体来说你需要做这几件事# 注册设备名称 torch.utils.rename_privateuse1_backend(mlu) # 注册设备模块 torch._register_device_module(mlu, MLUModule) # 生成对应的设备类型 torch.utils.generate_methods_for_privateuse1_backend()这三行代码执行完之后你就可以像用torch.cuda一样用torch.mlu了。tensor.mlu()、torch.mlu.current_device()、torch.mlu.synchronize()这些方法都会自动生成。但这里有个坑rename_privateuse1_backend必须在任何张量创建之前调用而且一个进程里只能调用一次。我见过有人在Jupyter Notebook里反复执行注册代码结果第二次就报错。正确的做法是把它放在包的__init__.py里或者用一个单独的初始化模块来管理。3.2 算子注册从ATen到你的硬件PyTorch的算子注册机制核心是TORCH_LIBRARY和TORCH_LIBRARY_IMPL这两个宏。对于第三方后端你需要为每个算子实现对应的kernel然后注册到你的设备类型上。// 以add算子为例 TORCH_LIBRARY_IMPL(aten, PrivateUse1, m) { m.impl(add.Tensor, TORCH_FN(mlu_add_tensor)); m.impl(add.Scalar, TORCH_FN(mlu_add_scalar)); m.impl(add.out, TORCH_FN(mlu_add_out)); }这里的关键是算子变体。PyTorch里一个add操作可能有十几个变体add.Tensor、add.Scalar、add.out、add.Scalar_out、add_.Tensor原地操作等等。你如果只实现了add.Tensor那用户写torch.add(a, b, outc)的时候就会报“未实现”的错误。我的经验是先把PyTorch的native_functions.yaml里所有标记为CompositeExplicitAutograd的算子过一遍这些是可以通过组合其他算子实现的优先级可以放低。真正要优先实现的是CompositeImplicitAutograd和那些直接对应硬件指令的算子。3.3 内存管理别小看CachingAllocatorCUDA生态里CUDACachingAllocator是PyTorch显存管理的核心。它通过缓存已分配的内存块避免频繁调用cudaMalloc和cudaFree带来的性能开销。在非CUDA设备上如果你直接用malloc和free训练速度可能会掉30%以上。寒武纪的torch_mlu里实现了一套MLUCachingAllocator基本思路和CUDA版本一致维护一个按大小分桶的空闲块列表分配时优先从缓存里找合适大小的块找不到再向驱动申请。释放时不立即归还给驱动而是放回缓存。这里有个细节值得注意内存池的大小和碎片化策略。CUDA的allocator默认会保留所有释放的块直到进程结束。如果你的设备显存比较小比如推理卡只有16GB可能需要设置一个上限超过之后主动释放一些块。PyTorch提供了torch.cuda.memory._set_allocator_settings这样的接口第三方后端也可以实现类似的配置项。3.4 图编译与Inductor后端对接PyTorch 2.x之后torch.compile成了性能优化的主要入口。它的工作流程是Dynamo捕获Python字节码生成FX图AOTAutograd做前向和反向的图分解Inductor把FX图 lowering 成Triton代码或者C代码。对于非CUDA设备你有两个选择实现一个Inductor后端继承torch._inductor.codegen.common.CodeGen实现自己的调度和代码生成逻辑。这条路工作量大但性能上限高。走Triton兼容路线如果你的硬件能跑Triton生成的代码或者你能把Triton IR翻译成自己的指令那就可以复用Inductor的大部分流程。寒武纪走的是哪条路公开资料里没有明确说。但从它之前发布的torch_mlu更新日志来看torch.compile的支持是逐步推进的早期版本需要设置torch._dynamo.config.suppress_errors True来跳过不支持的图。4. 实操从零搭建PyTorch环境并验证芯片适配4.1 环境准备Anaconda与Python版本选择不管你用的是CUDA设备还是国产芯片Anaconda都是管理Python环境最省心的方式。我个人的习惯是每个项目一个独立环境避免依赖冲突。# 创建环境Python版本建议3.9或3.10 conda create -n pytorch_mlu python3.10 conda activate pytorch_mlu # 安装PyTorch基础包 # 注意如果你的芯片厂商提供了定制版PyTorch要用他们的源 pip install torch torchvision torchaudio这里有个关键点PyTorch版本和芯片驱动版本的匹配。CUDA生态里PyTorch 2.0需要CUDA 11.7或11.8PyTorch 2.1开始支持CUDA 12.1。国产芯片也有类似的版本对应关系装之前一定要看厂商的release note。我踩过的一个坑是用conda装PyTorch时conda会自动装一个它认为兼容的CUDA runtime但这个runtime可能和你系统里的驱动版本不匹配。后来我改成用pip装并且明确指定--index-url指向厂商的包源问题就少了。4.2 验证设备可用性与基本算子环境装好之后第一件事是验证设备能不能被PyTorch识别import torch # 检查设备是否可用 print(torch.mlu.is_available()) # 如果是寒武纪 print(torch.mlu.device_count()) print(torch.mlu.get_device_name(0)) # 创建一个张量并移动到设备上 x torch.randn(3, 3) x_mlu x.mlu() print(x_mlu.device) # 跑一个简单的矩阵乘法 a torch.randn(1024, 1024).mlu() b torch.randn(1024, 1024).mlu() c torch.mm(a, b) print(c.sum())如果这几步都能跑通说明基础的算子注册和内存管理没问题。接下来要测的是算子覆盖度。我的做法是拿一个真实的模型比如ResNet-50跑一遍前向和反向看哪些算子会报“未实现”。import torchvision.models as models model models.resnet50().mlu() x torch.randn(32, 3, 224, 224).mlu() y model(x) loss y.sum() loss.backward() print(ResNet-50 forward/backward OK)如果这一步报错错误信息通常会告诉你缺哪个算子。比如aten::adaptive_avg_pool2d没实现你就需要去补这个算子的kernel。4.3 性能对比别只看“能跑”“能跑”和“跑得快”是两回事。我见过一些适配方案功能测试全过但训练速度只有CUDA版本的十分之一。问题通常出在几个地方算子实现没有用上硬件的向量化指令比如矩阵乘法如果只是用for循环在CPU上算完再拷贝回设备那速度肯定不行。内存拷贝太频繁每次算子调用都做一次host-device同步会把流水线打断。没有做算子融合PyTorch Eager模式下conv bn relu是三个独立的kernel调用。CUDA生态里有cuDNN做融合非CUDA设备如果没做类似的优化性能差距会很大。我一般会用torch.profiler来看每个算子的耗时with torch.profiler.profile( activities[torch.profiler.ProfilerActivity.CPU, torch.profiler.ProfilerActivity.MLU], scheduletorch.profiler.schedule(wait1, warmup1, active3), on_trace_readytorch.profiler.tensorboard_trace_handler(./log) ) as prof: for step, data in enumerate(dataloader): if step 5: break train_step(model, data) prof.step()看trace的时候重点关注两件事一是设备上的kernel执行时间占比二是host和device之间的同步点。如果同步点太多说明你的后端在算子调度上还有优化空间。4.4 分布式训练接入的注意事项单卡跑通之后下一步通常是多卡分布式。PyTorch的分布式接口主要有两种DistributedDataParallelDDP和FullyShardedDataParallelFSDP。它们底层都依赖通信库来做梯度同步。CUDA生态里用NCCL非CUDA设备要么实现一套兼容NCCL API的通信库要么用Gloo。Gloo的问题是它主要针对CPU优化在设备间通信时性能损失比较大。我实测过一个4卡训练的任务用Gloo的吞吐量只有NCCL的60%左右。如果你的芯片厂商提供了自己的通信库接入方式通常是实现torch.distributed.ProcessGroup的子类然后通过init_process_group的backend参数指定。这里要注意的是通信和计算的重叠。DDP默认会在反向传播的同时做梯度allreduce如果你的通信库不支持异步操作这个重叠就做不起来训练速度会明显下降。5. 常见问题与排查技巧实录5.1 算子未实现报错怎么定位最常见的报错长这样RuntimeError: Could not run aten::xxx with arguments from the MLU backend.排查步骤确认这个算子在CUDA后端有没有实现。如果CUDA也没有那可能是PyTorch版本的问题。检查你的TORCH_LIBRARY_IMPL注册代码看算子名和变体是否写对了。PyTorch的算子名是大小写敏感的add.Tensor和add.tensor不一样。如果算子是通过组合实现的Composite检查依赖的子算子是否都已实现。我整理了一个速查表报错信息可能原因解决方法Could not run aten::xxx算子未注册实现并注册对应kernelExpected all tensors to be on the same device张量设备不一致检查.to(device)调用MLU out of memory显存不足减小batch size或优化内存池NCCL error/Gloo error通信库配置问题检查环境变量和网络配置dtype not supported数据类型不支持转换到支持的dtype或实现该dtype的kernel5.2 环境配置的坑驱动、CUDA、PyTorch三者关系虽然这里聊的是国产芯片但很多人是在CUDA环境里做开发然后迁移到国产芯片上。CUDA环境本身就有不少坑我顺带说一下。驱动版本和CUDA版本的关系NVIDIA驱动是向下兼容CUDA的但有一个最低版本要求。比如CUDA 12.1需要驱动版本530。你可以用nvidia-smi看驱动版本用nvcc --version看CUDA版本。如果nvcc显示的版本和PyTorch编译时用的CUDA版本不一致可能会出现运行时错误。PyTorch和CUDA的对应关系PyTorch官网的安装命令里会明确写cu118、cu121这样的后缀。如果你用conda install pytorch而不指定conda可能会装一个CPU版本或者装一个和你驱动不匹配的CUDA版本。Anaconda环境隔离我强烈建议用conda创建独立环境不要在base环境里装PyTorch。因为不同项目可能依赖不同版本的PyTorch混在一起迟早出问题。5.3 性能调优的独家经验做了几年框架适配我总结了几条性能调优的经验有些是文档里不会写的第一条先看数据加载再看模型计算。很多人一上来就优化算子结果发现瓶颈在DataLoader上。用torch.utils.data.DataLoader的时候num_workers设成CPU核心数的一半到三分之二比较合适pin_memoryTrue在CUDA环境下能加速host到device的拷贝但在非CUDA设备上不一定有效要实测。第二条batch size不是越大越好。大batch能提高硬件利用率但也会增加显存压力和通信开销。我一般会做一个batch size的扫描从16开始翻倍看吞吐量的变化曲线找到拐点。第三条混合精度训练要谨慎。AMP自动混合精度在CUDA上很成熟但在非CUDA设备上FP16的算子覆盖度可能不够。如果发现loss变成NaN先检查是不是某个算子在FP16下溢出了。第四条算子融合是最大的性能杠杆。如果你们的芯片支持自定义算子融合一定要把convbnrelu、lineargelu这些常见pattern做进去。我见过一个案例光是融合了这几个pattern训练速度就提升了40%。5.4 从CUDA迁移到国产芯片的代码改动清单如果你有一个现成的CUDA项目要迁移到国产芯片需要改的地方其实不多但每一处都要仔细# 1. 设备指定 # 原来 device torch.device(cuda:0) # 改成 device torch.device(mlu:0) # 或厂商指定的设备名 # 2. 张量移动 # 原来 x x.cuda() # 改成 x x.mlu() # 3. 分布式后端 # 原来 dist.init_process_group(backendnccl) # 改成 dist.init_process_group(backendcncl) # 或厂商提供的后端名 # 4. 随机种子 # 原来 torch.cuda.manual_seed(42) # 改成 torch.mlu.manual_seed(42) # 5. 性能分析 # 原来 with torch.profiler.profile(activities[torch.profiler.ProfilerActivity.CUDA]): # 改成 with torch.profiler.profile(activities[torch.profiler.ProfilerActivity.MLU]):看起来简单但实际迁移时最容易出问题的是第三方库的依赖。比如apex、deepspeed、flash-attention这些库它们内部有大量CUDA-specific的代码。如果厂商没有提供对应的移植版本你可能需要自己改。6. 这件事对行业意味着什么6.1 多后端生态的必然趋势PyTorch基金会接纳寒武纪本质上反映了一个趋势深度学习框架正在从“CUDA中心化”走向“多后端并行”。这个趋势不是PyTorch一家的事TensorFlow有tf.device的插件机制JAX有PJRTPortable JAX Runtime大家都在做类似的事情。对开发者来说这意味着以后写代码时设备相关的部分会越来越抽象。你可能不需要写x.cuda()而是写x.to(device)然后通过配置来决定用哪个后端。这对代码的可移植性是好事但也要求你对不同后端的特性有基本了解不然性能调优会无从下手。6.2 国产芯片软件栈的短板与机会说实话国产AI芯片在硬件参数上追得很快但在软件栈上普遍落后。这个落后不是“能不能跑”的问题而是“好不好用”的问题。具体表现在文档质量参差不齐很多厂商的文档只告诉你“怎么装”不告诉你“为什么这么装”出了问题只能提工单。社区支持薄弱CUDA生态里有Stack Overflow、有GitHub上成千上万的issue国产芯片的社区还在建设中。工具链不完整性能分析工具、调试工具、可视化工具这些CUDA生态里习以为常的东西在国产芯片上往往缺失。寒武纪进PyTorch理事会至少说明它在软件栈上的投入得到了社区认可。这对整个国产芯片行业是一个正向信号软件生态的建设开始被放到和硬件同等重要的位置。6.3 给开发者的建议现在该做什么如果你是一个深度学习开发者不管你现在用的是CUDA还是国产芯片我有几个建议第一不要把设备相关的代码写死。用device torch.device(...)这样的方式而不是到处写.cuda()。这样以后迁移的时候改一个地方就行。第二关注PyTorch的RFCRequest for Comments。PyTorch的重大变更都会先发RFC比如PrivateUse1机制、torch.compile的后端接口都是在RFC阶段就公开讨论的。提前了解这些能让你在适配时少走弯路。第三动手试。如果你手边有国产芯片的开发板或者云上的实例花一个下午把PyTorch环境搭起来跑一个简单的模型。很多问题只有亲手做了才会遇到看文档是看不出来的。第四参与社区。PyTorch的GitHub issue和论坛里关于非CUDA后端的讨论越来越多。你遇到的问题很可能别人也遇到过。把你的解决方案分享出来既帮了别人也让自己对问题的理解更深一层。7. 一个具体的算子适配案例从报错到跑通7.1 问题现场adaptive_avg_pool2d未实现我之前帮一个团队做模型迁移模型里用了nn.AdaptiveAvgPool2d((1, 1))在CUDA上跑得好好的换到某国产芯片上就报错RuntimeError: Could not run aten::adaptive_avg_pool2d with arguments from the XXX backend.查了一下这个算子在PyTorch里的实现是CompositeExplicitAutograd也就是说它本身不直接对应硬件指令而是通过组合其他算子实现的。理论上如果基础算子都实现了这个算子应该能自动工作。但报错说明要么是组合路径上的某个基础算子没实现要么是自动微分部分出了问题。7.2 排查过程逐层分解我的排查思路是这样的第一步确认adaptive_avg_pool2d在CUDA后端的实现方式。翻PyTorch源码发现它最终调用的是adaptive_avg_pool2d_out_cuda里面用了at::native::adaptive_avg_pool2d这个函数。第二步检查这个函数依赖哪些基础算子。主要是mean、view、unsqueeze这几个。写一个最小复现脚本import torch x torch.randn(1, 64, 7, 7).mlu() # 手动模拟adaptive_avg_pool2d y x.mean(dim[2, 3], keepdimTrue) print(y.shape) # 应该是 (1, 64, 1, 1)如果这一步报错说明mean算子有问题。如果这一步能过那问题出在自动微分或者算子注册上。第三步检查自动微分。adaptive_avg_pool2d的反向传播需要adaptive_avg_pool2d_backward这个算子在CUDA后端是单独实现的。如果国产芯片的后端没有实现这个反向算子那前向能跑反向就会报错。7.3 解决方案注册复合算子确认问题之后解决方案有两种方案一实现缺失的基础算子。如果mean没实现那就补mean的kernel。这是最彻底的做法但工作量大。方案二注册复合算子。在TORCH_LIBRARY_IMPL里把adaptive_avg_pool2d注册为一个CompositeImplicitAutograd算子让PyTorch自动用基础算子组合出前向和反向。TORCH_LIBRARY_IMPL(aten, PrivateUse1, m) { m.impl(adaptive_avg_pool2d, TORCH_FN(at::native::adaptive_avg_pool2d)); m.impl(adaptive_avg_pool2d_backward, TORCH_FN(at::native::adaptive_avg_pool2d_backward)); }这里的关键是at::native::adaptive_avg_pool2d这个函数本身是设备无关的它内部会调用mean等基础算子。只要基础算子在你的设备上实现了这个复合算子就能工作。7.4 验证与性能测试改完之后重新跑模型model MyModel().mlu() x torch.randn(16, 3, 224, 224).mlu() y model(x) loss y.sum() loss.backward() print(Forward and backward OK)跑通之后用profiler看一下这个算子的耗时。如果发现adaptive_avg_pool2d的耗时占比很高那可能需要进一步优化比如针对(1, 1)这种输出尺寸做特化实现。这个案例的通用经验是遇到算子未实现先查PyTorch源码看它是怎么实现的再决定是补基础算子还是注册复合算子。不要一上来就写kernel很多时候组合现有算子就能解决问题。8. 关于PyTorch版本选择的一些个人建议8.1 稳定版还是Nightly版PyTorch的发布节奏是每季度一个稳定版中间有nightly版。对于生产环境我强烈建议用稳定版。nightly版虽然能提前用到新特性但API变动频繁而且可能有未修复的bug。对于芯片适配来说稳定版还有一个好处厂商的适配通常是跟着稳定版走的。你用nightly版可能遇到厂商还没适配的API变更。8.2 从哪个版本开始支持PrivateUse1PrivateUse1机制是PyTorch 1.13正式引入的。如果你用的芯片厂商的适配是基于更早的版本比如1.12那它可能用的是更老的扩展机制比如torch.utils.cpp_extension或者直接改PyTorch源码。后者的维护成本很高每次PyTorch升级都要重新打patch。所以如果你在选择芯片方案可以问一下厂商你们的PyTorch适配是基于哪个版本用的是PrivateUse1还是改源码这个问题的答案很大程度上反映了厂商软件栈的成熟度。8.3 长期支持版本的考量PyTorch基金会从2.0开始对每个大版本提供一定的长期支持。但说实话PyTorch的LTS策略不如Ubuntu那么明确。我的建议是如果你的项目周期比较长选一个社区活跃、厂商适配跟得紧的版本然后锁定这个版本不要频繁升级。我自己的项目里PyTorch版本是写在requirements.txt里的精确到小版本号。升级之前一定会在测试环境里跑一遍完整的回归测试。9. 写在最后一些零散但有用的经验做框架适配这几年我最大的体会是软件栈的成熟度比硬件参数更能决定一个芯片好不好用。一个算力很强的芯片如果PyTorch适配做得稀烂开发者用起来会非常痛苦。反过来一个算力中等的芯片如果软件栈做得好能覆盖大部分常用模型那它的实际可用性反而更高。寒武纪进PyTorch理事会是一个积极的信号但也是一个起点。进了理事会不等于所有问题都解决了后面还有大量的工程工作要做。对开发者来说保持关注、动手尝试、反馈问题是对这个生态最好的支持。最后分享一个小技巧如果你在适配过程中遇到了PyTorch的bug或者觉得某个API设计不合理可以在PyTorch的GitHub上提issue。提issue的时候附上一个最小复现脚本说明你的设备类型和PyTorch版本。我提过几个关于PrivateUse1的issue社区的响应速度比我想象的要快。参与开源社区其实没有想象中那么遥不可及。
网站建设高端定制企业官网