> 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/trl.md).

# TRL (обучение RLHF/DPO)

**TRL** (Transformer Reinforcement Learning) — официальная библиотека HuggingFace для обучения языковых моделей с помощью методов обучения с подкреплением. Имея более 10 тыс. звёзд на GitHub, она предоставляет передовые реализации RLHF, DPO, PPO, GRPO и других алгоритмов выравнивания для LLM.

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

***

## Что такое TRL?

TRL — это библиотека, лежащая в основе многих лучших по выравниванию языковых моделей современности. Она предоставляет:

* **SFT (супервизированное дообучение)** — стандартное дообучение по инструкциям в формате ChatML
* **RLHF/PPO** — классическая оптимизация проксимальной политики с моделью вознаграждения
* **DPO** — Direct Preference Optimization (модель вознаграждения не нужна!)
* **GRPO** — Group Relative Policy Optimization (метод DeepSeek-R1)
* **KTO** — Kahneman-Tversky Optimization (работает с непарными предпочтениями)
* **Reward Modeling** — обучите модель вознаграждения на данных человеческих предпочтений
* **IterativeSFT** — онлайн-обучение с подкреплением с более простой схемой
* **ORPO** — Odds Ratio Preference Optimization

TRL нативно интегрируется с экосистемой HuggingFace: `transformers`, `peft`, `datasets`, `accelerate`, и `bitsandbytes`.

{% hint style="info" %}
**Какой алгоритм следует использовать?**

* **DPO** — самый простой и стабильный. Используйте, когда у вас есть парные данные предпочтений (выбранный/отклонённый).
* **PPO** — самый мощный, но и самый сложный. Используйте, когда у вас есть модель вознаграждения или функция оценки.
* **GRPO** — отлично подходит для задач рассуждения и математики. Метод обучения DeepSeek-R1.
* **SFT** — всегда начинайте с этого перед применением любого RL-метода.
  {% endhint %}

***

## Требования к серверу

| Компонент | Минимум                   | Рекомендуется                |
| --------- | ------------------------- | ---------------------------- |
| GPU       | RTX 3090 (24 GB)          | A100 80 GB / H100            |
| VRAM      | 16 GB (SFT/DPO 7B + LoRA) | 80 GB (полное дообучение 7B) |
| ОЗУ       | 32 ГБ                     | 64 GB+                       |
| CPU       | 8 ядер                    | 16+ ядер                     |
| Хранилище | 100 ГБ                    | 300+ GB                      |
| ОС        | Ubuntu 20.04+             | Ubuntu 22.04                 |
| Python    | 3.9+                      | 3.11                         |
| CUDA      | 12.8+                     | 12.8+                        |

### VRAM по задаче

| Задача | Модель      | Метод       | VRAM             |
| ------ | ----------- | ----------- | ---------------- |
| SFT    | Llama 3 8B  | QLoRA 4-bit | \~8 ГБ           |
| DPO    | Llama 3 8B  | LoRA        | \~20 GB          |
| PPO    | Llama 3 8B  | Полное      | \~80 GB (2×A100) |
| GRPO   | Qwen 7B     | LoRA        | \~24 GB          |
| SFT    | Llama 3 70B | QLoRA 4-bit | \~48 GB          |
| DPO    | Llama 3 70B | LoRA        | \~80 GB          |

***

## Порты

| Порт | Сервис | Примечания                                      |
| ---- | ------ | ----------------------------------------------- |
| 22   | SSH    | Доступ к терминалу, передача файлов, мониторинг |

TRL — это библиотека для обучения; она запускается как CLI- или Python-скрипт, веб-сервер не требуется.

***

## Установка на Clore.ai

### Шаг 1 — Арендуйте сервер

1. Перейдите на [Маркетплейс Clore.ai](https://clore.ai/marketplace)
2. Фильтруйте по **VRAM ≥ 24 GB** (RTX 3090, A100 или H100)
3. Выберите **PyTorch** или **CUDA 12.8** базовый образ
4. Выберите **Хранилище ≥ 200 GB** для моделей и датасетов
5. Откройте порт **22** для доступа по SSH

### Шаг 2 — Подключитесь по SSH

```bash
ssh root@<server-ip> -p <ssh-port>
```

### Шаг 3 — Установите TRL

```bash
# Создайте виртуальное Python-окружение
python3 -m venv /opt/trl
source /opt/trl/bin/activate

# Установите TRL со всеми зависимостями
pip install trl

# Установите дополнительные зависимости для полных рабочих процессов
pip install \
    transformers \
    datasets \
    peft \
    accelerate \
    bitsandbytes \
    wandb \
    scipy \
    sentencepiece \
    protobuf

# Проверьте поддержку GPU
python3 -c "import torch; print(f'CUDA: {torch.cuda.is_available()}, GPU: {torch.cuda.get_device_name(0)}')"
```

### Шаг 4 — Аутентификация HuggingFace

```bash
# Войдите, чтобы получить доступ к ограниченным моделям (Llama, Gemma)
huggingface-cli login
# Введите ваш токен HF с https://huggingface.co/settings/tokens

# Или задайте переменную окружения
export HF_TOKEN=hf_your-token-here
```

### Шаг 5 — Опционально: отслеживание в Weights & Biases

```bash
# Настройте отслеживание экспериментов (крайне рекомендуется)
pip install wandb
wandb login  # Введите ваш API-ключ W&B с https://wandb.ai/settings

# Или отключите W&B
export WANDB_DISABLED=true
```

***

## Супервизированное дообучение (SFT)

SFT всегда является первым шагом перед любой техникой RL.

### Подготовьте свой датасет

```python
# Формат: библиотека datasets с колонкой 'messages' или 'text'
# Формат ChatML (рекомендуется)
from datasets import Dataset

data = [
    {
        "messages": [
            {"role": "system", "content": "Вы полезный ассистент облака GPU."},
            {"role": "user", "content": "Как арендовать GPU на Clore.ai?"},
            {"role": "assistant", "content": "Посетите clore.ai/marketplace, отфильтруйте по характеристикам GPU, выберите сервер и нажмите «Арендовать». Доступ по SSH предоставляется сразу после оплаты."}
        ]
    },
    # ... больше примеров
]

dataset = Dataset.from_list(data)
dataset.save_to_disk("data/sft_dataset")
dataset.push_to_hub("your-username/my-sft-dataset")  # опционально
```

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

```python
# sft_train.py
from trl import SFTTrainer, SFTConfig
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
from peft import LoraConfig, get_peft_model
from datasets import load_dataset
import torch

# Конфигурация модели
model_name = "meta-llama/Llama-3.2-8B-Instruct"

# QLoRA: конфигурация 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,
)

# Загрузить токенизатор
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "right"

# Конфигурация LoRA
lora_config = LoraConfig(
    r=16,
    lora_alpha=32,
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
                    "gate_proj", "up_proj", "down_proj"],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
)

# Загрузить датасет
dataset = load_dataset("trl-lib/ultrachat_200k", split="train_sft[:10%]")

# Конфигурация обучения
training_config = SFTConfig(
    output_dir="./sft_output",
    num_train_epochs=3,
    per_device_train_batch_size=2,
    gradient_accumulation_steps=4,
    learning_rate=2e-4,
    warmup_ratio=0.05,
    lr_scheduler_type="cosine",
    fp16=False,
    bf16=True,
    max_seq_length=2048,
    dataset_text_field="messages",
    logging_steps=10,
    save_steps=100,
    save_total_limit=3,
    push_to_hub=False,
    report_to="wandb",  # или "none"
)

# Инициализировать тренер
trainer = SFTTrainer(
    model=model,
    args=training_config,
    train_dataset=dataset,
    peft_config=lora_config,
    tokenizer=tokenizer,
)

# Обучение
trainer.train()
trainer.save_model("./sft_final")
```

```bash
# Запустить обучение
python3 sft_train.py
```

***

## DPO (Direct Preference Optimization)

DPO — самый популярный метод выравнивания: модель вознаграждения не нужна, только пары предпочтений.

### Подготовьте DPO-датасет

```python
# Формат: у каждого примера есть 'prompt', 'chosen', 'rejected'
from datasets import Dataset

data = [
    {
        "prompt": "Объясните, как оптимизировать использование GPU",
        "chosen": "Чтобы оптимизировать использование GPU: 1) используйте большие размеры батча, чтобы максимизировать загрузку, 2) включите смешанную точность (bf16/fp16), 3) профилируйте с помощью nvidia-smi, чтобы выявить узкие места, 4) используйте потоки CUDA для параллельных операций.",
        "rejected": "Просто используйте больше GPU."
    },
    # ... больше пар предпочтений
]

dataset = Dataset.from_list(data)
```

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

```python
# dpo_train.py
from trl import DPOTrainer, DPOConfig
from transformers import AutoTokenizer, AutoModelForCausalLM
from datasets import load_dataset
import torch

model_name = "./sft_final"  # Начните со своей SFT-модели!

# Загрузите SFT-модель (политику, которую нужно выровнять)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype=torch.bfloat16,
    device_map="auto",
)

# Референсная модель (замороженная копия SFT-модели)
ref_model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype=torch.bfloat16,
    device_map="auto",
)

tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token

# Загрузить датасет предпочтений
dataset = load_dataset("trl-lib/ultrafeedback_binarized", split="train[:5%]")

# Конфигурация DPO
dpo_config = DPOConfig(
    output_dir="./dpo_output",
    num_train_epochs=1,
    per_device_train_batch_size=2,
    gradient_accumulation_steps=4,
    learning_rate=5e-7,           # Значительно ниже, чем у SFT
    beta=0.1,                     # Коэффициент штрафа KL
    loss_type="sigmoid",          # Стандартная функция потерь DPO
    max_length=2048,
    max_prompt_length=512,
    bf16=True,
    logging_steps=10,
    save_steps=50,
    report_to="wandb",
)

trainer = DPOTrainer(
    model=model,
    ref_model=ref_model,
    args=dpo_config,
    train_dataset=dataset,
    tokenizer=tokenizer,
)

trainer.train()
trainer.save_model("./dpo_final")
```

***

## PPO (Proximal Policy Optimization)

PPO — классический подход RLHF: используйте его, когда у вас есть сигнал вознаграждения:

```python
# ppo_train.py
from trl import PPOTrainer, PPOConfig, AutoModelForCausalLMWithValueHead
from transformers import AutoTokenizer, pipeline
from datasets import load_dataset
import torch

model_name = "./sft_final"

# Модель политики (с value head для PPO)
model = AutoModelForCausalLMWithValueHead.from_pretrained(
    model_name,
    torch_dtype=torch.bfloat16,
)

tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token

# Модель вознаграждения (может быть любой функцией оценки)
sentiment_pipe = pipeline(
    "sentiment-analysis",
    model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",
    device=0,
)

def reward_fn(texts):
    """Оцените каждый ответ. Верните список тензоров вознаграждения."""
    results = sentiment_pipe(texts)
    rewards = []
    for result in results:
        score = result["score"] if result["label"] == "POSITIVE" else -result["score"]
        rewards.append(torch.tensor(score))
    return rewards

ppo_config = PPOConfig(
    output_dir="./ppo_output",
    learning_rate=1.41e-5,
    mini_batch_size=1,
    batch_size=4,
    gradient_accumulation_steps=4,
    kl_penalty="kl",
    target_kl=6.0,
    cliprange=0.2,
    vf_coef=0.1,
)

trainer = PPOTrainer(
    config=ppo_config,
    model=model,
    ref_model=None,  # Автоматически копирует начальную модель как референс
    tokenizer=tokenizer,
)

# Цикл обучения
dataset = load_dataset("imdb", split="train[:1000]")
for epoch in range(3):
    for batch in trainer.dataloader:
        queries = batch["input_ids"]
        
        # Сгенерировать ответы
        responses = trainer.generate(queries, max_new_tokens=100)
        
        # Оценить ответы
        texts = tokenizer.batch_decode(responses, skip_special_tokens=True)
        rewards = reward_fn(texts)
        
        # Обновление PPO
        stats = trainer.step(queries, responses, rewards)
        trainer.log_stats(stats, batch, rewards)
```

***

## GRPO (Group Relative Policy Optimization)

GRPO используется в DeepSeek-R1 для обучения рассуждению:

```python
# grpo_train.py
from trl import GRPOTrainer, GRPOConfig
from transformers import AutoTokenizer, AutoModelForCausalLM
from datasets import Dataset
import re, torch

model_name = "Qwen/Qwen2.5-7B-Instruct"

model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype=torch.bfloat16,
    device_map="auto",
)
tokenizer = AutoTokenizer.from_pretrained(model_name)

# Математический датасет
def make_math_dataset():
    examples = [
        {"prompt": "Сколько будет 2+2?", "answer": "4"},
        {"prompt": "Сколько будет 15 * 7?", "answer": "105"},
        # ... больше математических задач
    ]
    return Dataset.from_list(examples)

dataset = make_math_dataset()

def correctness_reward(completions, answer, **kwargs):
    """Вознаграждайте 1.0, если ответ верный, и 0.0 в противном случае."""
    rewards = []
    for completion in completions:
        # Извлеките последнее число из завершения
        numbers = re.findall(r'\d+', completion[-1]["content"])
        if numbers and numbers[-1] == answer:
            rewards.append(1.0)
        else:
            rewards.append(0.0)
    return rewards

grpo_config = GRPOConfig(
    output_dir="./grpo_output",
    num_train_epochs=3,
    per_device_train_batch_size=4,
    num_generations=8,       # GRPO генерирует G ответов на каждый запрос
    learning_rate=5e-7,
    bf16=True,
    logging_steps=10,
)

trainer = GRPOTrainer(
    model=model,
    args=grpo_config,
    train_dataset=dataset,
    reward_funcs=correctness_reward,
    tokenizer=tokenizer,
)

trainer.train()
```

***

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

Используйте `accelerate` для распределённого обучения:

```bash
# Настройте accelerate для работы с несколькими GPU
accelerate config

# Пример конфигурации для 4 GPU:
# - compute_environment: LOCAL_MACHINE
# - distributed_type: MULTI_GPU
# - num_processes: 4
# - mixed_precision: bf16

# Запустите обучение на всех GPU
accelerate launch sft_train.py
accelerate launch dpo_train.py

# Или явно указать GPU
CUDA_VISIBLE_DEVICES=0,1,2,3 accelerate launch \
  --num_processes 4 \
  --mixed_precision bf16 \
  sft_train.py
```

***

## Использование CLI TRL

TRL предоставляет удобные команды CLI:

```bash
# SFT через CLI
trl sft \
  --model_name_or_path meta-llama/Llama-3.2-8B-Instruct \
  --dataset_name trl-lib/ultrachat_200k \
  --dataset_text_field messages \
  --output_dir ./cli_sft_output \
  --num_train_epochs 3 \
  --per_device_train_batch_size 2 \
  --gradient_accumulation_steps 4 \
  --learning_rate 2e-4 \
  --bf16 \
  --use_peft \
  --lora_r 16 \
  --lora_alpha 32

# DPO через CLI
trl dpo \
  --model_name_or_path ./cli_sft_output \
  --dataset_name trl-lib/ultrafeedback_binarized \
  --output_dir ./cli_dpo_output \
  --num_train_epochs 1 \
  --beta 0.1 \
  --bf16
```

***

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

```bash
# Следите за загрузкой GPU
watch -n 1 nvidia-smi

# Мониторьте loss обучения (если используете W&B)
# Откройте https://wandb.ai/your-username в браузере

# Проверьте каталог вывода на наличие чекпойнтов
ls -lh sft_output/checkpoint-*/

# Возобновить из чекпойнта
python3 sft_train.py --resume_from_checkpoint sft_output/checkpoint-500/
```

***

## Рекомендации по GPU для Clore.ai

{% hint style="warning" %}
**Многопроцессорные конфигурации с GPU класса 80GB не представлены на маркетплейсе Clore.ai.** Самые крупные доступные сейчас машины — это 4× RTX PRO 6000 Blackwell (по 96GB, всего 380GB) и 8–11× RTX 5090 (по 32GB). Ёмкость A100 / H200 / B200 продаётся как [голое железо](https://clore.ai/bare-metal) по запросу. Проверьте [Цены и доступность GPU](/guides/guides_v2-ru/nachalo-raboty/pricing.md) перед выбором размера развёртывания.
{% endhint %}

Обучение TRL — одна из самых требовательных к VRAM задач. Выбирайте GPU в зависимости от размера модели и метода:

| Задача                                         | GPU                | Примечания                                                                                    |
| ---------------------------------------------- | ------------------ | --------------------------------------------------------------------------------------------- |
| SFT / DPO для 7–8B (QLoRA)                     | **RTX 3090** 24 ГБ | \~8 ГБ для QLoRA 4-bit; удобно помещается; $0.07–0.21/час на Clore.ai                         |
| SFT / DPO для 7–8B (LoRA bf16)                 | **RTX 4090** 24 ГБ | Та же VRAM, что и у 3090, но на 30% быстрее вычисления; отлично подходит для быстрой итерации |
| Полный SFT для 7B или DPO для 13B              | **A100 40 ГБ**     | 40 ГБ хватает для полноточного обучения 7B; память ECC предотвращает скрытые ошибки           |
| PPO / полное дообучение 7B или любой 70B QLoRA | **A100 80 ГБ**     | PPO требует в VRAM 2× policy+ref model; 80 ГБ позволяет запустить оба без OOM                 |

**Практический совет:** Начните с RTX 3090 и QLoRA для экспериментов — обучите Llama 3 8B примерно за 2 часа на 10 тыс. примеров. После проверки пайплайна переходите на A100 80GB для полноточных запусков или моделей 70B.

**Показатели скорости (Llama 3 8B SFT, QLoRA, batch=4, seq=2048):**

* RTX 3090: \~1,100 токенов/с пропускная способность обучения
* RTX 4090: \~1,450 токенов/с
* A100 80GB: \~2,800 токенов/с (полный bf16, без квантования)

***

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

### Недостаточно памяти CUDA

```bash
# Уменьшите размер батча
per_device_train_batch_size=1
gradient_accumulation_steps=16  # Сохраните тот же эффективный размер батча

# Используйте 4-битную квантование (QLoRA)
# Добавьте BitsAndBytesConfig с load_in_4bit=True

# Включите checkpointing градиентов
gradient_checkpointing=True

# Уменьшите длину последовательности
max_seq_length=1024  # вместо 2048+

# Проверьте память GPU
nvidia-smi --query-gpu=memory.used,memory.total --format=csv
```

### Loss — NaN

```bash
# Частая причина: слишком высокий learning rate
learning_rate=1e-5  # Попробуйте ниже

# Частая причина: плохие данные (пустые строки, значения None)
# Проверьте датасет:
python3 -c "
from datasets import load_from_disk
ds = load_from_disk('data/sft_dataset')
print(ds[0])
print(f'Length: {len(ds)}')
# Проверить None
none_count = sum(1 for x in ds if x.get('messages') is None)
print(f'None count: {none_count}')
"

# Включите bf16 вместо fp16 (более стабильно)
bf16=True
fp16=False
```

### DPO: `chosen_rewards > rejected_rewards` ложно

```bash
# Это означает, что модель предпочитает отвергнутые ответы — переобучение или плохие данные
# Решения:
# 1. Проверьте качество датасета
# 2. Уменьшите beta (меньше штраф KL)
# 3. Уменьшите learning rate
# 4. Добавьте больше SFT-обучения перед DPO
beta=0.05  # Попробуйте меньшие значения
```

### Обучение очень медленное

```bash
# Включите Flash Attention 2
pip install flash-attn --no-build-isolation

# В вашем коде:
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    attn_implementation="flash_attention_2",
    torch_dtype=torch.bfloat16,
)

# Используйте bf16 вместо fp16 на GPU Ampere+ (A100, RTX 3000+)
bf16=True

# Увеличьте число workers DataLoader
dataloader_num_workers=4

# Проверьте, что GPU действительно используется
nvidia-smi  # Должно показывать высокую загрузку GPU
```

### `tokenizer.pad_token` предупреждение

```bash
# Стандартное исправление для токенизаторов Llama/Mistral
tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "right"  # Важно для стабильности обучения
```

### Отказано в доступе / HuggingFace 401

```bash
# Войдите заново
huggingface-cli login

# Задайте токен в окружении
export HF_TOKEN=hf_your-token

# Для приватных моделей/датасетов убедитесь, что у вас есть доступ:
# Перейдите на https://huggingface.co/meta-llama/Llama-3.2-8B-Instruct
# Нажмите "Request access" и примите лицензию
```

***

## Сохранение и публикация вашей модели

```bash
# Объедините веса LoRA с базовой моделью
python3 << 'EOF'
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

base_model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-3.2-8B-Instruct",
    torch_dtype=torch.bfloat16,
    device_map="auto"
)
model = PeftModel.from_pretrained(base_model, "./sft_final")
merged = model.merge_and_unload()
merged.save_pretrained("./merged_model")

tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.2-8B-Instruct")
tokenizer.save_pretrained("./merged_model")
print("Объединённая модель сохранена!")
EOF

# Отправить в HuggingFace
huggingface-cli upload your-username/my-trl-model ./merged_model
```

***

## Полезные ссылки

* **GitHub**: <https://github.com/huggingface/trl> ⭐ 10K+
* **Документация**: <https://huggingface.co/docs/trl>
* **Статья по DPO**: <https://arxiv.org/abs/2305.18290>
* **GRPO / DeepSeek-R1**: <https://arxiv.org/abs/2501.12599>
* **Статья по PPO (RLHF)**: <https://arxiv.org/abs/2203.02155>
* **PEFT от HuggingFace**: <https://github.com/huggingface/peft>
* **Weights & Biases**: <https://wandb.ai>
* **Flash Attention**: <https://github.com/Dao-AILab/flash-attention>
* **Маркетплейс Clore.ai**: <https://clore.ai/marketplace>


---

# 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/trl.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.
