Skip to main content
This guide walks you through fine-tuning Gemma 4 E4B using QLoRA and Unsloth on VESSL Cloud. By the end, you will have a fine-tuned adapter saved to shared storage, ready for inference or team collaboration.
Google Gemma 4 official image

Prerequisites

Before starting, make sure you have:
  • A VESSL Cloud account with credits (sign up)
  • An organization with access to A100 SXM 80 GB GPU instances
  • Basic familiarity with Python and Hugging Face Transformers
New to VESSL Cloud? Complete the Member quickstart first to set up your account, payment, and storage.

Create a workspace

1

Set up storage volumes

You need two types of storage for this workflow:Why Cluster storage at /root? Your home directory ($HOME) is where pip installs packages by default. Mounting Cluster storage here means you only run pip install once — packages survive workspace pause/resume cycles.Why Object storage at /shared? Fine-tuned model weights need to be accessible from other workspaces or clusters. Object storage is S3-backed and reachable from anywhere, making it easy to share results with your team or deploy from a different region.Create both volumes before launching the workspace:
  • Cluster storage: Go to Cluster storage in the sidebar and click Create new volume. See Storage overview for details.
  • Object storage: Go to Object storage in the sidebar and click Create new volume. See Create a volume for details.
Do not mount Object storage at /root. Object storage is slower than Cluster storage and is not suitable as your primary workspace path. Use /shared or another separate mount point.
2

Launch the workspace

Create a new workspace with the following configuration:See Create a workspace for the full creation flow.
4-bit quantization (QLoRA) keeps VRAM usage around 18-22 GB for the E4B model, well within the 80 GB available on an A100. This leaves headroom for larger batch sizes or longer sequences if needed.
3

Connect to the workspace

Once the workspace shows Running, connect using JupyterLab or SSH. See Connect to a workspace.

Install packages

Open a terminal in your workspace and install the required libraries:
If you mounted Cluster storage at /root, these packages persist across workspace pause/resume. You only need to run this once.

Load the model

What load_in_4bit=True does: Instead of loading each parameter as a 16-bit float (the default), 4-bit quantization compresses the weights to 4 bits using the QLoRA (NF4) technique. This reduces the model’s memory footprint by roughly 4x, allowing a model that would normally require ~32 GB of VRAM to fit in ~8-10 GB. The quality loss is minimal because only the frozen base weights are quantized — the LoRA adapter trains in full precision.
nvidia-smi during training, peak VRAM around 11 GB on an A100 80 GB

Configure LoRA adapter

Hyperparameter reference

When to increase r:
  • Complex domain adaptation (medical, legal, code): try r=16
  • Large, diverse datasets (100k+ samples): try r=16 or r=32
  • Simple style transfer or format following: r=8 is usually sufficient

Prepare the dataset

This example uses the FineTome-100k dataset with 3,000 samples for a quick demo. For production use, train on the full dataset or substitute your own data.
Your dataset should be a JSON file where each entry has a conversations field — a list of message objects with role and content:
Load it with:
The 3,000-sample subset is for demonstration only. For meaningful quality improvements, use the full 100k dataset or at least 10k-20k high-quality samples of your own data.

Train

Training parameter reference

What train_on_responses_only does: By default, the loss is computed over the entire conversation (user + assistant turns). This option masks the user turns so the model only learns to generate the assistant responses. This improves training efficiency and prevents the model from memorizing user prompts.

Evaluate

After training, check how the model performs qualitatively and quantitatively.

Check training loss

The trainer_stats object contains the training log. A decreasing loss curve indicates the model is learning:
A healthy loss curve starts high (2-3+) and decreases steadily. If loss plateaus very early, consider increasing r or using more data. If loss spikes or diverges, reduce the learning rate.
60-step training loss decreasing steadily from around 2.37

Compare before and after

Run the same prompt through the fine-tuned model to see the effect:
For a more rigorous evaluation, split your data upfront and compute loss on the held-out portion:
This reports evaluation loss at regular intervals, letting you detect overfitting (training loss decreases but eval loss increases).

Save the model

Save the fine-tuned adapter and tokenizer to Object storage:
Since /shared is backed by Object storage, the saved model is:
  • Persistent — survives workspace termination
  • Cross-cluster — accessible from workspaces in any region
  • Team-shareable — any team member with access to the volume can load the adapter
Adapter and tokenizer files written to /shared/gemma4-finetuned/final/ after training
To load the adapter later from another workspace:

Gemma 4 model comparison

Choose the right Gemma 4 variant based on your GPU and task complexity:
VRAM estimates assume 4-bit quantization with QLoRA, batch size 1, and sequence length 2048. Actual usage varies with batch size, sequence length, and gradient accumulation settings.

Next steps

  • Get the runnable recipe — A packaged version of this workflow (an interactive notebook plus a vesslctl batch-job path, trained on a small domain QA dataset) lives in the gemma4-finetuning cookbook recipe, with measured cost and VRAM benchmarks.
  • Use your own data — Replace FineTome-100k with domain-specific conversation data for targeted improvements.
  • Try DPO or ORPO — After SFT, apply preference optimization (DPO/ORPO) to further align the model with desired behavior.
  • Scale up — Move to the 12B or 27B model for higher quality. Use r=16 or r=32 with larger datasets.
  • Export to GGUF — Convert the fine-tuned model to GGUF format for local inference with llama.cpp or Ollama.
  • Deploy as a batch job — Use VESSL Cloud batch jobs to run fine-tuning as a scheduled, reproducible pipeline.
  • Automate with vesslctl — Turn this interactive run into a one-line command with vesslctl job create. Swap the Jupyter cells for a train.py and submit it from your terminal or a CI pipeline.