Дообучение под домен
Обучите LoRA-адаптер на своих документах, чтобы модель говорила словарём и рассуждала в стиле вашей узкой области.
RAG даёт Cradle факты (прайсы, спецификации, пункты договоров). Дообучение даёт стиль и паттерны рассуждений узкой области — юриспруденция, медицина, строительство, бухгалтерия и т.д. Две функции работают вместе.
Python нужен только для шагов LoRA. Основной рантайм Cradle остаётся без Python.
Что можно доучить на MacBook Pro M3 Pro 18 GB
| База | LoRA-train | Inference | Время обучения (500 примеров, 3 эпохи) |
|---|---|---|---|
| Qwen2.5-1.5B-Instruct | комфортно | норм | ~15 мин |
| Qwen2.5-3B-Instruct | комфортно (~8 GB RAM) | норм | ~40 мин |
| Qwen2.5-7B-Instruct | borderline (rank ≤ 8, grad checkpoint) | норм | ~2 ч |
С 36 GB RAM и больше можно использовать Qwen2.5-7B с rank 16.
Шаг 1 — собрать датасет
Соберите исходники в одну папку:
~/corpus/legal/
├── snippets/
│ ├── contract-terms.md
│ └── court-practice.pdf
├── gost/
│ └── civil-code-sections.pdf
└── examples/
└── faq-operator.mdЗапустите сборщик датасета:
pnpm build-dataset \
--files ~/corpus/legal \
--out "~/Library/Application Support/cradle/finetune-datasets/legal-v1" \
--mode qa \
--model "~/Library/Application Support/cradle/models/qwen3-8b-q4.gguf" \
--qa-per-chunk 2 \
--language ru--mode qa— синтезирует Q&A-пары из каждого chunk'а локальной моделью. Медленно, но даёт instruction-tuning dataset.--mode raw— быстро, отдаёт{ "text": "<chunk>" }для continued pretraining.--model— путь к скачанному chat-GGUF, используется для Q&A-синтеза. Рекомендуется Qwen3 8B.
Результат:
legal-v1/
├── train.jsonl
├── valid.jsonl
└── meta.jsonПроверьте 5–10 пар вручную: вопросы должны звучать естественно, ответы не
содержать выдуманных цифр. Если синтезатор галлюцинирует — попробуйте модель
побольше или --mode raw.
Шаг 2 — установка MLX
Python нужен один раз на training-машине. Используйте uv:
curl -LsSf https://astral.sh/uv/install.sh | sh
uv venv cradle-finetune --python 3.11
source cradle-finetune/bin/activate
uv pip install -r /path/to/cradle/tools/finetune/requirements.txt
python -c "import mlx_lm; print(mlx_lm.__version__)"
# ожидайте ≥ 0.31.0Шаг 3 — обучение LoRA
Скопируйте пример конфига и отредактируйте пути:
cp tools/finetune/lora_config.example.yaml ~/lora-legal.yaml
# отредактируйте: data, adapter_path, base modelЗапустите обучение:
python -m mlx_lm.lora --config ~/lora-legal.yamlВ логе вы увидите:
Loading pretrained model
Loading training data
Training
Iter 1: Val loss 2.134, Val took 4.2s
Iter 10: Train loss 1.987, It/sec 0.85, Tokens/sec 420
...
Iter 750: Train loss 1.234, Val loss 1.456
Saved final adapter weights to adapters-raw/legal-v1/adapters.safetensorsНа что смотреть:
- Val loss должен падать. Если застрял или растёт — перетренировка, сократите
iters. - It/sec 0.5–2 на M3 Pro — норма. Если меньше 0.2 — RAM забита, уменьшите
batch_sizeили включитеgrad_checkpoint. - OOM на середине — уменьшите
num_layersс 16 до 8,rankс 16 до 8.
Шаг 4 — экспорт в GGUF
Нужен clone llama.cpp для convert_hf_to_gguf.py и llama-quantize:
git clone https://github.com/ggml-org/llama.cpp ~/repos/llama.cpp
cd ~/repos/llama.cpp
cmake -B build && cmake --build build --config Release -jДальше один скрипт сливает LoRA в базу и квантует:
cd /path/to/cradle
BASE_MODEL=Qwen/Qwen2.5-3B-Instruct \
ADAPTER_PATH="~/Library/Application Support/cradle/adapters-raw/legal-v1" \
OUT_DIR=/tmp/legal-v1-gguf \
LLAMA_CPP=~/repos/llama.cpp \
QUANT=Q4_K_M \
./tools/finetune/export_gguf.shРезультат: /tmp/legal-v1-gguf/model-Q4_K_M.gguf (~1.9 GB для 3B базы).
Шаг 5 — импорт в Cradle
Вариант А (простой) — как новую модель
- Переместите GGUF в
~/Library/Application Support/cradle/models/legal-v1.gguf. - В Cradle: Models → Add Custom URL.
- URL:
file:///Users/aki/Library/Application%20Support/cradle/models/legal-v1.gguf - Role:
general, Context: 16384 (или как у базовой модели). - Сохраните → модель появится в списке установленных.
Теперь в Agents → Edit у нужного агента выберите эту модель вместо базовой.
Вариант Б (экспериментальный) — runtime LoRA-адаптер
Если у вас отдельный GGUF-адаптер:
- В Cradle перейдите в Adapters.
- Import adapter → выберите GGUF.
- Укажите базовую модель по
catalogId. - Scale: 1.0.
В Agents → Edit → "Domain adapter" выберите новый адаптер. База остаётся прежней.
⚠️ Проверено ограниченно:
node-llama-cppv3.4 поддерживает LoRA-адаптеры черезcreateContext({ lora: ... }), но формат адаптера должен быть совместим с llama.cpp. MLX-LM напрямую GGUF-адаптеры не выгружает — используйте Вариант А, пока не понадобится независимо надевать несколько адаптеров.
Troubleshooting
- OOM на iter 1 — база слишком большая. Для 18 GB max: 3B с rank=16 или 7B с rank=8 + grad_checkpoint.
- Val loss не падает — мало данных (less than 100 примеров) или неверный
формат. Откройте
train.jsonl, убедитесь, что каждая строка — валидный JSON с полемmessages. - GGUF после fuse выходит 16 GB — забыли квантовать. Проверьте, что
llama-quantizeпрошёл без ошибок иOUT_DIRсодержитmodel-Q4_K_M.gguf, а не толькоmodel-f16.gguf. - Агент с адаптером всё равно отвечает как базовая модель — scale слишком
мал, попробуйте scale=1.5. Или адаптер доучился слабо: увеличьте
iters.
Что дальше
- После обкатки RAG и Finetune должны работать вместе: адаптер формирует "язык", RAG подсовывает актуальные факты.