<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>分布式训练 | Twinkle</title><link>https://modelscope.github.io/twinkle-web/zh/tags/%E5%88%86%E5%B8%83%E5%BC%8F%E8%AE%AD%E7%BB%83/</link><atom:link href="https://modelscope.github.io/twinkle-web/zh/tags/%E5%88%86%E5%B8%83%E5%BC%8F%E8%AE%AD%E7%BB%83/index.xml" rel="self" type="application/rss+xml"/><description>分布式训练</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>zh-Hans</language><lastBuildDate>Wed, 03 Jun 2026 00:00:00 +0000</lastBuildDate><image><url>https://modelscope.github.io/twinkle-web/media/logo_hu_fedc6a0bfe689b18.png</url><title>分布式训练</title><link>https://modelscope.github.io/twinkle-web/zh/tags/%E5%88%86%E5%B8%83%E5%BC%8F%E8%AE%AD%E7%BB%83/</link></image><item><title>两种执行模式：torchrun（本地）与 Ray（分布式）</title><link>https://modelscope.github.io/twinkle-web/zh/blog/torchrun-ray/</link><pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate><guid>https://modelscope.github.io/twinkle-web/zh/blog/torchrun-ray/</guid><description>&lt;p&gt;Twinkle 的 &lt;code&gt;infra&lt;/code&gt; 模块提供统一的编程模型，无缝支持两种运行模式：&lt;strong&gt;local&lt;/strong&gt;（单机 torchrun）和 &lt;strong&gt;ray&lt;/strong&gt;（多机 Ray 集群）。本文介绍其架构设计、基于装饰器的 API，以及各模式的适用场景。&lt;/p&gt;
&lt;h2 id="两种模式概览"&gt;两种模式概览&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Local (torchrun)&lt;/th&gt;
&lt;th&gt;Ray (分布式)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;启动方式&lt;/td&gt;
&lt;td&gt;&lt;code&gt;torchrun --nproc_per_node=N&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ray start&lt;/code&gt; + 驱动脚本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;适用范围&lt;/td&gt;
&lt;td&gt;单机，共享文件系统&lt;/td&gt;
&lt;td&gt;多机集群&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;进程模型&lt;/td&gt;
&lt;td&gt;每 GPU 一个进程，torch.distributed&lt;/td&gt;
&lt;td&gt;Ray Actor + PlacementGroup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;最适合&lt;/td&gt;
&lt;td&gt;快速实验、单机训练&lt;/td&gt;
&lt;td&gt;生产环境多机、异构资源&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;两种模式使用&lt;strong&gt;完全相同的用户代码&lt;/strong&gt;——切换只需修改 &lt;code&gt;twinkle.infra.initialize()&lt;/code&gt; 的 &lt;code&gt;mode&lt;/code&gt; 参数。&lt;/p&gt;
&lt;h2 id="初始化"&gt;初始化&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;twinkle.infra&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;infra&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Local 模式 — 从 torchrun 环境变量自动检测 ranks 和设备&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;infra&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;local&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Ray 模式 — 需要显式定义 DeviceGroup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;infra&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ray&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;nproc_per_node&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DeviceGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;model&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ranks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;device_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;cuda&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DeviceGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;sampler&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ranks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;device_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;cuda&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Local 模式&lt;/strong&gt;下，Twinkle 从环境变量读取 &lt;code&gt;WORLD_SIZE&lt;/code&gt;、&lt;code&gt;RANK&lt;/code&gt;、&lt;code&gt;LOCAL_RANK&lt;/code&gt;（由 torchrun 设置），创建一个涵盖所有 GPU 的默认 &lt;code&gt;DeviceGroup&lt;/code&gt;，并自动构建带 &lt;code&gt;dp&lt;/code&gt; 维度的 &lt;code&gt;DeviceMesh&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ray 模式&lt;/strong&gt;下，&lt;code&gt;RayHelper.initialize()&lt;/code&gt; 创建 &lt;code&gt;ResourceManager&lt;/code&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;查询 Ray 集群所有活跃节点的 GPU/NPU 资源&lt;/li&gt;
&lt;li&gt;为每个节点创建 &lt;code&gt;PlacementGroup&lt;/code&gt; 包，保证资源共置&lt;/li&gt;
&lt;li&gt;通过 &lt;code&gt;visible_devices&lt;/code&gt; 发现将逻辑 rank 映射到物理 GPU&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="装饰器-api"&gt;装饰器 API&lt;/h2&gt;
&lt;p&gt;Twinkle 的核心抽象是两个装饰器，让任何类都能透明地分布式化：&lt;/p&gt;
&lt;h3 id="remote_class"&gt;&lt;code&gt;@remote_class&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;封装类的 &lt;code&gt;__init__&lt;/code&gt;，在本地直接运行或创建 Ray Actor：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@infra.remote_class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;all&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device_mesh&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DeviceMesh&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;load_model&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Local 模式下 &lt;code&gt;__init__&lt;/code&gt; 正常执行。Ray 模式下，&lt;code&gt;RayHelper.create_workers()&lt;/code&gt; 为每个 GPU rank 创建一个 Ray Actor，每个 Actor 具备：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;独立的 &lt;code&gt;CUDA_VISIBLE_DEVICES&lt;/code&gt;，指向分配的物理 GPU&lt;/li&gt;
&lt;li&gt;用于 torch.distributed 初始化的 &lt;code&gt;MASTER_ADDR&lt;/code&gt; / &lt;code&gt;MASTER_PORT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;正确的 &lt;code&gt;WORLD_SIZE&lt;/code&gt; / &lt;code&gt;RANK&lt;/code&gt; 环境变量&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="remote_function"&gt;&lt;code&gt;@remote_function&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;为方法添加分发、执行和聚合语义：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@infra.remote_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dispatch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;slice_dp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mean&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;train_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;loss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;loss&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;loss&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;三个参数控制分布式行为：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;dispatch&lt;/strong&gt; — 参数如何分配给 worker：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;'all'&lt;/code&gt;：所有 worker 收到相同参数&lt;/li&gt;
&lt;li&gt;&lt;code&gt;'slice'&lt;/code&gt;：参数均匀分片&lt;/li&gt;
&lt;li&gt;&lt;code&gt;'slice_dp'&lt;/code&gt;：按 DeviceMesh 的数据并行维度分片（EP 感知）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;execute&lt;/strong&gt; — 哪些 worker 执行：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;'all'&lt;/code&gt;：所有 worker（默认）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;'first'&lt;/code&gt;：仅第一个 worker&lt;/li&gt;
&lt;li&gt;&lt;code&gt;'peer'&lt;/code&gt;：仅对等 worker（用于跨组通信）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;collect&lt;/strong&gt; — 结果如何聚合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;'none'&lt;/code&gt;：返回原始列表&lt;/li&gt;
&lt;li&gt;&lt;code&gt;'mean'&lt;/code&gt; / &lt;code&gt;'sum'&lt;/code&gt;：数值归约&lt;/li&gt;
&lt;li&gt;&lt;code&gt;'first'&lt;/code&gt;：返回第一个 worker 的结果&lt;/li&gt;
&lt;li&gt;&lt;code&gt;'last_pp'&lt;/code&gt;：返回最后一个流水线并行阶段的结果&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Callable&lt;/code&gt;：自定义聚合函数&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="lazycollect延迟结果聚合"&gt;LazyCollect：延迟结果聚合&lt;/h2&gt;
&lt;p&gt;Ray 模式下的一个关键优化是 &lt;strong&gt;LazyCollect&lt;/strong&gt;。远程调用不会立即阻塞 &lt;code&gt;ray.get()&lt;/code&gt;，而是返回一个 &lt;code&gt;LazyCollect&lt;/code&gt; 可调用对象：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;train_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 返回 LazyCollect（非阻塞）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ... 执行其他工作 ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;actual_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 需要值时才阻塞&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这使得计算和通信可以重叠——驱动端可以同时向多个组（model、sampler、processor）分发任务，仅在真正消费结果时阻塞。&lt;/p&gt;
&lt;p&gt;LazyCollect 还支持 &lt;code&gt;__iter__&lt;/code&gt; 和 &lt;code&gt;__len__&lt;/code&gt;，对大部分消费代码完全透明。&lt;/p&gt;
&lt;h2 id="resourcemanagergpu-分配"&gt;ResourceManager：GPU 分配&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ResourceManager&lt;/code&gt; 处理 GPU 到节点映射的复杂逻辑：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;节点发现&lt;/strong&gt; — 查询 Ray 获取所有活跃节点及 GPU 数量&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PlacementGroup 创建&lt;/strong&gt; — 每节点一个 PG，包含 &lt;code&gt;{GPU: N, CPU: node_cpu//2}&lt;/code&gt; 资源包&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPU 映射&lt;/strong&gt; — 发现每个节点的实际 &lt;code&gt;CUDA_VISIBLE_DEVICES&lt;/code&gt;，正确映射逻辑 rank 到物理 GPU&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多加速器支持&lt;/strong&gt; — 通过 &lt;code&gt;Platform&lt;/code&gt; 抽象支持 GPU、NPU 等多种加速器。使用 &lt;code&gt;RAY_EXPERIMENTAL_NOSET_*&lt;/code&gt; 环境变量防止 Ray 覆盖设备可见性&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CPU Worker 支持&lt;/strong&gt; — 为纯 CPU 进程（数据处理器）创建独立的 PlacementGroup&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="设备拓扑可视化"&gt;设备拓扑可视化&lt;/h2&gt;
&lt;p&gt;Twinkle 提供 &lt;code&gt;get_device_placement()&lt;/code&gt; 渲染训练拓扑：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;╔══════════════════════════════════════════════════════════════════════════════╗
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;║ DEVICE PLACEMENT TOPOLOGY ║
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;╚══════════════════════════════════════════════════════════════════════════════╝
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ◈ DeviceGroup: model │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────────────────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├─ Device Type : cuda │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └─ Ranks : [0, 1, 2, 3] │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌─ DeviceMesh: MyModel │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ Dimensions : dp=4 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ Parallelism: DP=4 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="错误处理与通知"&gt;错误处理与通知&lt;/h2&gt;
&lt;p&gt;远程函数会自动捕获&lt;strong&gt;驱动端调用位置&lt;/strong&gt;，并附加到 worker 内部抛出的异常中：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[twinkle driver caller: train.py:42] CUDA out of memory
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可通过 &lt;code&gt;initialize()&lt;/code&gt; 传入可选的 &lt;code&gt;notifier&lt;/code&gt;（如钉钉 webhook），在任何远程函数失败时发送告警——适用于长时间运行的分布式任务。&lt;/p&gt;
&lt;h2 id="如何选择模式"&gt;如何选择模式&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;使用 Local 模式：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;单机 1-8 张 GPU&lt;/li&gt;
&lt;li&gt;快速原型验证和调试&lt;/li&gt;
&lt;li&gt;简单数据并行训练&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;使用 Ray 模式：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多机集群&lt;/li&gt;
&lt;li&gt;异构资源分配（模型 GPU + 采样器 GPU + CPU 处理器）&lt;/li&gt;
&lt;li&gt;生产级训练，需要容错机制&lt;/li&gt;
&lt;li&gt;多模型部署（训练 + 推理在同一集群）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Twinkle 设计的优雅之处在于——你的训练代码保持不变，只需修改 &lt;code&gt;initialize()&lt;/code&gt; 调用即可切换模式。&lt;/p&gt;</description></item></channel></rss>