Close Menu
MyAppsPlus

    Subscribe to Updates

    Get the latest creative news from FooBar about art, design and business.

    What's Hot

    The UK is investing $134 million into an AI Biosecurity Lab

    October 24, 2026

    Samsung’s archrival wants to spread 100 special CPUs in every SSD controller ahead of PCIe 8.0, High Bandwidth Flash onslaught

    October 24, 2026

    AI is unlikely to take these 10 jobs anytime soon

    October 24, 2026
    Facebook X (Twitter) Instagram
    Facebook X (Twitter) Instagram
    MyAppsPlusMyAppsPlus
    Saturday, October 24
    • Home
    • Breaking Tech
    • Apps & Software
    • AI & Automation
    • Android
    • iPhone & iOS
    • More
      • Reviews
      • How-To Guides
      • Deals & Discounts
      • Shop
    MyAppsPlus
    Home»AI & Automation»Train Qwen3 on AWS Trainium with torchtitan
    AI & Automation

    Train Qwen3 on AWS Trainium with torchtitan

    myappsplusBy myappsplusOctober 24, 20260011 Mins Read
    Share Facebook Twitter Pinterest Copy Link LinkedIn Tumblr Email Telegram WhatsApp
    Follow Us
    Google News Flipboard
    Train Qwen3 on AWS Trainium with torchtitan
    Share
    Facebook Twitter LinkedIn Pinterest Email Copy Link

    Using torchtitan on AWS Trainium means using it the way you always have. TorchNeuron registers Trainium as a native PyTorch device, which lets torchtitan use it through standard PyTorch interfaces. You can use these configurations to pre-train from random initialization or fine-tune published weights. You can also customize the model implementation and kernels for your workload. In this post, you train Qwen3 three ways on a single trn2.48xlarge.

    The first method uses Transformers v5 as a modeling backend in torchtitan. It runs Hub models through AutoModelForCausalLM and reads and writes published safetensors directly. The second method switches to torchtitan’s native Qwen3 by changing config.model_spec. The third adds Neuron Kernel Interface (NKI) mixture-of-experts (MoE) kernels from the torchtitan-neuron recipes and then uses torchtitan’s override registry to attach your own kernel. All three configurations use the same torchrun launch pattern and config structure.

    Prerequisites

    To follow this walkthrough, use a single trn2.48xlarge with either the AWS Deep Learning AMI for Neuron or a Neuron PyTorch training container. Both environments provide the Neuron driver, runtime, and compiler required to train on Trainium.

    Before you install torchtitan-neuron, check whether your environment already includes it. The following command prints the installed version and package path:

    python3 -c "import torchtitan, torchtitan_neuron; print(torchtitan.__version__, torchtitan_neuron.__file__)"

    This walkthrough uses the versions in the following table. To reproduce the examples, pin these versions. The Transformers v5 integration and Trainium-specific override modules can change between torchtitan releases.

    Component Version
    Instance trn2.48xlarge, 16 Trainium2 accelerators, 128 physical NeuronCores
    Logical NeuronCores 64 at LNC=2
    torch, torch_neuronx 2.14.0, 2.14.3
    transformers 5.16.0
    torchtitan-neuron release-2.33 (0.2.2+neuron.1)

    When torch_neuronx is installed, TorchNeuron registers Trainium as the neuron device and torchtitan detects it at startup. In eager mode, Neuron compiles operations as they execute. With torch.compile, Neuron compiles the captured graph. This same launch pattern works across all three configurations.

    For the versions used in this walkthrough, install torchtitan-neuron and torchtitan’s remaining dependencies with --no-deps to preserve the Neuron build of torch:

    git clone https://github.com/aws-neuron/torchtitan-neuron
    cd torchtitan-neuron
    pip install -r requirements.txt

    Before you start training, get the Qwen3 model artifacts from Hugging Face Hub. Store them in a local directory that you can pass to the training config:

    hf download Qwen/Qwen3-4B-Instruct-2507 
      --local-dir "$PWD/assets/hf/Qwen3-4B-Instruct-2507"

    Each training configuration is a Python config function. The three examples start from a base config that you update for each step.

    Train with Hugging Face Transformers v5

    In the first configuration, Transformers v5 builds Qwen3 through AutoModelForCausalLM. The Hub model definition supplies the implementation used for the forward and backward passes. You select the model by setting its Hub ID in the config.

    Start with transformers_modeling_backend_full(). It leaves the fields that map to Hugging Face configuration keys unset, so AutoConfig.from_pretrained() loads the model architecture from the Hub.

    Create neuron_qwen3.py in the torchtitan-neuron repository root, where you run the training command. Add the imports, model artifact path, and base config:

    import os
    from torchtitan.experiments.transformers_modeling_backend.config_registry import (
        transformers_modeling_backend_full,
    )
    from torchtitan.experiments.transformers_modeling_backend.configs import (
        TransformersBackendConfig,
    )
    
    ASSETS = os.path.abspath("./assets/hf/Qwen3-4B-Instruct-2507")
    
    def v5_qwen3_4b() -> TransformersBackendConfig:
        config = transformers_modeling_backend_full()
        config.hf_model = "Qwen/Qwen3-4B-Instruct-2507"
        config.hf_assets_path = ASSETS
        config.dataloader.dataset = "c4_test"
        config.training.steps = 10
        config.training.local_batch_size = 1
        config.parallelism.data_parallel_shard_degree = -1
        return config
    torchrun --nproc_per_node=64 --rdzv_backend c10d --rdzv_endpoint localhost:0 
      --local-ranks-filter 0 --role rank --tee 3 
      -m torchtitan.train --module neuron_qwen3 --config v5_qwen3_4b

    This command launches 64 training processes, one for each logical NeuronCore. --module neuron_qwen3 imports the local config module. --config v5_qwen3_4b selects the configuration function. The data parallel setting shards the model across all 64 ranks.

    To fine-tune from published weights, enable checkpoint loading and point initial_load_path to ASSETS. The state-dictionary adapter adjusts the leading model. prefix and handles tied embeddings. It saves the final checkpoint as Hugging Face safetensors.

    def v5_qwen3_4b_finetune() -> TransformersBackendConfig:
        config = v5_qwen3_4b()
        config.checkpoint.enable = True
        config.checkpoint.folder = "checkpoint_qwen3_4b_ft"
        config.checkpoint.initial_load_path = ASSETS # absolute path required
        config.checkpoint.initial_load_in_hf = True
        config.checkpoint.initial_load_model_only = True
        config.checkpoint.last_save_in_hf = True
        config.checkpoint.last_save_model_only = True
        return config

    Use the first training-step loss as a quick check that torchtitan loaded the published weights. For Qwen/Qwen3-4B-Instruct-2507, the verified run produced a step 1 loss of 6.54 from published weights and 12.43 from random initialization.

    After training, load the exported checkpoint with AutoModelForCausalLM and load_state_dict. A successful round trip reports no missing or unexpected keys other than lm_head.weight, which Qwen3-4B ties to the token embeddings. This confirms that the files remain a standard Hugging Face checkpoint.

    Figure 1: The published checkpoint starts with a loss of 6.54, and the exported weights load without missing or unexpected keys

    Train with torchtitan’s native models

    In the second configuration, torchtitan builds its native Qwen3Model. Add the native Qwen3 imports and config function to neuron_qwen3.py:

    This example starts from qwen3_32b() because the tested torchtitan build does not provide a generic qwen3_4b() config builder. The next line replaces the 32B model specification with the 4B specification. The remaining fields reproduce the tested run.

    from torchtitan.models.qwen3 import model_registry
    from torchtitan.models.qwen3.config_registry import qwen3_32b
    from torchtitan.trainer import Trainer
    
    def native_qwen3_4b() -> Trainer.Config:
        config = qwen3_32b()
        config.model_spec = model_registry("4B", attn_backend="sdpa")
        config.hf_assets_path = ASSETS
        config.dataloader.dataset = "c4_test"
        config.training.steps = 10
        config.training.local_batch_size = 1
        config.training.global_batch_size = 64
        config.parallelism.data_parallel_shard_degree = -1
        return config
    torchrun --nproc_per_node=64 --rdzv_backend c10d --rdzv_endpoint localhost:0 
      --local-ranks-filter 0 --role rank --tee 3 
      -m torchtitan.train --module neuron_qwen3 --config native_qwen3_4b

    config.model_spec selects the model class and defines how torchtitan shards the model and maps its checkpoint keys. Here, model_registry("4B", attn_backend="sdpa") selects torchtitan’s native Qwen3 implementation with scaled dot product attention (SDPA).

    Add NKI kernels for mixture of experts

    In the third configuration, torchtitan runs mixture-of-experts layers with kernels written in NKI, the Neuron kernel language. Add the required imports and Qwen3 MoE config function to neuron_qwen3.py:

    from torchtitan.config import CompileConfig
    from torchtitan_neuron.models.qwen3.config_registry import qwen3_nki_moe_config
    
    def nki_qwen3_30b_a3b() -> Trainer.Config:
        config = qwen3_nki_moe_config(
            "30B-A3B",
            compile_config=CompileConfig(enable=False, backend="neuron"),
            n_layers=4,
            num_experts=64,
            top_k=4,
        )
        config.hf_assets_path = ASSETS
        return config
    torchrun --nproc_per_node=64 --rdzv_backend c10d --rdzv_endpoint localhost:0 
      --local-ranks-filter 0 --role rank --tee 3 
      -m torchtitan.train --module neuron_qwen3 --config nki_qwen3_30b_a3b

    This configuration uses data parallel sharding across 64 ranks with a tensor parallel degree of 1. It does not use expert parallelism. num_experts=64 sets the number of experts in the model, not the expert parallel degree.

    Setting CompileConfig(enable=False) runs this example in eager mode. TorchNeuron supports registered NKI operators in both eager execution and torch.compile.

    In the torchtitan build used for this walkthrough, qwen3_nki_moe_config() replaces the MoE block with the NKI grouped-experts implementation. It also selects SDPA and the gather-free rotary embedding. When you enable torch.compile, add "grad_clip" to CompileConfig.components to compile gradient-norm clipping.

    NKI kernels enter training as PyTorch operators. wrap_nki makes an NKI kernel callable from PyTorch, and nki_op registers the operator. register_autograd attaches its backward pass using routing metadata saved during the forward pass.

    The example reduces Qwen3-30B-A3B to 4 layers and 64 experts so it fits on one trn2.48xlarge. It routes each token to 4 experts with top_k=4.

    Attach your own NKI kernel

    In some cases, you might want to optimize an operation for the tensor shapes in your model. A specialized kernel can tailor its tiling and data movement to those shapes. It can also replace a performance-critical sequence of PyTorch operations with one optimized operator. You can write the kernel yourself or start with one from nkilib. This example uses rope_hf from nkilib.core.embeddings, which expects the Hugging Face tensor layout and supports its own backward mode. This example demonstrates kernel registration and autograd integration, not a performance improvement.

    Create my_neuron_kernels.py in the repository root, where you launch training. torchtitan stores query and key as [batch, seq, heads, head_dim], whereas rope_hf expects [batch, heads, seq, head_dim]. Convert the layout inside the operator and allocate the output tensors with torch.empty_like():

    import torch
    from nkilib.core.embeddings.rope_hf import rope_hf
    from torch_neuronx import nki_op
    from torch_neuronx.nki_hop import wrap_nki
    from torch_neuronx.utils import get_logical_neuron_cores
    
    LNC = (int(get_logical_neuron_cores()),)
    wrapped_rope = wrap_nki(rope_hf)
    
    @nki_op("my_kernels::rope_fwd")
    def rope_fwd(query, key, rope_cache):
        q = query.permute(0, 2, 1, 3).contiguous()
        k = key.permute(0, 2, 1, 3).contiguous()
        cache = rope_cache.reshape(-1, rope_cache.shape[-1])
        q_out, k_out = wrapped_rope[LNC](
            q,
            k,
            torch.empty_like(q),
            torch.empty_like(k),
            rope_cache=cache,
        )
        return (
            q_out.permute(0, 2, 1, 3).contiguous(),
            k_out.permute(0, 2, 1, 3).contiguous(),
        )

    rope_hf computes gradients when you call it with backward=True. Register a second operator for that mode. Save the rotary cache during the forward pass so the backward pass can reuse it. Return None for the cache gradient because the cache is not differentiable.

    @nki_op("my_kernels::rope_bwd")
    def rope_bwd(grad_query, grad_key, rope_cache):
        gq = grad_query.permute(0, 2, 1, 3).contiguous()
        gk = grad_key.permute(0, 2, 1, 3).contiguous()
        cache = rope_cache.reshape(-1, rope_cache.shape[-1])
        out_q, out_k = wrapped_rope[LNC](
            gq,
            gk,
            torch.empty_like(gq),
            torch.empty_like(gk),
            rope_cache=cache,
            backward=True,
        )
        return (
            out_q.permute(0, 2, 1, 3).contiguous(),
            out_k.permute(0, 2, 1, 3).contiguous(),
        )
    def _setup_context(ctx, inputs, output):
        ctx.save_for_backward(inputs[2])
    
    def _backward(ctx, grad_query, grad_key):
        (rope_cache,) = ctx.saved_tensors
        grad_q, grad_k = rope_bwd(grad_query, grad_key, rope_cache)
        return grad_q, grad_k, None
    
    rope_fwd.register_autograd(_backward, setup_context=_setup_context)

    Because rope_hf requires a supported sequence length, validate that constraint before calling the kernel. Subclass CosSinRoPE and call rope_fwd from apply_rotary_emb:

    from dataclasses import dataclass
    from torchtitan.config import derive, override
    from torchtitan.models.common.rope import CosSinRoPE
    
    class NKIRoPE(CosSinRoPE):
        @dataclass(kw_only=True, slots=True)
        class Config(CosSinRoPE.Config):
            pass
    
        @staticmethod
        def apply_rotary_emb(query, key, rope_cache):
            stride = 128 * LNC[0]
            if query.shape[1] % stride:
                raise ValueError(
                    f"rope_hf requires a sequence length that is a multiple of "
                    f"128 * LNC={stride}, got {query.shape[1]}"
                )
            q_out, k_out = rope_fwd(query, key, rope_cache)
            return q_out.type_as(query), k_out.type_as(key)

    Register NKIRoPE as the replacement for CosSinRoPE. derive() copies the shared configuration fields into the replacement config:

    @override(
        "nki_rope",
        target=CosSinRoPE.Config,
        exact=True,
        description="nkilib rope_hf kernel in place of the PyTorch rotation",
    )
    def _nki_rope(cfg: CosSinRoPE.Config) -> NKIRoPE.Config:
        return derive(cfg, NKIRoPE.Config)

    To load the custom override, pass its module name to --override.imports. torchtitan imports the registry entry before it builds the model:

    torchrun --nproc_per_node=64 --rdzv_backend c10d --rdzv_endpoint localhost:0 
      --local-ranks-filter 0 --role rank --tee 3 
      -m torchtitan.train --module neuron_qwen3 --config native_qwen3_4b 
      --override.imports my_neuron_kernels

    Before training starts, torchtitan logs each config node that the override replaces. Confirm that the output contains one nki_rope entry for each Qwen3 layer:

    [Override] nki_rope: model_spec.model.layers.0.attention.rope CosSinRoPEConfig -> NKIRoPE.Config
    [Override] nki_rope: model_spec.model.layers.1.attention.rope CosSinRoPEConfig -> NKIRoPE.Config

    Set the sequence length to a multiple of 128 * LNC, which is 256 when LNC is 2. Reshape the rotary cache to [seq, head_dim * 2], with cosine values in the first half and sine values in the second. The kernel validates these constraints before training begins.

    For a complete torchtitan example, see torchtitan_neuron/models/gpt_oss/nki_attention.py. It connects nkilib flash-attention kernels through the same operator and override mechanisms. It also handles DTensor inputs for tensor parallelism.

    Before you train with a custom kernel, compare its outputs with the implementation it replaces. In the numerical test with float32 inputs, rope_hf and torchtitan’s PyTorch rotary embedding produced a maximum absolute difference of 0.0 for both query and key.

    When you register multiple overrides, limit each one to the intended module instances with fqns. For example, fqns=["layers.1[0-9].attention.rope"] targets the rotary embedding in layers 10 through 19. torchtitan stops when two overrides claim the same node and warns when an override matches no nodes.

    Review the training output

    At startup, confirm that torchtitan reports 64 ranks and the expected model. The first step includes compilation and takes longer than later steps. Each training step reports the loss, gradient norm, high-bandwidth memory (HBM) usage, throughput, and model FLOPs utilization (MFU). For the checkpoint run, confirm that the first-step loss is near 6.54. For the custom kernel run, confirm that the nki_rope override appears once for each Qwen3 layer.

    Scale across the instance

    The same parallelism settings apply to the Transformers and native model configurations. A trn2.48xlarge exposes 64 logical NeuronCores at LNC=2. Set data_parallel_shard_degree = -1 to shard the model parameters, gradients, and optimizer state across every rank that torchrun starts.

    Set config.parallelism.tensor_parallel_degree to shard each layer’s weights across a group of ranks. Each rank computes a slice of every matrix multiplication. With sequence parallelism enabled by default, normalization layers run on activations sharded along the sequence dimension. torchtitan combines tensor parallelism with Fully Sharded Data Parallel (FSDP) on a multidimensional DeviceMesh.

    Watch per-rank HBM as you increase the model size, sequence length, or local batch size. These values determine how much memory each rank requires.

    Clean up

    If you want to keep your checkpoints, copy them to persistent storage before you clean up. If you plan to reuse the instance, stop it. When you no longer need the instance, terminate it.

    Conclusion

    AWS Trainium works as a supported torchtitan device across all three configurations in this walkthrough. You can train Qwen3 through Hugging Face Transformers v5 and load or save published safetensors directly. You can also train with torchtitan’s native Qwen3 implementation by setting config.model_spec. For mixture-of-experts models, use the torchtitan-neuron NKI recipes. For custom kernels, use the override registry to attach NKI operators through the same launch flow.

    For setup guidance, see the AWS Neuron documentation. For current

    Qwen3 torchtitan train Trainium
    Follow on Google News Follow on Flipboard
    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email Copy Link
    myappsplus
    • Website

    Related Posts

    The Pentagon’s guidelines for “responsible AI” aren’t always followed, report shows

    October 24, 2026

    Why Socceroo Cristian Volpato is the latest footballer to license his AI clone

    October 24, 2026

    Tether Enlists 15 Companies Including Bitmain for AI-Driven Bitcoin Mining Automation Infrastructure

    October 24, 2026
    Add A Comment
    Leave A Reply Cancel Reply

    Top Posts

    Cathay Pacific tests Google AI that dramatically cuts airplane contrails — tiny altitude shifts slash environmental impact by 40% in early trials

    September 8, 2026137 Views

    Drone swarm tech valued by both defense and civilian sectors, industry platform says

    September 8, 202615 Views

    Keep running out of mobile data? This new unlimited plan gets you up to 80Mbps 5G speeds for just AU$50/m

    October 8, 202614 Views
    Latest Reviews

    WD’s 6TB Elements portable hard drive drops to $260 for simple plug-and-play backups

    myappsplusSeptember 1, 2026

    Job postings show early signs of AI automation impact

    myappsplusSeptember 1, 2026

    iPhone 18 Pro Colors Apparently Include Black, But Skip Silver

    myappsplusSeptember 1, 2026
    Stay In Touch
    • Facebook
    • YouTube
    • TikTok
    • WhatsApp
    • Twitter
    • Instagram

    Subscribe to Updates

    Get the latest tech news from FooBar about tech, design and biz.

    Most Popular

    WD’s 6TB Elements portable hard drive drops to $260 for simple plug-and-play backups

    September 1, 20260 Views

    iPhone 18 Pro Colors Apparently Include Black, But Skip Silver

    September 1, 20260 Views

    The new Amazfit Cheetah 2 Pro falls to $399.99 in its first Amazon discount

    September 1, 20260 Views
    Our Picks

    The UK is investing $134 million into an AI Biosecurity Lab

    October 24, 2026

    Samsung’s archrival wants to spread 100 special CPUs in every SSD controller ahead of PCIe 8.0, High Bandwidth Flash onslaught

    October 24, 2026

    AI is unlikely to take these 10 jobs anytime soon

    October 24, 2026

    Subscribe to Updates

    Subscribe to our newsletter and get the latest tech news, app updates, AI trends, smartphone reviews, and exclusive deals delivered straight to your inbox.

    Facebook X (Twitter) Instagram Pinterest
    • About Us
    • Get In Touch
    • Disclaimer
    • Privacy Policy
    • Terms & Conditions
    © 2026 MyAppsPlus. All Rights Reserved.

    Type above and press Enter to search. Press Esc to cancel.