LoRA Primer - Tinker Documentation

LoRA Primer

Tinker supports LoRA fine-tuning, which adjusts a small number of parameters, rather than full fine-tuning, which adjusts all of the parameters of the original model.

Our current understanding is that LoRA has equivalent performance to full fine-tuning when doing RL or doing SL on small datasets, while it has worse performance on larger datasets. In more detail:

See LoRA Without Regret for more details and experimental results.

Hyperparameters

The learning rate (LR) is usually the most important hyperparameter in your ML experiments.

LoRA requires a much larger LR than full fine-tuning---typically about 10x larger. People often mistakenly retain their full fine-tuning LR when they port their code to use LoRA, leading them to conclude that LoRA works poorly.

Calculate the correct LoRA learning rate:

We've provided a utility that calculates the factor you should scale the full fine-tuning LR by to get the equivalent LoRA LR:

from tinker_cookbook.hyperparam_utils import get_lora_lr_over_full_finetune_lr

model_name = "Qwen/Qwen3.5-9B"
print(get_lora_lr_over_full_finetune_lr(model_name))

The utility currently returns a factor of 10, which we've found empirically to be accurate across model sizes.

What is LoRA exactly?

LoRA is short for Low-Rank Adaptation. Given that the original model has a weight matrix WWW, we replace it with a new weight matrix W′=W+BAW'=W + BAW′=W+BA, where BBB and AAA are low-rank matrices. If WWW is an n×nn \times nn×n matrix, then BBB and AAA are n×rn \times rn×r and r×nr \times nr×n matrices, respectively, where rrr is the rank of the low-rank approximation. The default rank used by Tinker is 32.

The fact that LoRA uses a low-rank approximation of weight matrices is not terribly important. We prefer to think of LoRA as just a random projection of the parameter space that happens to be efficient to implement. When training with RL or small SL datasets, we are only learning a small amount of information, and this reduced set of parameters is more than enough.

What rank to use?

The default rank used by Tinker is 32. However, if you're doing SL on a large dataset, you should use a larger rank. For supervised learning, as a very rough approximation, LoRA will give good results as long as the number of LoRA parameters is at least as large as the number of completion tokens (i.e., weight=1 tokens). You can calculate the number of LoRA parameters with the following utility:

from tinker_cookbook.hyperparam_utils import get_lora_param_count

model_name = "Qwen/Qwen3.5-9B"
print(get_lora_param_count(model_name, lora_rank=32))

For reinforcement learning, we've found that small ranks give equivalent performance to larger ranks and full fine-tuning.

Note that conveniently, the optimal learning rate does not depend on the LoRA rank. In fact, you can verify that if you train with SL on different ranks (but with the same LR), you'll get exactly the same learning curves for the first few steps of training.