- Training a byte-pair encoding (BPE) tokenizer on FineWeb-Edu.
- Pretraining a base transformer model.
- Midtraining on curated tasks.
- Supervised fine-tuning for conversational alignment.
- Deploying a FastAPI web server with a chat interface.
Requirements
Before you begin, make sure you have:- A Together AI account with access to GPU clusters.
- The admin role on the cluster’s project. Only project admins can download the cluster kubeconfig in Step 7.
- The Together CLI installed on your local machine.
kubectlinstalled on your local machine (installation guide).- Basic familiarity with SSH and the command line.
Step 1: Create a cluster
Create an 8xH100 cluster to train nanochat:- Sign in to the Together AI console.
- Select GPU Clusters in the navigation sidebar.
- Select Create cluster.
- Select On-demand capacity.
- Select the H100-SXM GPU type card, then set Select GPU Count to 8.
- Choose your preferred Region.
- Under Cluster Details, enter a Cluster name (for example,
nanochat-training) and set Orchestration to Slurm. - Under Storage, open Storage Selection, select + Create new storage, and set Size (TiB) to at least 1.
- Select Create Cluster, then select Confirm & Create.
Step 2: SSH into the cluster
In the console, open your cluster’s details page and select Copy head node SSH command, then run the copied command in your terminal. With key-based SSH, the command connects through a jump host:Step 3: Clone nanochat and set up the environment
In the login node shell, clone the nanochat repository and set up your shell environment:Step 4: Allocate GPUs
In the login node shell, start ascreen session so training keeps running if your SSH connection drops. Inside it, use Slurm’s srun command to allocate 8 GPUs, which opens an interactive bash session on a compute node:
nvidia-smi to verify GPU access:
screen -r speedrun to reattach to the session.
Step 5: Configure the cache directory
Point the nanochat cache directory at/scratch, the fast NVMe storage local to each compute node, so that dataset streaming, checkpoints, and intermediate artifacts don’t bottleneck training. Without this change, model FLOPs utilization (MFU) during training is only about 13% instead of about 50%.
Set the path in speedrun.sh, not in your shell. The script exports its own value of NANOCHAT_BASE_DIR near the top, which overrides any value you export in your shell. Edit that line to point at /scratch:
/scratch is ephemeral, copy anything you want to keep long-term to /home, which lives on the persistent shared volume.
Step 6: Run the training pipeline
In the compute node shell inside yourscreen session, start the pipeline with nanochat’s speedrun.sh script:
- Tokenizer training: Trains a GPT-4-style BPE tokenizer on FineWeb-Edu data.
- Base model pretraining: Trains the base transformer model with rotary embeddings and the Muon optimizer.
- Midtraining: Fine-tunes on a mixture of SmolTalk, MMLU, GSM8K, synthetic identity conversations, and spelling tasks.
- Supervised fine-tuning (SFT): Aligns the model for conversational interactions.
- Evaluation: Runs CORE benchmarks and generates a report.
- MFU: Expect about 50%. A lower value usually means a data loading bottleneck, so check the cache directory you set in Step 5.
- tok/sec: Measures training throughput in tokens processed per second.
- Step timing: Each training step should complete in a few seconds.
$NANOCHAT_BASE_DIR, the /scratch path you set in Step 5.
The remaining steps serve the trained model in nanochat’s chat UI. You run them from your local machine, reaching the cluster through kubectl. You can start Steps 7 and 8 while training runs, but wait for training to finish before you launch the web server in Step 9.
Step 7: Download the cluster kubeconfig
On your local machine, use the Together CLI to download the cluster’s kubeconfig, whichkubectl needs to access the cluster. Find your cluster ID with tg clusters list, then write the kubeconfig to a local file, with the cluster as its default context:
Step 8: Access the compute pod with kubectl
On your local machine, pointkubectl at the kubeconfig from Step 7 and list the pods in the slurm namespace:
NANOCHAT_BASE_DIR at the /scratch path from Step 5, and activate the virtual environment that speedrun.sh created. Replace <LOGIN> with the login name from your SSH command in Step 2:
Step 9: Launch the web server
After training finishes, launch the FastAPI web server in the pod shell where you activated the virtual environment:Step 10: Forward the web server port
Leave the server running. In a new terminal window on your local machine, set up port forwarding to the web server:Step 11: Chat with nanochat
Open this URL in your browser:Congrats! You trained and deployed your own ChatGPT-style model on a Together GPU cluster.
Clean up to stop billing
On-demand clusters bill hourly until you delete them. When you’re done experimenting, delete the cluster:/home, persists after cluster deletion and continues to bill until you delete it too.
Costs and performance
Typical results for a fullspeedrun.sh run on an 8xH100 cluster:
- Training time: About 4 hours.
- MFU: About 50%.
- Cost: About $130 at the on-demand H100 rate (8 GPUs for about 4 hours), plus storage.
report.md file that the pipeline writes to the nanochat directory when training completes.
Troubleshooting
nvidia-smi doesn’t show GPUs after srun: Rerun srun and request the GPUs on a single node explicitly:
- Check that
NANOCHAT_BASE_DIRis set to/scratch. - Make sure no other processes are using GPU memory.
- Verify that the pod name in your
port-forwardcommand exactly matches one listed bykubectl -n slurm get pods. - Check the logs in the pod terminal to confirm the web server is running.
- If port 6818 is already in use on your machine, forward a different local port and open that port in your browser.
Next steps
To keep going with nanochat:- Modify the SFT data or run additional reinforcement learning training for specific behaviors.
- Extend
chat_web.pywith authentication and persistence layers. - Try the
run1000.shscript for a larger model.
Slurm
Submit and manage batch jobs with the preconfigured Slurm scheduler.
Manage clusters
Manage access, scale capacity, and monitor cluster health.