aboutsummaryrefslogtreecommitdiffstats
path: root/README.es.md
blob: 806659df4aed87b76964c1c46fa234e728b0dbef (plain)
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
# llm-tune

[English](README.md)

Ajuste fino con LoRA para modelos de la familia Llama, escrito desde cero en
Rust con [burn](https://burn.dev). Carga pesos de Hugging Face, entrena un
adaptador LoRA con un dataset de instrucciones y guarda solo el adaptador. Todo
el proceso es lo bastante chico para leerlo de una vez y corre en CPU.

Por defecto entrena [SmolLM2-135M-Instruct](https://huggingface.co/HuggingFaceTB/SmolLM2-135M-Instruct)
con [databricks-dolly-15k](https://huggingface.co/datasets/databricks/databricks-dolly-15k).

```console
$ llm-tune train --steps 200
model : 30 layers, hidden 576, 9 heads / 3 kv, head_dim 64, vocab 49152
lora  : rank 8, alpha 16, scaling 2.00, targets ["q", "v"]
training 120 LoRA tensors on 256 examples
before -> |B| = 0.000000   |W_base| = 162.8625
step    1/200  loss 0.5757  seq 157
...
adapter saved to adapters/dolly/
```

## Qué implementa

- **Llama en burn**: RMSNorm, embeddings rotatorios con la convención
  «half-split» de Hugging Face, atención con consultas agrupadas (`repeat_kv`),
  MLP SwiGLU y embeddings atados.
- **Carga de pesos** desde `model.safetensors`: convierte BF16 a F32 de forma
  perezosa (el backend ndarray no tiene BF16), transpone los pesos de las capas
  Linear y traduce los nombres de Hugging Face a las rutas de los módulos de burn.
- **LoRA**: `LoraLinear` envuelve cada proyección; A arranca con ruido gaussiano
  y B en cero, así que el entrenamiento parte exactamente del modelo base. Los
  pesos base se congelan y solo A y B reciben gradiente.
- **Pérdida con máscara**: entropía cruzada causal donde solo cuenta la
  respuesta del asistente; el prompt no aporta gradiente.
- **Archivos del adaptador**: `adapter.safetensors` (solo los tensores A/B) y
  `adapter_config.json` (rango, alpha, targets). Al cargarlo verifica que se
  aplicaron todos los tensores esperados, así un adaptador incompatible falla
  con un error en lugar de generar basura.

## Uso

```sh
git clone https://git.all.ar/pub/llm-tune.git
cd llm-tune
./scripts/download.sh          # modelo (~270 MB) y dataset, con verificación de sumas
cargo build --release

# comprobar que el modelo base genera texto coherente
./target/release/llm-tune check "The capital of France is"

# entrenar un adaptador y probarlo
./target/release/llm-tune train --steps 200 --examples 256 --out adapters/dolly
./target/release/llm-tune check --adapter adapters/dolly \
  $'<|im_start|>user\nWhat is the capital of France?<|im_end|>\n<|im_start|>assistant\n'
```

| Opción | Por defecto | |
|---|---|---|
| `--model` | `models/smollm2-135m-instruct` | directorio del modelo de Hugging Face |
| `train --data` | `data/dolly-15k/databricks-dolly-15k.jsonl` | JSONL con formato dolly |
| `train --steps` | 20 | pasos del optimizador |
| `train --batch` | 1 | ejemplos por paso |
| `train --lr` | 1e-4 | tasa de aprendizaje de AdamW |
| `train --max-len` | 256 | los ejemplos más largos se descartan |
| `train --examples` | 256 | ejemplos leídos del dataset |
| `train --out` | `adapters/dolly` | dónde se guarda el adaptador |

El backend por defecto es ndarray (CPU). `--features cuda` o `--features wgpu`
activan los backends de GPU de burn al compilar.

## Licencia

MIT