Skip to content

Commit 7946f45

Browse files
committed
docs: QLoRA Documentation and Notebooks
1 parent cf9b093 commit 7946f45

8 files changed

Lines changed: 1021 additions & 4 deletions

File tree

.github/workflows/run_jupyter_notebooks.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ jobs:
109109
# Run Hugging Face authentication
110110
hf auth login --token "$HF_TOKEN"
111111
112-
for notebook in "$MAXTEXT_NOTEBOOKS_ROOT"/{sft,rl}*.ipynb; do
112+
for notebook in "$MAXTEXT_NOTEBOOKS_ROOT"/{sft,rl,lora}*.ipynb; do
113113
filename=$(basename "$notebook")
114114
# TODO: Update runnner to v6e-8 as RL with LLama3.1-8b doesn't fit on v6e-4
115115
if [[ "$filename" == "sft_llama3_demo_gpu.ipynb" || "$filename" == "maxtext_with_gepa.ipynb" ]]; then

docs/guides.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ Interactive development guides for running MaxText on Google Colab or local Jupy
6363
A step-by-step guide for the community to help expand MaxText's model library.
6464
:::
6565

66+
:::{grid-item-card} 🎗️ LoRA Model Bringup
67+
:link: guides/lora_model_bringup
68+
:link-type: doc
69+
70+
Learn how to integrate Low-Rank Adaptation (LoRA) support for a new model architecture.
71+
:::
72+
6673
:::{grid-item-card} 🎓 Distillation
6774
:link: guides/distillation
6875
:link-type: doc
@@ -89,6 +96,7 @@ guides/checkpointing_solutions.md
8996
guides/monitoring_and_debugging.md
9097
guides/run_python_notebook.md
9198
guides/model_bringup.md
99+
guides/lora_model_bringup.md
92100
guides/distillation.md
93101
guides/eval_framework.md
94102
```

docs/guides/lora_model_bringup.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<!--
2+
Copyright 2026 Google LLC
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
https://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
17+
# Adding a New Model for LoRA Fine-Tuning
18+
19+
This guide explains how to add Low-Rank Adaptation (LoRA) support for a new model architecture in MaxText.
20+
21+
MaxText leverages [Tunix](https://github.com/google/tunix) and [Qwix](https://github.com/google/qwix) to support Parameter-Efficient Fine-Tuning (PEFT) on JAX/NNX model definitions. Since the architecture uses modular APIs, adding LoRA support for a new model is highly streamlined.
22+
23+
______________________________________________________________________
24+
25+
## 1. Step-by-Step Bring-up Guide for NNX LoRA
26+
27+
To enable LoRA support for a new model, follow these two simple steps:
28+
29+
### Step 1.1: Verify Base Model Support
30+
31+
The target model architecture must already be implemented and supported as a base model in MaxText.
32+
33+
- The JAX/NNX model definition should be located under `src/maxtext/models/` (e.g., \[gemma3.py\](file:///home/jackyf_google_com/maxtext/src/maxtext/models/gemma3.py)).
34+
- The model configurations must be registered and runnable for baseline pre-training or full fine-tuning.
35+
36+
### Step 1.2: Define Trainable LoRA Target Modules
37+
38+
Add a recommended target pattern for your model architecture prefix in \[src/maxtext/configs/post_train/lora_module_path.yml\](file:///home/jackyf_google_com/maxtext/src/maxtext/configs/post_train/lora_module_path.yml):
39+
40+
```yaml
41+
your_model_prefix: "decoder/layers/.*(self_attention/(query|key|value|out)|mlp/(wi_0|wi_1|wo))"
42+
```
43+
44+
> [!NOTE]
45+
> MaxText's `_get_lora_module_path` in `lora_utils.py` automatically handles both **scanned** (e.g., `layers/0/self_attention/...`) and **unscanned** (e.g., `layers/self_attention/...`) layer formats by injecting an optional layer index regex. You only need to define standard, unscanned paths.
46+
47+
If no prefix matches your model name, MaxText falls back to the `default` pattern:
48+
49+
```yaml
50+
default: "decoder/layers/.*(self_attention/(query|key|value|out)|mlp/(wi_0|wi_1|wo))"
51+
```
52+
53+
______________________________________________________________________
54+
55+
## 2. Integrating Custom Weight Mappings (When is it needed?)
56+
57+
Determining whether you need to implement custom weight mappings depends entirely on your downstream workflow:
58+
59+
### Scenario A: SFT Training & Conversion to PEFT (No Mapping Needed)
60+
61+
If you only need to run SFT fine-tuning with LoRA and then export the adapter back to Hugging Face format using `to_huggingface.py`, **you do not need to write any custom weight mappings.**
62+
63+
- The conversion utility automatically maps, scales, and formats the LoRA adapter parameters back into standard Hugging Face PEFT format based on the base model's existing weight mapping.
64+
65+
### Scenario B: Decoding with the MaxText vLLM Adapter (Mapping is Required)
66+
67+
If you want to perform decoding or run high-performance serving on your adapted model using the **MaxText vLLM adapter** (e.g., via `vllm_decode`), **you must define and register a custom weight mapping.** This allows the vLLM JAX wrapper to dynamically map and feed weights to the vLLM engine.
68+
69+
To add weight mapping for vLLM decode:
70+
71+
1. **Create a Weight Mapping Config**:
72+
Create a new file in \[src/maxtext/integration/tunix/weight_mapping/\](file:///home/jackyf_google_com/maxtext/src/maxtext/integration/tunix/weight_mapping/) (e.g., `your_model.py`) defining a mapping dataclass. You can refer to \[gemma3.py\](file:///home/jackyf_google_com/maxtext/src/maxtext/integration/tunix/weight_mapping/gemma3.py) or \[llama3.py\](file:///home/jackyf_google_com/maxtext/src/maxtext/integration/tunix/weight_mapping/llama3.py) as templates.
73+
74+
Your class should specify:
75+
76+
- `to_hf_mapping()`: Maps MaxText base parameters to Hugging Face parameters and specifies their sharding axes.
77+
- `to_hf_hook_fns()`: Custom hook functions for complex weight transformations (e.g., RoPE reordering or query scaling).
78+
- `lora_to_hf_mappings()`: Custom mapping for LoRA weights if they require different handling.
79+
80+
2. **Register the Mapping**:
81+
Register your new class in \[src/maxtext/integration/tunix/weight_mapping/__init__.py\](file:///home/jackyf_google_com/maxtext/src/maxtext/integration/tunix/weight_mapping/__init__.py) inside the `StandaloneVllmWeightMapping` class:
82+
83+
```python
84+
# Inside StandaloneVllmWeightMapping
85+
if name.startswith("your_model_name"):
86+
return YOUR_MODEL_VLLM_MAPPING
87+
```

docs/guides/model_bringup.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ Please ensure all items on the following checklist are completed before finalizi
134134

135135
- [ ] Create a user guide and post an announcement in the MaxText repo.
136136

137+
5. (Optional) LoRA Support
138+
139+
- [ ] Integrate LoRA support for the newly onboarded model by following the [LoRA Model Bringup Guide](lora_model_bringup.md).
140+
137141
## Community Q&A (FAQ)
138142

139143
**Q: How do I debug code inside a JAX JIT function?**

docs/tutorials/post_training_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ MaxText was co-designed with key Google led innovations to provide a unified pos
2828
- [SFT on Multi-Host TPUs](./posttraining/sft_on_multi_host.md)
2929
- **LoRA (Low-Rank Adaptation)**
3030
- [LoRA on Single-Host TPUs](./posttraining/lora.md)
31+
- [LoRA on Multi-Host TPUs](./posttraining/lora_on_multi_host.md)
3132
- **DPO (Direct Preference Optimization) and ORPO (Odds-Ratio Policy Optimization)**
3233
- [DPO/ORPO on Single-Host TPUs](./posttraining/dpo.md)
3334
- **Multimodal SFT**

docs/tutorials/posttraining/lora.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ export DATASET_NAME=<DATASET_NAME> # e.g., openai/gsm8k
6060
export TRAIN_SPLIT=<TRAIN_SPLIT> # e.g., train
6161
export HF_DATA_DIR=<DATASET_PATH> # e.g., main
6262
export TRAIN_DATA_COLUMNS=<DATA_COLUMNS> # e.g., ['question','answer']
63-
export CHAT_TEMPLATE_PATH=<TEMPLATE_PATH> # e.g., maxtext/examples/chat_templates/math_qa.json
6463

6564
# -- LoRA Conversion configuration (Optional) --
6665
export HF_LORA_ADAPTER_PATH=<HF_LORA_ADAPTER_PATH> # e.g., 'username/adapter-name'
@@ -118,7 +117,6 @@ python3 -m maxtext.trainers.post_train.sft.train_sft \
118117
per_device_batch_size="${PER_DEVICE_BATCH_SIZE?}" \
119118
max_target_length="${MAX_TARGET_LENGTH?}" \
120119
learning_rate="${LEARNING_RATE?}" \
121-
chat_template_path="${CHAT_TEMPLATE_PATH?}" \
122120
enable_nnx=True \
123121
pure_nnx_decoder=True \
124122
lora.enable_lora=True \
@@ -176,7 +174,6 @@ python3 -m maxtext.trainers.post_train.sft.train_sft \
176174
per_device_batch_size="${PER_DEVICE_BATCH_SIZE?}" \
177175
max_target_length="${MAX_TARGET_LENGTH?}" \
178176
learning_rate="${LEARNING_RATE?}" \
179-
chat_template_path="${CHAT_TEMPLATE_PATH?}" \
180177
enable_nnx=True \
181178
pure_nnx_decoder=True \
182179
lora.enable_lora=True \

0 commit comments

Comments
 (0)