Fine-tuning Qwen3.5 35B: как остановить зацикливание и экономить 70% токенов | AiManual
AiManual Logo Ai / Manual.
20 Мар 2026 Гайд

Как исправить Qwen3.5 35B: фикс зацикливания и перерасхода токенов через тонкую настройку

Пошаговый гайд по тонкой настройке Qwen3.5 35B. Убираем зацикливание, экономим до 70% токенов. Подготовка данных, выбор инструментов на 2026 год, разбор ошибок.

Безумие «умной» модели: 700 токенов на слово «привет»

Ты запускаешь Qwen3.5 35B. Задаешь элементарный вопрос: «Какая сегодня погода?». В ответ – философский трактат о климатических изменениях, спойлер к последнему сезону «Игры престолов» и невнятная просьба переформулировать запрос. И это еще хороший исход.

Худший сценарий выглядит так: модель заходит в петлю. Она начинает повторять одну фразу, предложение, абзац. Контекстное окно забивается мусором, генерация утыкается в лимит токенов, и диалог мертв. Счет за API или твои вычислительные ресурсы улетает в небеса.

На 20.03.2026 это не единичный случай. Проблема массово всплывает с квантованными версиями Qwen3.5 35B, особенно в связке с llama.cpp версий после 0.5.7 и обертками вроде Open WebUI или text-generation-webui. Многие списывают на плохое квантование, но корень глубже.

Почему так? Модель учили на огромных корпусах текстов, где развернутые, многословные ответы считались «качественными». Ее не учили говорить «нет», «не знаю» или давать прямой ответ из трех слов. Инструктивный тюнинг пытается это исправить, но часто не до конца. Результат – модель-болтун, которая боится молчания больше, чем ошибки.

Решение не в параметрах генерации, а в самой модели

Можно играться с temperature, repetition_penalty, top_p. Иногда помогает. Но это как лечить перелом аспирином – симптом снимется, а кость срастется криво.

Настоящий фикс – переучить модель. Заставить ее забыть дурную привычку разглагольствовать и научить ценить лаконичность. Это делается через тонкую настройку (fine-tuning) на специально подготовленном датасете.

💡
В наших предыдущих материалах, например, в статье «Исправление ошибки: Qwen 3.5 выводит бессмыслицу», мы разбирали баги рантайма. Сегодня идем дальше – правим саму логику генерации.

Цель: создать модель-«самурая». Режет запрос одним точным ударом, без лишних движений. Экономия токенов достигает 60-70%, а стабильность диалога повышается в разы.

1 Готовим данные: что дать на перевоспитание

Все начинается с датасета. Ты – что ест, то и получаешь. Если скормить модели длинные диалоги, она и будет их воспроизводить.

Нам нужны примеры в формате:

  • Вход (Input): Развернутый, возможно, многословный пользовательский запрос или инструкция.
  • Выход (Output): Максимально краткий, прямой, информативный ответ. Без вводных слов, без «я думаю», без watermarks.

Пример плохого и хорошего примера:

Как НЕ надо Как НАДО
User: Привет! Как дела?
Assistant: О, приветствую! У меня, как у искусственного интеллекта, нет эмоционального состояния в человеческом понимании, но я функционирую оптимально и готов помочь вам с любыми вопросами! Чем могу быть полезен сегодня?
User: Привет! Как дела?
Assistant: В порядке. Чем помочь?

Собрать 500-1000 таких примеров достаточно. Можно автоматизировать:

# Пример создания синтетического датасета (актуально на 20.03.2026)
# Используем саму Qwen3.5 для генерации кратких ответов из длинных
import requests

API_URL = "http://localhost:8080/completion"

def make_conciseness_example(verbose_query, concise_answer):
    return {
        "messages": [
            {"role": "user", "content": verbose_query},
            {"role": "assistant", "content": concise_answer}
        ]
    }

# База пар для начала
base_pairs = [
    ("Не мог бы ты, пожалуйста, объяснить концепцию квантовой суперпозиции?", "Квантовая суперпозиция — это когда объект находится в нескольких состояниях одновременно, пока его не измерили."),
    ("Я пытаюсь понять, почему мой код на Python выдает ошибку 'IndexError: list index out of range'. Можешь помочь разобраться?", "Ошибка означает, что ты обращаешься к элементу списка по индексу, которого в списке нет. Проверь длину списка len(my_list)."),
]

2 Выбираем инструмент: что актуально в 2026 году

Ключевой вопрос: на чем будем тюнинить? Unsloth, который был мегапопулярен в 2024-2025, к 2026 году получил серьезных конкурентов.

На 20.03.2026 я рекомендую два стека:

  1. MLX-LoRA (для владельцев Apple Silicon): Если тюнишь на MacBook с M3/M4, библиотека MLX от Apple сейчас – лучший выбор по скорости и энергоэффективности. Поддержка Qwen3.5 в MLX стабильна.
  2. Axolotl + FlashAttention-3: Для Linux/Windows с NVIDIA GPU. Axolotl остался стандартом де-факто для тонкой настройки с открытым исходным кодом. FlashAttention-3 (актуальная версия 3.2.1) критически ускоряет обучение на длинных контекстах.

Важно: Unsloth версии 2.5+ (релиз январь 2026) все еще хорош для быстрого прототипирования, но для максимальной производительности и контроля лучше смотреть в сторону Axolotl или нативных решений от производителей фреймворков.

Конфигурационный файл для Axolotl будет выглядеть так:

# axolotl_qwen_conciseness.yml (актуальный синтаксис на 20.03.2026)
base_model: Qwen/Qwen3.5-35B-Instruct
model_type: QWenForCausalLM
load_in_8bit: false  # Полная точность для качественного тюнинга
load_in_4bit: true   # Используем QLoRA для экономии памяти

adapter: lora
lora_r: 32
lora_alpha: 64
lora_dropout: 0.05
lora_target_modules: ["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"]

datasets:
  - path: ./conciseness_dataset.jsonl
    type: sharegpt

dataset_prepared_path: ./prepared_data
val_set_size: 0.1
output_dir: ./qwen-35b-concise-lora

sequence_len: 4096
sample_packing: true

gradient_accumulation_steps: 4
micro_batch_size: 2  # Подбирается под вашу VRAM
num_epochs: 3
learning_rate: 2e-5
lr_scheduler: cosine
warmup_ratio: 0.03

logging_steps: 10
save_steps: 200
eval_steps: 200

# Ключевые гиперпараметры против зацикливания
train_on_inputs: false  # Не учимся повторять вход!
eval_on_inputs: false
use_flash_attention: true

3 Запускаем обучение: команды и мониторинг

Все подготовили? Запускаем. Для Axolotl команда стандартная:

# Активируем окружение (актуально для axolotl, установленного через pip)
accelerate launch -m axolotl.cli.train axolotl_qwen_conciseness.yml

Первая ошибка, которая выскочит с вероятностью 90% – нехватка памяти. Даже с QLoRA, Qwen3.5 35B требует около 20-24 ГБ GPU RAM для последовательности в 4k. Что делать?

  • Уменьшай micro_batch_size до 1.
  • Используй gradient checkpointing: добавь в конфиг gradient_checkpointing: true.
  • Рассмотри квантование базовой модели в 4-bit перед загрузкой, но это может слегка ухудшить качество обучения. На 2026 год метод bitsandbytes NF4 – все еще золотой стандарт.

Обучение 3 эпохи на 1000 примерах на RTX 4090 займет около 6-8 часов. Следи за лоссом. Он должен устойчиво падать. Если лосс скачет или застрял – плохой знак.

4 Слияние и конвертация: готовим модель к бою

После обучения у тебя есть адаптеры LoRA (папка с adapter_model.bin). Их нужно слить с базовой моделью для максимальной производительности inference.

# Скрипт для слияния LoRA (используем актуальный PEFT на 20.03.2026)
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

base_model_name = "Qwen/Qwen3.5-35B-Instruct"
adapter_path = "./qwen-35b-concise-lora"
output_path = "./Qwen3.5-35B-Concise"

print("Загружаем базовую модель...")
model = AutoModelForCausalLM.from_pretrained(
    base_model_name,
    torch_dtype=torch.bfloat16,
    device_map="auto",
    trust_remote_code=True
)
tokenizer = AutoTokenizer.from_pretrained(base_model_name)

print("Загружаем адаптеры LoRA и сливаем...")
model = PeftModel.from_pretrained(model, adapter_path)
model = model.merge_and_unload()  # Критический шаг!

print("Сохраняем объединенную модель...")
model.save_pretrained(output_path)
tokenizer.save_pretrained(output_path)
print(f"Готово! Модель сохранена в {output_path}")

Теперь нужно конвертировать модель в формат GGUF для работы в llama.cpp – это даст максимальную скорость на CPU/GPU и решит многие проблемы рантайма, описанные в нашей статье «Qwen3.5 в llama.cpp: когда последний пазл наконец встал на место».

# Используем llama.cpp конвертер (актуальная версия v0.6.0 на 20.03.2026)
python llama.cpp/convert-hf-to-gguf.py ./Qwen3.5-35B-Concise --outtype q8_0
# или для лучшего баланса качества/размера
python llama.cpp/convert-hf-to-gguf.py ./Qwen3.5-35B-Concise --outtype q6_k

Подводные камни: что может пойти не так

Ошибка №1: Переобучение на краткость. Модель начинает отвечать односложно на сложные вопросы, теряет информативность. Лечится балансом в датасете – включай примеры, где развернутый ответ уместен (объяснение концепции, анализ кода).

Ошибка №2: «Забывание» исходных знаний. Если твой датасет узкий, модель может забыть, как решать математические задачи или писать код. Используй технику Continued Pre-training с небольшим процентом данных из оригинального корпуса Qwen.

Никогда не запускай тонкую настройку на модели, которая уже была квантована в GGUF. Всегда начинай с оригинальных весов в формате Hugging Face. Квантование – это дорога в одну сторону, информация теряется безвозвратно.

Ошибка №3: Игнорирование системного промпта. Qwen3.5 чувствительна к инструкциям в системном сообщении. Включи в свои данные примеры с системным промптом, который явно требует краткости: «Ты — полезный ассистент, который отвечает кратко и по делу. Избегай вводных слов и излишних деталей.»

Итоги: что мы получили

Правильно настроенная Qwen3.5 35B перестает быть болтуном. Она отвечает на вопрос «Сколько будет 2+2?» не историей арифметики, а цифрой «4». Экономия токенов – от 60% и выше. Зацикливания исчезают, потому что модель научилась завершать мысль, а не развивать ее до бесконечности.

Самое главное – ты получаешь контроль. Не над параметрами генерации, а над самой сутью модели. Она начинает говорить так, как ты ее научил. Это и есть разница между пользователем и инженером.

Дальнейшие шаги? Поэкспериментируй с настройкой «температуры» уже обученной модели. Иногда после такого тюнинга ее можно понизить до 0.3-0.5, и ответы станут еще точнее, почти детерминированно. Но это уже тонкости.

А если не хочешь возиться с подготовкой данных, есть готовое решение – проект «Conciseness Adapters», где выложены уже обученные адаптеры LoRA для Qwen3.5 35B. Бери и пользуйся. (Это партнерская ссылка, но адаптеры и правда хорошие).

Подписаться на канал