From f8cdceb1c097775a167ccbc66eb8370a67c4fc27 Mon Sep 17 00:00:00 2001 From: JingyaHuang Date: Tue, 27 Oct 2026 13:40:07 +0000 Subject: [PATCH 1/8] doc: update neuron doc + improve tpu doc --- docs/source/en/_toctree.yml | 4 +- docs/source/en/optimization/neuron.md | 160 +++++++++++++++++++++----- docs/source/en/optimization/tpu.md | 10 +- 3 files changed, 137 insertions(+), 37 deletions(-) diff --git a/docs/source/en/_toctree.yml b/docs/source/en/_toctree.yml index ab98a5243059..52e7c8556fb6 100644 --- a/docs/source/en/_toctree.yml +++ b/docs/source/en/_toctree.yml @@ -113,9 +113,9 @@ - local: optimization/habana title: Intel Gaudi - local: optimization/neuron - title: AWS Neuron + title: AWS Trainium - local: optimization/tpu - title: TPU + title: Google TPU title: Hardware-specific acceleration - isExpanded: false sections: diff --git a/docs/source/en/optimization/neuron.md b/docs/source/en/optimization/neuron.md index 6a45bd0563bb..31bb9e715003 100644 --- a/docs/source/en/optimization/neuron.md +++ b/docs/source/en/optimization/neuron.md @@ -1,4 +1,4 @@ - -# AWS Neuron +# AWS Trainium -Diffusers functionalities are available on [AWS Inf2 instances](https://aws.amazon.com/ec2/instance-types/inf2/), which are EC2 instances powered by [Neuron machine learning accelerators](https://aws.amazon.com/machine-learning/inferentia/). These instances aim to provide better compute performance (higher throughput, lower latency) with good cost-efficiency, making them good candidates for AWS users to deploy diffusion models to production. +[Trainium](https://aws.amazon.com/machine-learning/trainium/) and +[Inferentia](https://aws.amazon.com/machine-learning/inferentia/) are AWS's machine learning accelerators, both built +on NeuronCores. Diffusers runs on them through TorchNeuron (the `torch_neuronx` package), the PyTorch backend from the +AWS Neuron SDK. It registers a `"neuron"` device, so pipelines run with the same code as on any other device. -[Optimum Neuron](https://huggingface.co/docs/optimum-neuron/en/index) is the interface between Hugging Face libraries and AWS Accelerators, including AWS [Trainium](https://aws.amazon.com/machine-learning/trainium/) and AWS [Inferentia](https://aws.amazon.com/machine-learning/inferentia/). It supports many of the features in Diffusers with similar APIs, so it is easier to learn if you're already familiar with Diffusers. Once you have created an AWS Inf2 instance, install Optimum Neuron. +Two execution modes are available: -```bash -python -m pip install --upgrade-strategy eager optimum[neuronx] +| Mode | How to activate | Notes | +|---|---|---| +| Eager | `pipe.to("neuron")` | Operations dispatched one at a time, asynchronous | +| Compile | `torch.compile(module, backend="neuron")` | Whole-graph compilation, static shapes | + +Follow the [AWS Neuron documentation](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/) to set up the Neuron +SDK and install `torch_neuronx`. Once installed, `import torch` loads it automatically and registers the `"neuron"` +device, so `pipe.to("neuron")` is the only change needed. Add `import torch_neuronx` only if you disabled backend +autoloading with `TORCH_DEVICE_BACKEND_AUTOLOAD=0`. + +Both modes compile kernels to the Neuron executable format (NEFF) the first time they see a new graph, so the first +call is slow and later calls are fast. Compiled NEFFs are cached on disk, by default under `/tmp`, which is cleared on +reboot. Set `TORCH_NEURONX_NEFF_CACHE_DIR` to a persistent directory to keep them. + +## Eager mode + +FLUX.2-klein-4B fits on a single NeuronCore, so move the whole pipeline to the `"neuron"` device. + +```python +import torch + +from diffusers import Flux2KleinPipeline + +pipe = Flux2KleinPipeline.from_pretrained("black-forest-labs/FLUX.2-klein-4B", dtype=torch.bfloat16) +pipe.to("neuron") + +image = pipe( + prompt="a golden retriever surfing a wave, photorealistic", + height=1024, + width=1024, + num_inference_steps=4, +).images[0] + +image.save("output.png") ``` -> [!TIP] -> We provide pre-built [Hugging Face Neuron Deep Learning AMI](https://aws.amazon.com/marketplace/pp/prodview-gr3e6yiscria2) (DLAMI) and Optimum Neuron containers for Amazon SageMaker. It's recommended to correctly set up your environment. +If a model is too large for a single NeuronCore, or you have several cores and want lower latency, shard the models +across cores instead. See the [Tensor parallelism](#tensor-parallelism) section. -The example below demonstrates how to generate images with the Stable Diffusion XL model on an inf2.8xlarge instance (you can switch to cheaper inf2.xlarge instances once the model is compiled). To generate some images, use the [`~optimum.neuron.NeuronStableDiffusionXLPipeline`] class, which is similar to the [`StableDiffusionXLPipeline`] class in Diffusers. +## Compiled mode -Unlike Diffusers, you need to compile models in the pipeline to the Neuron format, `.neuron`. Launch the following command to export the model to the `.neuron` format. +TorchNeuron registers `"neuron"` as a `torch.compile` backend name, so components compile like any other +`torch.compile` target. The first call (warmup) is slow because it compiles; later calls with the same shapes reuse the +compiled graph. -```bash -optimum-cli export neuron --model stabilityai/stable-diffusion-xl-base-1.0 \ - --batch_size 1 \ - --height 1024 `# height in pixels of generated image, eg. 768, 1024` \ - --width 1024 `# width in pixels of generated image, eg. 768, 1024` \ - --num_images_per_prompt 1 `# number of images to generate per prompt, defaults to 1` \ - --auto_cast matmul `# cast only matrix multiplication operations` \ - --auto_cast_type bf16 `# cast operations from FP32 to BF16` \ - sd_neuron_xl/ +> [!IMPORTANT] +> TorchNeuron requires **static shapes**, so pass `dynamic=False`. A new `height` or `width` compiles again for that +> shape, once; shapes already seen are reused. Changing `num_inference_steps` doesn't recompile. + +```python +import torch + +from diffusers import Flux2KleinPipeline + +pipe = Flux2KleinPipeline.from_pretrained("black-forest-labs/FLUX.2-klein-4B", dtype=torch.bfloat16) +pipe.to("neuron") +pipe.transformer.compile(backend="neuron", fullgraph=True, dynamic=False) + +# Warmup — triggers static graph compilation. +pipe(prompt="warmup", height=1024, width=1024, num_inference_steps=4) + +# Later calls with the same shapes reuse the compiled graph. +image = pipe( + prompt="a golden retriever surfing a wave, photorealistic", + height=1024, + width=1024, + num_inference_steps=4, +).images[0] + +image.save("output.png") ``` -Now generate some images with the pre-compiled SDXL model. +For transformers with many identical blocks, compiling only the repeated blocks with +`pipe.transformer.compile_repeated_blocks(backend="neuron", fullgraph=True, dynamic=False)` compiles one block and +reuses it for the others, which cuts the warmup time considerably. + +## Tensor parallelism + +Shard models too large for one NeuronCore across several. The example below shards the Qwen-Image-2.1 transformer with +[`TensorParallelConfig`], passed to the `parallel_config` argument of [`~ModelMixin.from_pretrained`]. Each rank reads +only its own slice of every sharded weight, so the full model is never materialized. For general TP details +(`_tp_plan`, colwise/rowwise), see the [Tensor parallelism](../training/distributed_inference#tensor-parallelism) guide. + +On Neuron, initialize the process group with `backend="neuron"` and build the mesh with `DeviceMesh("neuron", ...)`. +The text encoder runs once per prompt, so it stays on the CPU and only the prompt embeddings are moved to the device. ```python ->>> from optimum.neuron import NeuronStableDiffusionXLPipeline +import torch +import torch.distributed as dist +from torch.distributed.device_mesh import DeviceMesh + +from diffusers import QwenImage21Pipeline, QwenImage21Transformer2DModel, TensorParallelConfig + +dist.init_process_group(backend="neuron") +mesh = DeviceMesh("neuron", list(range(dist.get_world_size()))) +device = torch.neuron.current_device() + +repo_id = "Qwen/Qwen-Image-2.1" +transformer = QwenImage21Transformer2DModel.from_pretrained( + repo_id, subfolder="transformer", dtype=torch.bfloat16, parallel_config=TensorParallelConfig(mesh=mesh) +) +pipe = QwenImage21Pipeline.from_pretrained(repo_id, transformer=transformer, dtype=torch.bfloat16) +pipe.vae.to(device) + +prompt_embeds, _, _ = pipe.encode_prompt( + prompt="a golden retriever surfing a wave, photorealistic", device=torch.device("cpu") +) + +image = pipe( + prompt_embeds=prompt_embeds.to(device), + height=1024, + width=1024, + num_inference_steps=40, + generator=torch.Generator("cpu").manual_seed(0), +).images[0] +if dist.get_rank() == 0: + image.save("output.png") +``` + +> [!IMPORTANT] +> Pass a fixed-seed CPU `generator`. Without it, every rank draws its own random initial latents and the output is +> noise. ->>> stable_diffusion_xl = NeuronStableDiffusionXLPipeline.from_pretrained("sd_neuron_xl/") ->>> prompt = "a pig with wings flying in floating US dollar banknotes in the air, skyscrapers behind, warm color palette, muted colors, detailed, 8k" ->>> image = stable_diffusion_xl(prompt).images[0] +Launch one process per NeuronCore. Set `--nproc_per_node` to the number of NeuronCores you want to shard across. + +```bash +torchrun --nproc_per_node=8 qwenimage21_tp.py ``` -peggy generated by sdxl on inf2 +To compile the sharded transformer, call +`pipe.transformer.compile_repeated_blocks(backend="neuron", fullgraph=True, dynamic=False)` after loading it. -Feel free to check out more guides and examples on different use cases from the Optimum Neuron [documentation](https://huggingface.co/docs/optimum-neuron/en/inference_tutorials/stable_diffusion#generate-images-with-stable-diffusion-models-on-aws-inferentia)! +> [!TIP] +> [Optimum Neuron](https://huggingface.co/docs/optimum-neuron/en/index) offers ahead-of-time exported Neuron pipelines, +> such as [`~optimum.neuron.NeuronStableDiffusionXLPipeline`], for deployment on Inferentia and Trainium. diff --git a/docs/source/en/optimization/tpu.md b/docs/source/en/optimization/tpu.md index e5f75480f82f..8b7fce9d88c3 100644 --- a/docs/source/en/optimization/tpu.md +++ b/docs/source/en/optimization/tpu.md @@ -10,16 +10,18 @@ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express o specific language governing permissions and limitations under the License. --> -# TorchTPU +# Google TPU -[TorchTPU](https://github.com/google-pytorch/torch_tpu/) is a PyTorch backend for Google's Tensor Processing Units -(TPUs), which lets you run Diffusers pipelines on Cloud TPUs (v6e, v7x) with minimal code changes. +Tensor Processing Units (TPUs) are Google's machine learning accelerators, available as Cloud TPUs (v6e, v7x). +Diffusers runs on them through [TorchTPU](https://github.com/google-pytorch/torch_tpu/), the PyTorch backend for TPUs, +with minimal code changes. -Two execution modes are available: +Three execution modes are available: | Mode | Constant | How to activate | Notes | |---|---|---|---| | Strict eager (default) | `EagerMode.DEFER_NEVER` | `pipe.to("tpu")` | Operations dispatched one at a time, asynchronous | +| Optimized eager | `EagerMode.DEFER_AND_FUSE` | `TORCH_TPU_DEFER_AND_FUSE=1` | Operations deferred and fused into larger graphs; faster than strict eager, longer compile | | Compile | — | `torch.compile(module, backend="tpu")` | AOT compilation with `TpuBackend` | Follow the [TorchTPU installation guide](https://github.com/google-pytorch/torch_tpu/). Once installed, `import torch` From 33d42fa7d93f7f33d5861aaa93b4120837b8febf Mon Sep 17 00:00:00 2001 From: JingyaHuang Date: Tue, 27 Oct 2026 15:33:12 +0000 Subject: [PATCH 2/8] docs: improve doc --- docs/source/en/optimization/neuron.md | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/docs/source/en/optimization/neuron.md b/docs/source/en/optimization/neuron.md index 31bb9e715003..6d7db663e199 100644 --- a/docs/source/en/optimization/neuron.md +++ b/docs/source/en/optimization/neuron.md @@ -14,8 +14,9 @@ specific language governing permissions and limitations under the License. [Trainium](https://aws.amazon.com/machine-learning/trainium/) and [Inferentia](https://aws.amazon.com/machine-learning/inferentia/) are AWS's machine learning accelerators, both built -on NeuronCores. Diffusers runs on them through TorchNeuron (the `torch_neuronx` package), the PyTorch backend from the -AWS Neuron SDK. It registers a `"neuron"` device, so pipelines run with the same code as on any other device. +on NeuronCores. Diffusers runs on them through [TorchNeuron](https://github.com/aws-neuron/torch-neuronx) (the +`torch_neuronx` package), the PyTorch backend from the AWS Neuron SDK. It registers a `"neuron"` device, so pipelines +run with the same code as on any other device. Two execution modes are available: @@ -138,19 +139,8 @@ if dist.get_rank() == 0: image.save("output.png") ``` -> [!IMPORTANT] -> Pass a fixed-seed CPU `generator`. Without it, every rank draws its own random initial latents and the output is -> noise. - Launch one process per NeuronCore. Set `--nproc_per_node` to the number of NeuronCores you want to shard across. ```bash torchrun --nproc_per_node=8 qwenimage21_tp.py ``` - -To compile the sharded transformer, call -`pipe.transformer.compile_repeated_blocks(backend="neuron", fullgraph=True, dynamic=False)` after loading it. - -> [!TIP] -> [Optimum Neuron](https://huggingface.co/docs/optimum-neuron/en/index) offers ahead-of-time exported Neuron pipelines, -> such as [`~optimum.neuron.NeuronStableDiffusionXLPipeline`], for deployment on Inferentia and Trainium. From b59b9c8b3e16a7a8f338b897334ebc00d5b7c6d9 Mon Sep 17 00:00:00 2001 From: Jingya HUANG <44135271+JingyaHuang@users.noreply.github.com> Date: Wed, 28 Oct 2026 11:58:20 +0100 Subject: [PATCH 3/8] Update docs/source/en/optimization/neuron.md Co-authored-by: Steven Liu <59462357+stevhliu@users.noreply.github.com> --- docs/source/en/optimization/neuron.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/source/en/optimization/neuron.md b/docs/source/en/optimization/neuron.md index 6d7db663e199..5181dd4d22e9 100644 --- a/docs/source/en/optimization/neuron.md +++ b/docs/source/en/optimization/neuron.md @@ -12,11 +12,7 @@ specific language governing permissions and limitations under the License. # AWS Trainium -[Trainium](https://aws.amazon.com/machine-learning/trainium/) and -[Inferentia](https://aws.amazon.com/machine-learning/inferentia/) are AWS's machine learning accelerators, both built -on NeuronCores. Diffusers runs on them through [TorchNeuron](https://github.com/aws-neuron/torch-neuronx) (the -`torch_neuronx` package), the PyTorch backend from the AWS Neuron SDK. It registers a `"neuron"` device, so pipelines -run with the same code as on any other device. +[TorchNeuron](https://github.com/aws-neuron/torch-neuronx) is the native PyTorch backend for Trainium2 and Trainium3. Diffusers runs on these instances through the `torch_neuronx` package, which registers a `"neuron"` device, so pipelines run with the same code as on any other device. Two execution modes are available: From 192a3dbfc51329d45c4e01abf7a5f927306ed2ef Mon Sep 17 00:00:00 2001 From: Jingya HUANG <44135271+JingyaHuang@users.noreply.github.com> Date: Wed, 28 Oct 2026 11:58:45 +0100 Subject: [PATCH 4/8] Update docs/source/en/optimization/neuron.md Co-authored-by: Steven Liu <59462357+stevhliu@users.noreply.github.com> --- docs/source/en/optimization/neuron.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/source/en/optimization/neuron.md b/docs/source/en/optimization/neuron.md index 5181dd4d22e9..5fa3994e1d89 100644 --- a/docs/source/en/optimization/neuron.md +++ b/docs/source/en/optimization/neuron.md @@ -58,8 +58,7 @@ across cores instead. See the [Tensor parallelism](#tensor-parallelism) section. ## Compiled mode TorchNeuron registers `"neuron"` as a `torch.compile` backend name, so components compile like any other -`torch.compile` target. The first call (warmup) is slow because it compiles; later calls with the same shapes reuse the -compiled graph. +`torch.compile` target. The first call (warmup) is slow because it compiles; later calls with the same shapes reuse the compiled graph. > [!IMPORTANT] > TorchNeuron requires **static shapes**, so pass `dynamic=False`. A new `height` or `width` compiles again for that From eb7b9073475a4b049d3290f410f763ee61913c74 Mon Sep 17 00:00:00 2001 From: Jingya HUANG <44135271+JingyaHuang@users.noreply.github.com> Date: Wed, 28 Oct 2026 12:00:11 +0100 Subject: [PATCH 5/8] Update docs/source/en/optimization/neuron.md Co-authored-by: Steven Liu <59462357+stevhliu@users.noreply.github.com> --- docs/source/en/optimization/neuron.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/source/en/optimization/neuron.md b/docs/source/en/optimization/neuron.md index 5fa3994e1d89..40cff564a9c3 100644 --- a/docs/source/en/optimization/neuron.md +++ b/docs/source/en/optimization/neuron.md @@ -26,9 +26,7 @@ SDK and install `torch_neuronx`. Once installed, `import torch` loads it automat device, so `pipe.to("neuron")` is the only change needed. Add `import torch_neuronx` only if you disabled backend autoloading with `TORCH_DEVICE_BACKEND_AUTOLOAD=0`. -Both modes compile kernels to the Neuron executable format (NEFF) the first time they see a new graph, so the first -call is slow and later calls are fast. Compiled NEFFs are cached on disk, by default under `/tmp`, which is cleared on -reboot. Set `TORCH_NEURONX_NEFF_CACHE_DIR` to a persistent directory to keep them. +In eager mode, each operation compiles the first time it runs. In compiled mode, the first call compiles the graph. Both modes cache the compiled Neuron executable format (NEFF) under `tmp/neff_cache` by default, and that directory is cleared on reboot. Set `TORCH_NEURONX_NEFF_CACHE_DIR` to a persistent directory to keep the cache. ## Eager mode From 543a5988f9b2564a1e65f2b1dacc8d3bdf5dc198 Mon Sep 17 00:00:00 2001 From: Jingya HUANG <44135271+JingyaHuang@users.noreply.github.com> Date: Wed, 28 Oct 2026 12:00:29 +0100 Subject: [PATCH 6/8] Update docs/source/en/optimization/neuron.md Co-authored-by: Steven Liu <59462357+stevhliu@users.noreply.github.com> --- docs/source/en/optimization/neuron.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/source/en/optimization/neuron.md b/docs/source/en/optimization/neuron.md index 40cff564a9c3..425fc2523eff 100644 --- a/docs/source/en/optimization/neuron.md +++ b/docs/source/en/optimization/neuron.md @@ -59,8 +59,7 @@ TorchNeuron registers `"neuron"` as a `torch.compile` backend name, so component `torch.compile` target. The first call (warmup) is slow because it compiles; later calls with the same shapes reuse the compiled graph. > [!IMPORTANT] -> TorchNeuron requires **static shapes**, so pass `dynamic=False`. A new `height` or `width` compiles again for that -> shape, once; shapes already seen are reused. Changing `num_inference_steps` doesn't recompile. +> TorchNeuron requires *static shapes*, so pass `dynamic=False`. A new `height` or `width` compiles again for that shape. Shapes already seen are reused. Changing `num_inference_steps` doesn't recompile. ```python import torch From c85de92553819fbb8b8fa870beee96f0e205971b Mon Sep 17 00:00:00 2001 From: Jingya HUANG <44135271+JingyaHuang@users.noreply.github.com> Date: Wed, 28 Oct 2026 12:00:39 +0100 Subject: [PATCH 7/8] Update docs/source/en/optimization/neuron.md Co-authored-by: Steven Liu <59462357+stevhliu@users.noreply.github.com> --- docs/source/en/optimization/neuron.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/source/en/optimization/neuron.md b/docs/source/en/optimization/neuron.md index 425fc2523eff..748199d4ec54 100644 --- a/docs/source/en/optimization/neuron.md +++ b/docs/source/en/optimization/neuron.md @@ -84,9 +84,7 @@ image = pipe( image.save("output.png") ``` -For transformers with many identical blocks, compiling only the repeated blocks with -`pipe.transformer.compile_repeated_blocks(backend="neuron", fullgraph=True, dynamic=False)` compiles one block and -reuses it for the others, which cuts the warmup time considerably. +For transformers with repeated blocks, use `compile_repeated_blocks(...)` to compile those blocks individually. This block is reused and reduces compile time considerably. ## Tensor parallelism From e6c9ebe42ff08bc8aca41a197a853c5b67be76b2 Mon Sep 17 00:00:00 2001 From: JingyaHuang Date: Wed, 28 Oct 2026 11:38:07 +0000 Subject: [PATCH 8/8] doc: apply suggestion --- docs/source/en/optimization/neuron.md | 37 +++++++-------------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/docs/source/en/optimization/neuron.md b/docs/source/en/optimization/neuron.md index 748199d4ec54..a45d84e8923a 100644 --- a/docs/source/en/optimization/neuron.md +++ b/docs/source/en/optimization/neuron.md @@ -88,49 +88,30 @@ For transformers with repeated blocks, use `compile_repeated_blocks(...)` to com ## Tensor parallelism -Shard models too large for one NeuronCore across several. The example below shards the Qwen-Image-2.1 transformer with -[`TensorParallelConfig`], passed to the `parallel_config` argument of [`~ModelMixin.from_pretrained`]. Each rank reads -only its own slice of every sharded weight, so the full model is never materialized. For general TP details -(`_tp_plan`, colwise/rowwise), see the [Tensor parallelism](../training/distributed_inference#tensor-parallelism) guide. +Follow the [Tensor parallelism](../training/distributed_inference#tensor-parallelism) guide for model loading, +sharding plans, and limitations. To adapt its example for Neuron, replace the CUDA process-group and device setup +with the following. On Neuron, initialize the process group with `backend="neuron"` and build the mesh with `DeviceMesh("neuron", ...)`. -The text encoder runs once per prompt, so it stays on the CPU and only the prompt embeddings are moved to the device. ```python import torch import torch.distributed as dist from torch.distributed.device_mesh import DeviceMesh -from diffusers import QwenImage21Pipeline, QwenImage21Transformer2DModel, TensorParallelConfig +from diffusers import TensorParallelConfig dist.init_process_group(backend="neuron") mesh = DeviceMesh("neuron", list(range(dist.get_world_size()))) device = torch.neuron.current_device() - -repo_id = "Qwen/Qwen-Image-2.1" -transformer = QwenImage21Transformer2DModel.from_pretrained( - repo_id, subfolder="transformer", dtype=torch.bfloat16, parallel_config=TensorParallelConfig(mesh=mesh) -) -pipe = QwenImage21Pipeline.from_pretrained(repo_id, transformer=transformer, dtype=torch.bfloat16) -pipe.vae.to(device) - -prompt_embeds, _, _ = pipe.encode_prompt( - prompt="a golden retriever surfing a wave, photorealistic", device=torch.device("cpu") -) - -image = pipe( - prompt_embeds=prompt_embeds.to(device), - height=1024, - width=1024, - num_inference_steps=40, - generator=torch.Generator("cpu").manual_seed(0), -).images[0] -if dist.get_rank() == 0: - image.save("output.png") +parallel_config = TensorParallelConfig(mesh=mesh) ``` +Pass this `parallel_config` to the transformer's [`~ModelMixin.from_pretrained`] and use `device` for the remaining +pipeline components. + Launch one process per NeuronCore. Set `--nproc_per_node` to the number of NeuronCores you want to shard across. ```bash -torchrun --nproc_per_node=8 qwenimage21_tp.py +torchrun --nproc_per_node=8 tensor_parallel_neuron.py ```