Fine-tune LLMs on the 0G decentralized compute network using TEE-secured GPU providers.
Instead of fine-tuning a model on your own GPU (or paying a centralized cloud like AWS), 0G lets you send your dataset to a decentralized network of GPU providers. These providers run your training inside a TEE (Trusted Execution Environment) — a hardware-level secure enclave that ensures your data and model stay private, even from the provider themselves. The network is cheaper than traditional cloud providers.
How it works:
You (dataset + config)
|
v
0G Network --- finds a GPU provider with TEE hardware
|
v
Provider trains your model inside a secure enclave
|
v
Encrypted model returned to you --- only your wallet can decrypt it
Key concepts:
- Provider — A GPU node on the 0G network that runs fine-tuning jobs inside TEE hardware
- LoRA adapter — The fine-tuning output. A small (few MB) add-on layer that modifies the base model's behavior. You load it on top of the original model to get your customized version
- Ledger — Your on-chain balance in the 0G system. You deposit tokens here, then transfer to a provider's sub-account before creating tasks
- Sub-account — A per-provider, per-service escrow. Funds transferred with
--service fine-tuningcan only be used for fine-tuning (not inference)
- Node.js >= 22.0.0
- Ethereum wallet with A0GI tokens (testnet faucet, more via Discord) — see testnet setup. You can export your private key from MetaMask or any EVM-compatible wallet
- Python >= 3.10 (only needed for running the fine-tuned model locally)
Network: This example runs on the 0G Galileo Testnet (Chain ID: 16602). Fine-tuning is not yet available on mainnet.
# Install the 0G CLI globally
npm install -g @0glabs/0g-serving-broker
# Configure network and login with your wallet
0g-compute-cli setup-network
0g-compute-cli login
# Clone this repo and install dependencies
git clone <this-repo>
cd 0g-fine-tuning-example
npm install
cp .env.example .env
# Edit .env and add your PRIVATE_KEY0g-compute-cli fine-tuning list-providersExample output:
Provider 1 0xA02b95Aa6886b1116C4f334eDe00381511E31A09
Available yes
Price 0.000000500000000000 0G per byte
Copy the provider address — you'll need it for all subsequent commands.
This is a two-step process because 0G uses a ledger system:
# Step 2a: Deposit tokens from your wallet into the 0G ledger
0g-compute-cli deposit --amount 3
# Step 2b: Transfer from ledger to the provider's fine-tuning sub-account
# IMPORTANT: --service fine-tuning is required, otherwise funds go to inference
0g-compute-cli transfer-fund --provider <PROVIDER> --amount 2 --service fine-tuningWhy two steps? The ledger acts as an escrow — your funds are locked per-provider and per-service, so the provider can only charge you for the actual training job.
Option A — Local dataset (recommended):
0g-compute-cli fine-tuning create-task \
--provider <PROVIDER> \
--model Qwen2.5-0.5B-Instruct \
--dataset-path ./dataset/train.jsonl \
--config-path ./config/training_config.jsonOption B — Pre-uploaded dataset:
# Upload first
0g-compute-cli fine-tuning upload --data-path ./dataset/train.jsonl
# Then create task with the root hash
0g-compute-cli fine-tuning create-task \
--provider <PROVIDER> \
--model Qwen2.5-0.5B-Instruct \
--dataset <ROOT_HASH> \
--config-path ./config/training_config.jsonExample output:
Uploading dataset to TEE...
Dataset uploaded successfully
Verify provider...
Provider verified
Creating task...
Created Task ID: 6241bd0a-74d4-4542-b724-99375dc692fd
Save the Task ID.
0g-compute-cli fine-tuning get-task --provider <PROVIDER> --task <TASK_ID>
# View training logs (loss, steps, etc.)
0g-compute-cli fine-tuning get-log --provider <PROVIDER> --task <TASK_ID>Task progresses through these states:
Init → SettingUp → SetUp → Training → Trained → Delivering → Delivered → UserAcknowledged → Finished
Wait until it reaches Delivered before proceeding. With the demo config, training takes ~7 minutes. Production jobs with more epochs/data may take 30 minutes to several hours depending on dataset size and model.
You have a 48-hour window after Delivered to download, or you lose access.
# Download the encrypted model
0g-compute-cli fine-tuning acknowledge-model \
--provider <PROVIDER> --task-id <TASK_ID> --data-path ./models/
# Wait ~1 minute for on-chain settlement, then decrypt
0g-compute-cli fine-tuning decrypt-model \
--provider <PROVIDER> --task-id <TASK_ID> \
--encrypted-model ./models/lora_model_<TASK_ID>.zip \
--output ./models/decrypted.zip
# Extract the LoRA adapter
cd models && unzip decrypted.zip -d lora_adapterpip install -r requirements.txt
python scripts/inference.py --adapter ./models/lora_adapter/output_modelThe script loads the base Qwen model from HuggingFace, applies your LoRA adapter on top, and runs test prompts. Example output:
Prompt: Review this product: Absolutely wonderful experience from start to finish.
Response: This is a positive review. The customer had an excellent experience...
Or load the adapter directly in Python:
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
import torch
base_model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen2.5-0.5B-Instruct",
torch_dtype=torch.bfloat16,
device_map="auto",
)
model = PeftModel.from_pretrained(base_model, "./models/lora_adapter/output_model")
tokenizer = AutoTokenizer.from_pretrained("./models/lora_adapter/output_model")| Model | Price | Use case |
|---|---|---|
| Qwen2.5-0.5B-Instruct | 0.5 0G / million tokens | Small, fast, cheap — good for testing |
| Qwen3-32B | 4 0G / million tokens | Large, powerful — for production quality |
JSONL file with one JSON object per line. Minimum 10 examples. UTF-8 encoding. Three formats are supported:
// Chat messages (recommended for instruction-tuned models)
{"messages": [{"role": "user", "content": "Classify this review: Great product!"}, {"role": "assistant", "content": "Positive review."}]}
// Instruction format
{"instruction": "Summarize this text", "input": "Long article here...", "output": "Brief summary."}
// Text completion
{"text": "Once upon a time in a land far away..."}See the Dataset Guide for multi-turn examples, system prompts, tips for building your own dataset, and recommended dataset sizes per model.
The file config/training_config.json controls how training runs:
{
"neftune_noise_alpha": 5,
"num_train_epochs": 3,
"per_device_train_batch_size": 2,
"learning_rate": 0.0002,
"max_steps": 45
}| Parameter | What it does | This repo's value |
|---|---|---|
neftune_noise_alpha |
Adds noise during training to improve generalization (paper) | 5 |
num_train_epochs |
How many times to loop through the full dataset | 3 |
per_device_train_batch_size |
Samples processed at once per GPU | 2 |
learning_rate |
How fast the model updates weights (higher = faster but less stable) | 0.0002 |
max_steps |
Hard cap on training steps (overrides epochs if reached first) | 45 |
Training takes ~7 minutes with the demo dataset. To do a quick connectivity test, set max_steps: 3 — results won't be meaningful but you'll verify the workflow works.
Tip: For production fine-tuning, remove
max_stepsentirely and increasenum_train_epochsto 3-5. Only modify values. Use decimal notation (no scientific notation like5e-5).
Fee = (tokenSize / 1,000,000) x pricePerMillionTokens x trainEpochs + Storage Reserve
Storage reserves: Qwen2.5-0.5B = 0.01 0G, Qwen3-32B = 0.09 0G
Example: 10,000 tokens, 3 epochs, Qwen2.5-0.5B = (10k/1M) x 0.5 x 3 + 0.01 = 0.025 0G
config/training_config.json # Training hyperparameters
dataset/README.md # Dataset format guide, tips, and size recommendations
dataset/train.jsonl # Training data (30 sentiment review examples)
dataset/test.jsonl # Test data (10 examples)
scripts/finetune.sh # CLI workflow wrapper (convenience script)
scripts/inference.py # Post-training LoRA inference (Python)
src/ # TypeScript SDK examples (programmatic alternative to CLI)
models/ # Output directory for trained models (git-ignored)
.env.example # Environment template
requirements.txt # Python dependencies for inference
A bash wrapper is included if you prefer not to type full CLI commands:
./scripts/finetune.sh setup # Install CLI + configure network
./scripts/finetune.sh login # Connect wallet
./scripts/finetune.sh list-providers # Find providers
./scripts/finetune.sh deposit 3 # Deposit funds
./scripts/finetune.sh transfer-fund <provider> 2
./scripts/finetune.sh create-task <provider>
./scripts/finetune.sh get-task <provider> <task_id>
./scripts/finetune.sh download-model <provider> <task_id>
./scripts/finetune.sh decrypt-model <provider> <task_id>| Error | Solution |
|---|---|
MinimumDepositRequired |
Run transfer-fund with --service fine-tuning flag |
| Provider busy | Queue your task or try another provider |
| Decryption key error | Wait ~1 minute after acknowledge for on-chain settlement |
| Model download failed | You have 48 hours from Delivered state to download |
- 0G Documentation
- Compute Network Overview
- Fine-Tuning Guide
- Testnet Setup — Chain ID 16602, Explorer
- Mainnet Info — Chain ID 16661, Explorer
- 0G Serving Broker SDK
- GitHub Issues