> For the complete documentation index, see [llms.txt](https://docs.clore.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.clore.ai/guides/guides_v2-ru/obuchenie/finetune-llm.md).

# Дообучение LLM

Обучите собственную LLM, используя эффективные техники дообучения на GPU CLORE.AI.

{% hint style="success" %}
Все примеры можно запускать на GPU-серверах, арендованных через [маркетплейс CLORE.AI](https://clore.ai/marketplace).
{% endhint %}

## Аренда на CLORE.AI

1. Перейдите на [маркетплейс CLORE.AI](https://clore.ai/marketplace)
2. Отфильтруйте по типу GPU, объёму VRAM и цене
3. Выберите **On-Demand** (фиксированная ставка) или **Spot** (цена ставки)
4. Настройте свой заказ:
   * Выберите Docker-образ
   * Установите порты (TCP для SSH, HTTP для веб-интерфейсов)
   * При необходимости добавьте переменные окружения
   * Введите команду запуска
5. Выберите способ оплаты: **CLORE**, **BTC**, или **USDT/USDC**
6. Создайте заказ и дождитесь развертывания

### Получите доступ к своему серверу

* Найдите данные для подключения в **Мои заказы**
* Веб-интерфейсы: используйте URL HTTP-порта
* SSH: `ssh -p <port> root@<proxy-address>`

## Что такое LoRA/QLoRA?

* **LoRA** (Низкоранговая адаптация) — обучайте небольшие адаптерные слои вместо полной модели
* **QLoRA** - LoRA с квантованием для ещё меньшего использования VRAM
* Обучите модель 7B на одной RTX 3090
* Обучите модель 70B на одной A100

## Требования

| Модель | Метод       | Мин. VRAM | Рекомендуется                                                                                            |
| ------ | ----------- | --------- | -------------------------------------------------------------------------------------------------------- |
| 7B     | QLoRA       | 12GB      | [RTX 3090](https://clore.ai/rent-3090.html?utm_source=docs\&utm_medium=guide\&utm_campaign=finetune-llm) |
| 13B    | QLoRA       | 20 ГБ     | [RTX 4090](https://clore.ai/rent-4090.html?utm_source=docs\&utm_medium=guide\&utm_campaign=finetune-llm) |
| 70B    | QLoRA       | 48 ГБ     | A100 80 ГБ                                                                                               |
| 7B     | Полная LoRA | 24 ГБ     | RTX 4090                                                                                                 |

## Быстрое развёртывание

**Docker-образ:**

```
pytorch/pytorch:2.11.0-cuda12.8-cudnn9-devel
```

**Порты:**

```
22/tcp
8888/http
6006/http
```

**Команда:**

```bash
pip install "transformers>=4.45" "datasets>=2.20" accelerate "peft>=0.14" \
    bitsandbytes "trl>=0.12" wandb jupyterlab && \
jupyter lab --ip=0.0.0.0 --port=8888 --allow-root
```

## Доступ к вашему сервису

После развертывания найдите свой `http_pub` URL в **Мои заказы**:

1. Перейдите на **Мои заказы** страницу
2. Нажмите на свой заказ
3. Найдите `http_pub` URL (например, `abc123.clorecloud.net`)

Используйте `https://YOUR_HTTP_PUB_URL` вместо `localhost` в примерах ниже.

## Подготовка датасета

### Рекомендуемый формат чата

```json
[
  {
    "messages": [
      {"role": "system", "content": "Вы — полезный помощник."},
      {"role": "user", "content": "Что такое Python?"},
      {"role": "assistant", "content": "Python — это язык программирования..."}
    ]
  }
]
```

### Формат инструкции

```json
[
  {
    "instruction": "Переведи на французский",
    "input": "Привет, как дела?",
    "output": "Bonjour, comment allez-vous?"
  }
]
```

### Формат Alpaca

```json
[
  {
    "instruction": "Дай три совета, как оставаться здоровым.",
    "input": "",
    "output": "1. Питайтесь сбалансированно..."
  }
]
```

## Поддерживаемые современные модели (2025)

| Модель                      | ID Hugging Face                           | Минимальная VRAM (QLoRA) |
| --------------------------- | ----------------------------------------- | ------------------------ |
| Llama 3.1 / 3.3 8B          | `meta-llama/Llama-3.1-8B-Instruct`        | 12GB                     |
| Qwen 2.5 7B / 14B           | `Qwen/Qwen2.5-7B-Instruct`                | 12 ГБ / 20 ГБ            |
| DeepSeek-R1-Distill (7B/8B) | `deepseek-ai/DeepSeek-R1-Distill-Qwen-7B` | 12GB                     |
| Mistral 7B v0.3             | `mistralai/Mistral-7B-Instruct-v0.3`      | 12GB                     |
| Gemma 2 9B                  | `google/gemma-2-9b-it`                    | 14 ГБ                    |
| Phi-4 14B                   | `microsoft/phi-4`                         | 20 ГБ                    |

## Скрипт дообучения QLoRA

Современный пример с PEFT 0.14+, Flash Attention 2, поддержкой DoRA и совместимостью с Qwen2.5 / DeepSeek-R1:

```python
import torch
from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    BitsAndBytesConfig,
    TrainingArguments,
)
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
from datasets import load_dataset
from trl import SFTTrainer, SFTConfig

# === Конфигурация ===
# Выберите один из вариантов: Qwen2.5, DeepSeek-R1-Distill, Llama 3.1, Mistral и т. д.
MODEL_NAME = "Qwen/Qwen2.5-7B-Instruct"
# MODEL_NAME = "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B"
# MODEL_NAME = "meta-llama/Llama-3.1-8B-Instruct"

DATASET = "your_dataset.json"  # или имя набора данных HuggingFace
OUTPUT_DIR = "./output"
MAX_SEQ_LENGTH = 4096           # Qwen2.5 поддерживает контекст до 32K
USE_DORA = True                 # DoRA улучшает качество по сравнению со стандартной LoRA
USE_FLASH_ATTN = True           # Flash Attention 2 экономит VRAM и ускоряет работу

# === Загрузка модели с 4-битным квантованием ===
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,
    bnb_4bit_use_double_quant=True,
)

model = AutoModelForCausalLM.from_pretrained(
    MODEL_NAME,
    quantization_config=bnb_config,
    device_map="auto",
    trust_remote_code=True,  # Требуется для Qwen2.5 и DeepSeek
    # Flash Attention 2: требует GPU Ampere+ (RTX 30/40, A100)
    attn_implementation="flash_attention_2" if USE_FLASH_ATTN else "eager",
)

tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
if tokenizer.pad_token is None:
    tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "right"

# === Настройка LoRA с опциональным DoRA ===
# DoRA (Weight-Decomposed Low-Rank Adaptation) — требуется PEFT >= 0.14
# use_dora=True разлагает веса на величину + направление для лучшего качества
lora_config = LoraConfig(
    r=64,                    # Ранг (выше = больше возможностей, больше VRAM)
    lora_alpha=16,           # Коэффициент масштабирования (держите равным r или половине r)
    target_modules=[
        "q_proj", "k_proj", "v_proj", "o_proj",  # Слои внимания
        "gate_proj", "up_proj", "down_proj",      # Слои MLP
    ],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
    use_dora=USE_DORA,        # DoRA: улучшенное качество (PEFT 0.14+)
    # use_rslora=True,        # Опционально: LoRA со стабилизацией ранга
)

# Подготовка модели к обучению QLoRA
model = prepare_model_for_kbit_training(
    model,
    use_gradient_checkpointing=True,
    gradient_checkpointing_kwargs={"use_reentrant": False},
)
model = get_peft_model(model, lora_config)

# Вывод сводки по обучаемым параметрам
model.print_trainable_parameters()
# Пример вывода: обучаемые параметры: 42,991,616 || все параметры: 7,284,891,648 || % обучаемых: 0.59

# === Загрузка набора данных ===
dataset = load_dataset("json", data_files=DATASET)
# Или используйте публичный набор данных:
# dataset = load_dataset("HuggingFaceH4/ultrachat_200k")

# === Форматирование набора данных для формата Qwen2.5 / ChatML ===
def format_chat_qwen(example):
    """Формат для Qwen2.5 с использованием шаблона ChatML."""
    messages = example.get("messages", [])
    if not messages:
        # Обработка данных в стиле Alpaca
        text = f"<|im_start|>system\nВы — полезный помощник.<|im_end|>\n"
        text += f"<|im_start|>user\n{example['instruction']}"
        if example.get("input"):
            text += f"\n{example['input']}"
        text += f"<|im_end|>\n<|im_start|>assistant\n{example['output']}<|im_end|>"
    else:
        # Обработка формата сообщений (ChatML)
        text = tokenizer.apply_chat_template(
            messages,
            tokenize=False,
            add_generation_prompt=False,
        )
    return {"text": text}

dataset = dataset.map(format_chat_qwen, remove_columns=dataset["train"].column_names)

# === Аргументы обучения (PEFT 0.14+ / TRL 0.12+) ===
training_args = SFTConfig(
    output_dir=OUTPUT_DIR,
    num_train_epochs=3,
    per_device_train_batch_size=2,
    gradient_accumulation_steps=8,         # Эффективный batch = 2 * 8 = 16
    learning_rate=2e-4,
    weight_decay=0.001,
    warmup_ratio=0.03,
    lr_scheduler_type="cosine",
    logging_steps=10,
    save_steps=100,
    save_total_limit=3,
    bf16=True,                             # Используйте bf16 для современных GPU (A100, RTX 30/40)
    # fp16=True,                           # Используйте fp16 для старых GPU
    optim="paged_adamw_8bit",
    max_grad_norm=0.3,
    group_by_length=True,
    report_to="wandb",                     # или "tensorboard"
    # Специфично для SFTConfig:
    max_seq_length=MAX_SEQ_LENGTH,
    dataset_text_field="text",
    packing=True,                          # Пакуйте несколько примеров для эффективности
)

# === Обучение ===
trainer = SFTTrainer(
    model=model,
    train_dataset=dataset["train"],
    tokenizer=tokenizer,
    args=training_args,
)

trainer.train()

# === Сохранение адаптера LoRA ===
trainer.save_model(f"{OUTPUT_DIR}/final")
tokenizer.save_pretrained(f"{OUTPUT_DIR}/final")
print(f"Модель сохранена в {OUTPUT_DIR}/final")
```

## Flash Attention 2

Flash Attention 2 уменьшает использование VRAM и значительно ускоряет обучение. Требуется GPU Ampere+ (RTX 3090, RTX 4090, A100).

```bash
# Установите Flash Attention 2
pip install flash-attn --no-build-isolation
```

```python
# Включите при загрузке модели:
model = AutoModelForCausalLM.from_pretrained(
    MODEL_NAME,
    attn_implementation="flash_attention_2",  # <-- добавьте это
    torch_dtype=torch.bfloat16,               # FA2 требует bf16 или fp16
    device_map="auto",
)
```

| Параметр                    | VRAM (7B) | Скорость        |
| --------------------------- | --------- | --------------- |
| Стандартное внимание (fp16) | \~22 ГБ   | базовый уровень |
| Flash Attention 2 (bf16)    | \~16 ГБ   | +30%            |
| Flash Attention 2 + QLoRA   | \~12 ГБ   | +30%            |

## DoRA (LoRA с декомпозицией весов)

DoRA (PEFT >= 0.14) разлагает предобученные веса на компоненты величины и направления. Это улучшает качество дообучения, особенно при меньших рангах.

```python
from peft import LoraConfig

# Стандартная LoRA
lora_config = LoraConfig(r=64, lora_alpha=16, use_dora=False, ...)

# DoRA — те же параметры, лучшее качество
lora_config = LoraConfig(r=64, lora_alpha=16, use_dora=True, ...)
# Примечание: DoRA добавляет ~5-10% к расходу VRAM по сравнению со стандартной LoRA
# Примечание: не всегда совместимо с квантованными моделями (4-бит/8-бит)
```

## Примеры Qwen2.5 и DeepSeek-R1-Distill

### Дообучение Qwen2.5

```python
MODEL_NAME = "Qwen/Qwen2.5-7B-Instruct"
# Для 14B: "Qwen/Qwen2.5-14B-Instruct" (требует 20+ ГБ VRAM с QLoRA)

model = AutoModelForCausalLM.from_pretrained(
    MODEL_NAME,
    quantization_config=bnb_config,
    device_map="auto",
    trust_remote_code=True,          # Требуется для Qwen2.5
    attn_implementation="flash_attention_2",
)
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)

# Qwen2.5 использует формат ChatML — используйте apply_chat_template
messages = [
    {"role": "system", "content": "Вы — полезный помощник."},
    {"role": "user", "content": "Привет!"},
    {"role": "assistant", "content": "Привет! Чем я могу помочь?"},
]
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=False)
```

### Дообучение DeepSeek-R1-Distill

Модели DeepSeek-R1-Distill (Qwen-7B, Qwen-14B, Llama-8B, Llama-70B) ориентированы на рассуждения. Дообучайте их, чтобы адаптировать стиль chain-of-thought к вашей предметной области.

```python
# Варианты DeepSeek-R1-Distill
MODEL_NAME = "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B"   # 7B на базе Qwen2.5
# MODEL_NAME = "deepseek-ai/DeepSeek-R1-Distill-Llama-8B" # 8B на базе Llama3
# MODEL_NAME = "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B" # 14B (требует A100)

model = AutoModelForCausalLM.from_pretrained(
    MODEL_NAME,
    quantization_config=bnb_config,
    device_map="auto",
    trust_remote_code=True,
    attn_implementation="flash_attention_2",
)

# DeepSeek-R1 использует теги <think>...</think> для рассуждений
# Сохраняйте это в обучающих данных, чтобы сохранить способность к chain-of-thought
example_format = """<|im_start|>user
Реши: чему равно 15 * 23?<|im_end|>
<|im_start|>assistant
<think>
15 * 23 = 15 * 20 + 15 * 3 = 300 + 45 = 345
</think>
Ответ — 345.<|im_end|>"""

# Целевые модули LoRA для DeepSeek-R1-Distill (база Qwen2.5)
lora_config = LoraConfig(
    r=32,
    lora_alpha=16,
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
                    "gate_proj", "up_proj", "down_proj"],
    use_dora=True,
    task_type="CAUSAL_LM",
)
```

## Использование Axolotl (проще)

Axolotl упрощает дообучение с помощью YAML-конфигов:

```bash
pip install axolotl

# Создать конфиг
cat > config.yml << 'EOF'
base_model: mistralai/Mistral-7B-v0.1
model_type: MistralForCausalLM
tokenizer_type: LlamaTokenizer

load_in_4bit: true
adapter: qlora
lora_r: 32
lora_alpha: 16

datasets:
  - path: your_data.json
    type: alpaca

sequence_len: 4096
sample_packing: true

gradient_accumulation_steps: 4
micro_batch_size: 2
num_epochs: 3
learning_rate: 2e-4

output_dir: ./output
EOF

# Обучение
accelerate launch -m axolotl.cli.train config.yml
```

## Примеры конфигурации Axolotl

### Чат-модель

```yaml
base_model: mistralai/Mistral-7B-Instruct-v0.2
load_in_4bit: true
adapter: qlora

datasets:
  - path: data.json
    type: sharegpt

chat_template: mistral
```

### Модель для кода

```yaml
base_model: codellama/CodeLlama-7b-hf
load_in_4bit: true
adapter: qlora

datasets:
  - path: code_data.json
    type: alpaca

sequence_len: 8192  # Более длинный контекст для кода
```

## Слияние весов LoRA

После обучения объедините LoRA обратно в базовую модель:

```python
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer

# Загрузить базовую модель
base_model = AutoModelForCausalLM.from_pretrained(
    "mistralai/Mistral-7B-v0.1",
    torch_dtype=torch.float16,
    device_map="auto",
)

# Загрузить LoRA
model = PeftModel.from_pretrained(base_model, "./output/final")

# Объединить
merged_model = model.merge_and_unload()

# Сохранить объединённую модель
merged_model.save_pretrained("./merged_model")
tokenizer.save_pretrained("./merged_model")
```

## Конвертация в GGUF

Для использования с llama.cpp/Ollama:

```bash

# Клонировать llama.cpp
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp

# Конвертировать
python convert.py ../merged_model --outtype f16 --outfile model-f16.gguf

# Квантовать
./quantize model-f16.gguf model-q4_k_m.gguf q4_k_m
```

## Мониторинг обучения

### Weights & Biases

```python
import wandb
wandb.init(project="llm-finetune", name="mistral-7b-lora")
```

### TensorBoard

```python

# В аргументах обучения
report_to="tensorboard"
logging_dir="./logs"

# Просмотр
tensorboard --logdir ./logs --port 6006 --bind_all
```

## Лучшие практики

### Гиперпараметры

| Параметр             | Модель 7B | Модель 13B | Модель 70B |
| -------------------- | --------- | ---------- | ---------- |
| размер батча         | 4         | 2          | 1          |
| накопление градиента | 4         | 8          | 16         |
| lr                   | 2e-4      | 1e-4       | 5e-5       |
| ранг LoRA            | 64        | 32         | 16         |
| эпохи                | 3         | 2-3        | 1-2        |

### Размер набора данных

* Минимум: 1 000 примеров
* Хорошо: 10 000+ примеров
* Качество > количество

### Как избежать переобучения

```python
training_args = TrainingArguments(
    ...
    weight_decay=0.01,
    warmup_ratio=0.03,
    save_total_limit=3,
    load_best_model_at_end=True,
    evaluation_strategy="steps",
    eval_steps=100,
)
```

## Многопроцессорное обучение на нескольких GPU

```bash

# С помощью accelerate
accelerate launch --multi_gpu --num_processes 4 train.py

# С помощью DeepSpeed
accelerate launch --use_deepspeed --num_processes 4 train.py
```

Конфиг DeepSpeed:

```json
{
  "bf16": {"enabled": true},
  "zero_optimization": {
    "stage": 2,
    "offload_optimizer": {"device": "cpu"}
  }
}
```

## Сохранение и экспорт

```bash

# Сохранить адаптер LoRA
trainer.save_model("./lora_adapter")

# Сохранить объединённую модель
merged_model.save_pretrained("./full_model")

# Загрузить в HuggingFace
huggingface-cli login
merged_model.push_to_hub("username/my-model")
```

## Устранение неполадок

### Ошибки OOM

* Уменьшите размер пакета
* Увеличьте gradient accumulation
* Используйте `gradient_checkpointing=True`
* Уменьшите lora\_r

### Потеря обучения не уменьшается

* Проверьте формат данных
* Увеличьте скорость обучения
* Проверьте данные на наличие проблем

### Потеря NaN

* Уменьшите скорость обучения
* Используйте fp32 вместо fp16
* Проверьте данные на повреждения

## Оценка стоимости

Типичные расценки на маркетплейсе CLORE.AI (по состоянию на 2026 год):

| GPU        | Почасовая ставка | Дневная ставка | 4-часовая сессия |
| ---------- | ---------------- | -------------- | ---------------- |
| RTX 3060   | \~$0.03          | \~$0.70        | \~$0.12          |
| RTX 3090   | \~$0.06          | \~$1.50        | \~$0.25          |
| RTX 4090   | \~$0.10          | \~$2.30        | \~$0.40          |
| A100 40 ГБ | \~$0.17          | \~$4.00        | \~$0.70          |
| A100 80 ГБ | \~$0.25          | \~$6.00        | \~$1.00          |

*Цены зависят от провайдера и спроса. Проверьте* [*маркетплейс CLORE.AI*](https://clore.ai/marketplace) *актуальные тарифы.*

> 📚 См. также: [Как дообучить LLaMA 3 на облачном GPU — пошаговое руководство](https://blog.clore.ai/how-to-fine-tune-llama-3-cloud-gpu/)

**Сэкономьте деньги:**

* Используйте **Spot** рынок для прерываемых задач — примерно треть серверов оценивает spot-цены ниже on-demand (медиана \~13% скидки), остальные совпадают с ними
* Платите **CLORE** токенами
* Сравните цены у разных провайдеров


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-ru/obuchenie/finetune-llm.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
