Skip to main content
Axolotl is an open-source fine-tuning toolkit. You configure a training job in YAML — model, dataset, method — and Axolotl runs it, no custom training code required. It supports 60+ model architectures and multiple training methods, including LoRA (which trains a small set of adapter parameters instead of the full model, significantly reducing GPU memory) and QLoRA (which adds 4-bit quantization on top of LoRA to reduce memory even further). This guide fine-tunes Qwen2.5-3B with LoRA on a Vast.ai GPU. We chose this model because it is ungated (no HuggingFace account needed), small enough to train on a single 24GB GPU, and widely used for fine-tuning. The same workflow applies to any Axolotl-supported model. By the end, you will have a working fine-tuned model.

Prerequisites

Hardware Requirements

  • GPU VRAM: 16 GB minimum — training peaks at ~14 GB with LoRA and gradient checkpointing. A 24 GB card (RTX 3090/4090, A5000, A100) gives enough headroom to raise the batch size or sequence length.
  • Disk: 100 GB (model weights ~6 GB, plus dataset cache and checkpoints)
  • CUDA: 12.4+

Find and Rent a GPU

The Axolotl Docker image is large (~15 GB). On slower connections, the image pull can take 30+ minutes. To filter for hosts with fast network downlinks, include inet_down >= 5000 (Mbps) in your search query below.
Search for a GPU instance with at least 16 GB VRAM, CUDA 12.4+, and a fast network downlink:
Create an instance using the Axolotl template, which includes Axolotl, PyTorch, Flash Attention, and all core dependencies. You can find the template hash by searching for “Axolotl” on the Vast.ai templates page and copying the hash from the template details. Replace <OFFER_ID> with an ID from the search results:
You can also skip the CLI and create the instance directly from the Axolotl template page in the web UI. The command returns a contract ID (e.g., new_contract: 33402620). Use this <CONTRACT_ID> for all subsequent commands. Instances typically reach running status in 2–5 minutes (not counting Docker image pull time). Poll with the following loop, which exits automatically once the status is running:
Once running, extract the SSH host and port into shell variables — every later ssh and scp command in this guide reuses them:

Configure Training

Axolotl uses a single YAML file to configure the entire training job. Save the following as config.yml on your local machine:
Copy it to your instance:
You can also create the file directly on the instance using nano or vim if you prefer. The following table explains the key settings:
To train on your own dataset, replace the datasets section. Axolotl supports Alpaca format (instruction/input/output fields), conversation format (OpenAI-style messages), and many others. See the Axolotl dataset docs for all supported formats.

Run Training

SSH into your instance and launch the training run:
Training this config (~10K examples, 1 epoch) takes approximately 15–30 minutes on an RTX 3090 or 4090. Progress is logged every step (see metrics below), so you should see output within the first minute — if not, check the Docker pull and dataset download have completed.
Weights & Biases (W&B) is an experiment tracking platform. Setting WANDB_MODE=disabled skips it so you are not prompted for a login. To enable tracking, set wandb_project in your config and run wandb login first.
Axolotl downloads the model weights, preprocesses the dataset, and begins training. You should see output confirming LoRA is active:
This means only ~30M parameters are being trained instead of the full 3B. Training progress is logged every step. The key metrics are loss (how wrong the model’s predictions are — lower is better), grad_norm (magnitude of parameter updates), and epoch (progress through the dataset, where 1.0 = one full pass):
When training completes, you will see:
The LoRA adapter is saved to ./outputs/qwen25-3b-lora/. The adapter is approximately 80 MB, compared to the 6 GB base model.

Test the Fine-Tuned Model

Verify the fine-tuned model by running inference. Save the following as test_inference.py on your local machine:
Copy it to the instance and run it:
You should see output similar to the following:

Download Your Model

Before destroying the instance, download the LoRA adapter to your local machine:
This downloads the ~80 MB adapter. To use it later, you also need the base model (Qwen/Qwen2.5-3B), which can be re-downloaded from HuggingFace.

Cleanup

Destroy the instance to stop billing:

Next Steps

  • Train longer: Increase num_epochs to 3–4 or use the full 100K dataset (split: train) for better results
  • Try QLoRA: Add load_in_4bit: true and change adapter: qlora to reduce VRAM further — useful for larger models like Qwen2.5-72B
  • Merge the adapter: Run axolotl merge-lora config.yml to combine the LoRA weights into the base model for faster inference without the PEFT library
  • Use your own data: Replace the dataset with your own JSONL file in Alpaca or conversation format
  • Scale to multi-GPU: Add a deepspeed or fsdp config section for distributed training across multiple GPUs — see the multi-node training guide

Additional Resources