Spaces:
Paused
Paused
File size: 8,127 Bytes
2f86d9b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | # Hackable Diffusion Adapter β Agent Playbook
This document is designed to guide AI coding agents through the structure,
setup, testing, and training workflows of the **Hackable Diffusion (HD) Text
Diffusion Supervised Fine-Tuning (SFT)** adapter library.
---
## π Codebase Structure
The project is structured as a standard Python/JAX package.
* **`configs/`**: Kauldron config files defining task hyperparameters, datasets, losses, optimizers, and evaluators.
* [`sft_sudoku.py`](gemma/diffusion/hackable_diffusion_adapter/configs/sft_sudoku.py): LoRA-based SFT training for the Sudoku puzzle solving task.
* [`sft_sudoku_full.py`](gemma/diffusion/hackable_diffusion_adapter/configs/sft_sudoku_full.py): Full weight SFT training for the Sudoku puzzle solving task (no LoRA).
* [`sft_pubmedqa.py`](gemma/diffusion/hackable_diffusion_adapter/configs/sft_pubmedqa.py): LoRA-based SFT training for the PubMedQA long-answer task.
* **`data/`**: Dataset loading, custom pipelines, and preprocessing transforms.
* [`data.py`](gemma/diffusion/hackable_diffusion_adapter/data/data.py): Common transforms (e.g. `CanvasChunker` for localized diffusion).
* **`hd/`**: Core modeling, network layers, and state handling.
* [`sft_model.py`](gemma/diffusion/hackable_diffusion_adapter/hd/sft_model.py): Core `SFTDiffusion` class managing the hybrid AR prefill and localized diffusion denoising steps.
* [`lora.py`](gemma/diffusion/hackable_diffusion_adapter/hd/lora.py): PEFT LoRA wrappers.
* [`mask_helpers.py`](gemma/diffusion/hackable_diffusion_adapter/hd/mask_helpers.py): Right-pad causal/block masks and cursor tracking.
* **`eval/`**: Custom evaluation metrics designed to avoid TPU/GPU OOM issues.
* [`sudoku_eval.py`](gemma/diffusion/hackable_diffusion_adapter/eval/sudoku_eval.py): Unified host-side `SudokuAllMetrics` evaluation.
---
## π οΈ Setup and Installation
Follow these instructions to set up the local Python environment.
### 1. Python Environment Setup
We recommend Python 3.12 and CUDA 13.
### 2. Installation
First install the gemma package.
**From PyPI (Recommended)**
```bash
pip install gemma
```
**From Source**
```bash
git clone https://github.com/google-deepmind/gemma.git
cd gemma
pip install .
```
Then we additionally require `jax[cuda13]` dependencies that can be installed
via
```bash
pip install -U jax[cuda13]
```
> **CUDA Version Constraint**: If configuring JAX for GPU, you must use
> **CUDA 13**. Mixing CUDA 12 packages (such as `jax-cuda12-plugin` or
> `nvidia-nccl-cu12`) will trigger PJRT initialization crashes and silent
> NCCL corruption.
---
## πΎ Dataset Preparation
Before launching SFT training, datasets must be preprocessed.
Note that running these scripts requires first cloning the source repository.
### PubMedQA Dataset
```bash
cd gemma/diffusion/hackable_diffusion_adapter/data/pubmedqa
bash prepare_pubmedqa_dataset.sh
cd -
```
### Sudoku Dataset
Requires Kaggle API access token. Ask the user to generate an access token and
then run the following command.
```bash
mkdir -p ~/.kaggle && echo YOUR_KAGGLE_TOKEN > ~/.kaggle/access_token && chmod 600 ~/.kaggle/access_token
```
Then the datapipeline can be run with the following command
```bash
cd gemma/diffusion/hackable_diffusion_adapter/data/sudoku
bash prepare_sudoku_dataset.sh
cd -
```
---
## π§ͺ Running Unit Tests
To verify the JAX layers, data pipelines, and sampling routines, run:
```bash
pytest gemma/diffusion/hackable_diffusion_adapter/
```
Or run individual tests:
```bash
pytest gemma/diffusion/hackable_diffusion_adapter/hd/lora_test.py
```
---
## π Launching SFT Training
Always use the standard Kauldron CLI command. Use the following env variables
to prevent JIT compilation OOMs and NCCL communication hangs:
Launches should be run from the parent dir of the gemma directory.
#### PubMedQA
```bash
env XLA_FLAGS="--xla_disable_hlo_passes=constant_folding" \
NCCL_ALGO="Ring" \
NCCL_PROTO="LL128" \
NCCL_NVLS_ENABLE="0" \
NCCL_CUMEM_ENABLE="0" \
python3 -m kauldron.main \
--cfg=gemma/diffusion/hackable_diffusion_adapter/configs/sft_pubmedqa.py \
--cfg.workdir=$(pwd)/xp_dir
```
#### Sudoku (with LoRA)
```bash
env XLA_FLAGS="--xla_disable_hlo_passes=constant_folding" \
NCCL_ALGO="Ring" \
NCCL_PROTO="LL128" \
NCCL_NVLS_ENABLE="0" \
NCCL_CUMEM_ENABLE="0" \
python3 -m kauldron.main \
--cfg=gemma/diffusion/hackable_diffusion_adapter/configs/sft_sudoku.py \
--cfg.workdir=$(pwd)/xp_dir
```
#### Sudoku (full weight updates)
```bash
env XLA_FLAGS="--xla_disable_hlo_passes=constant_folding" \
NCCL_ALGO="Ring" \
NCCL_PROTO="LL128" \
NCCL_NVLS_ENABLE="0" \
NCCL_CUMEM_ENABLE="0" \
python3 -m kauldron.main \
--cfg=gemma/diffusion/hackable_diffusion_adapter/configs/sft_sudoku_full.py \
--cfg.workdir=$(pwd)/xp_dir
```
---
## π Offline Evaluation
Evaluation is run **offline** β it is a separate step from training. The
`eval_main` binary loads a saved checkpoint, runs AR diffusion sampling
on the eval dataset, and reports task-specific metrics.
### Running an Eval Job
From the parent dir of the gemma directory:
```bash
env XLA_FLAGS="--xla_disable_hlo_passes=constant_folding" \
XLA_PYTHON_CLIENT_PREALLOCATE="false" \
TF_FORCE_GPU_ALLOW_GROWTH="true" \
python3 -m gemma.diffusion.hackable_diffusion_adapter.eval_main \
--cfg=gemma/diffusion/hackable_diffusion_adapter/configs/sft_sudoku.py \
--task=sudoku \
--step=1000 \
--eval_names=sample_ar_steps64 \
--cfg.workdir=$(pwd)/xp_dir_sudoku_lora \
--cfg.eval_ds.batch_size=2 \
--cfg.aux.eval_num_batches=2 \
--cfg.aux.num_canvases=2
```
### Key Flags
| Flag | Description |
|---|---|
| `--cfg` | Path to the training config file (same one used for training). |
| `--task` | Task to evaluate: `sudoku` or `pubmedqa`. Determines which metrics are reported. |
| `--step` | Checkpoint step to evaluate. If omitted, the latest checkpoint is used. |
| `--eval_names` | Comma-separated list of evaluators to run (e.g. `sample_ar_steps64`). If omitted, all evaluators are run. |
| `--cfg.workdir` | Working directory containing the training checkpoints. |
| `--cfg.eval_ds.batch_size` | Eval batch size (reduce if running out of memory). |
| `--cfg.aux.eval_num_batches` | Number of eval batches to process. Set to a small value for quick sanity checks, or omit to run over the full eval set. |
| `--cfg.aux.num_canvases` | Number of AR canvases to generate per example. |
### Available Evaluators
Evaluators are generated automatically by
[`ar_eval.make_ar_evals`](gemma/diffusion/hackable_diffusion_adapter/eval/ar_eval.py).
The naming convention is:
* `sample_ar_steps{N}` β AR sampling with `N` denoising steps
(default values: 32, 64, 96).
* `sample_ar_steps{N}_early_stopping` β Same as above but with
entropy-based early stopping.
### Checking Eval Results
Eval metrics are written to TensorBoard event files in the working directory.
Launch TensorBoard to view them:
```bash
tensorboard --logdir=$(pwd)/xp_dir_sudoku_lora
```
Metrics for each evaluator appear under the corresponding eval name
(e.g. `sample_ar_steps64`). Key metrics by task:
* **Sudoku**: overall accuracy, cell accuracy, difficulty-stratified results
(easy/medium/hard), exact mask accuracy.
* **PubMedQA**: short-answer accuracy, BLEU score.
---
## π« Guardrails & Best Practices for Code Modifications
* **No Raw `jnp.roll` or pad index assumptions**: When shifting sequences or
tracking attention masks, always use utilities from `mask_helpers.py`
(e.g. `set_cache_end_index`) to ensure compatibility with right-pad
conventions.
* **Keep configs flat**: Do not import helper config modules inside configs. Keep them self-contained and editable as single drop-in files.
* **Evaluate on host side for complex metrics**: Custom evaluation metrics
MUST inherit from `BaseTextMetric` or `BaseSimpleTextMetric` and execute
calculations inside `io_callback` on CPU to prevent device-side OOM.
|