Всем привет! Меня зовут Артем, я DS в компании Raft. Эта статья - полноценный гайд по дообучению с Unsloth, в котором мы разберём: что такое Unsloth, как выбрать метрики и гиперпараметры, как шаг за шагом использовать unsloth исследователям и разработчикам. Ниже я приложу весь код, который понадобится для обучения Qwen3 на медицинском датасете по МКБ по деменции.
Во второй части статьи я приведу свои лайфхаки для улучшения качества файнтьюнинга и поделюсь результатами реальных экспериментов.

Начнем с того, что такое Unsloth и с оглавления статьи.
📘 Сводный анализ ответов моделей на вопросы с использованием Chat Gpt
Что ты такое и зачем ты нужен?
Обучение и finetuning больших языковых моделей (LLM) требует значительных вычислительных ресурсов. Сейчас можно использовать библиотеку TRL от huggingface для обучения. Однако проект Unsloth предлагает инновационное решение, позволяющее ускорить этот процесс в несколько раз без потери качества.
По заявлениям разработчиков он может уменьшить потребление видеопамяти до 70% и ускорить обучение в несколько раз.

Достигается это за счет того, что все вычислительные ядра (kernels) переписаны с нуля с использованием языка Triton от OpenAI, который предназначен для создания высокоэффективных GPU-вычислений и использование переписанного pytorch autograd.
В итоге мы имеем:
Ускорение обучения в 2–5 раз благодаря оптимизации вычислений.
Снижение потребления памяти до 70% за счёт эффективного управления ресурсами.
Поддержка популярных моделей, включая Llama 3, Mistral, Gemma и другие.
Интеграция с Hugging Face и совместимость с существующими инструментами.
Это всё делает Unsloth эффективным, быстрым и удобным.
⚙️ Пробуем unsloth
Давайте попробуем обучить модель с помощью Unsloth шаг за шагом.
Подготовка к обучению
Мы будем использовать Rye в качестве менеджера пакетов.
Установка Rye🌾
🌾 Rye: Лёгкий менеджер пакетов для Python, отлично подходит для reproducible окружений. Установка через
curl
- быстрая и удобная.
curl -sSf https://rye.astral.sh/get | bash
После этого создадим и инициализируем проект
mkdir article
cd article
rye init
rye pin 3.13
rye sync
Добавим Unsloth, transformers, TRL в качестве зависимостей. Нам также понадобятся пакеты для ноутбуков ipywidgets и ipykernel, а также nltk и evaluate для метрики. Pandas используется для датасетов. Также при установке нам может понадобиться cmake, clang++ для сборки пакетов.
rye add unsloth unsloth-zoo trl transformers peft evaluate pandas tqdm ipywidgets ipykernel nltk pyarrow
Сделаем папку для ноутбука и датасетов
mkdir notebooks
cd notebooks
touch unsloth_test.ipynb
Пара слов про датасет. В этом туториале мы будем использовать заранее подготовленный мной датасеты. Они включают в себя вопросы, основанные на одной из глав МКБ-10. А именно про деменцию (с кода F00 до F03.4x).

Скачать датасеты можно по ссылке: ссылка
Либо здесь: Unsloth_article
Перейдём к подготовке ноутбука. Для его написания будем использовать VS Code. Для начала сделаем необходимые импорты:
import unsloth # Must be before than trl, transformers etc.
from unsloth import FastLanguageModel
import os
from dataclasses import dataclass
from pathlib import Path
import evaluate
import numpy as np
import pandas as pd
from datasets import Dataset
from tqdm.auto import tqdm
from transformers.trainer_utils import EvalPrediction
from trl import SFTConfig, SFTTrainer
Пройдемся по ним 📦:
Unsloth – сама библиотека. Она должна быть импортирована перед trl, transformers и другими библиотеками от hf.
pandas и dataset – для работы с датасетом
TRL – для обучения
evaluate – для метрики, чтобы мы могли измерять качество на eval.
Сделаем некоторые шаги до выполнения всего кода:
os.environ["UNSLOTH_RETURN_LOGITS"] = "1"
tqdm.pandas()
Дальше прочитаем наши датасеты:
ds_dir = Path("../dataset/")
ds_pth = ds_dir / "formatted(0).parquet"
eval_ds_pth = ds_dir / "formatted(0)_evaluate.parquet"
dataset = pd.read_parquet(ds_pth)
eval_dataset = pd.read_parquet(eval_ds_pth)
Создадим dataclass в котором будут находится часть наших настроек
@dataclass(slots=True, frozen=True)
class Config:
# LoRa Parameters
rank: int = 32
lora_alpha: int = 64
attention_layers: tuple = ("q_proj", "k_proj", "v_proj", "o_proj")
mlp_layers: tuple = ("gate_proj", "up_proj", "down_proj")
use_dora: bool = False
# SFT trainer params
gradient_accumulation_steps: int = 2
num_train_epochs: int = 5
# Unsloth parameters
load_in_4bit: bool = True # Need if model in bnb 4bit
model_url: str = "unsloth/Qwen3-8B-unsloth-bnb-4bit"
conf = Config()
Подготовка модели
Следующим шагом нам нужно будет загрузить саму модель, которую мы будем обучать. Мы будем обучать Qwen3-8B. Если захотите обучить другую LLM, то тогда вам нужно будет заменить model_url в классе с конфигом. Желательно взять её из репозитория unsloth на hf:
model, tokenizer = FastLanguageModel.from_pretrained(
conf.model_url, load_in_4bit=conf.load_in_4bit, max_seq_length=128000
)
model = FastLanguageModel.get_peft_model(
model,
r=conf.rank,
lora_alpha=conf.lora_alpha,
target_modules=list(conf.attention_layers) + list(conf.mlp_layers),
use_dora=conf.use_dora,
max_seq_length=tokenizer.model_max_length,
)
Подготовка метрики для оценки модели
Для оценки на eval мы будем использовать метрику meteor. Я её выбрал, потому что она основана на поиске совпадений слов (unigrams) между машинным и эталонным переводом, при этом учитываются не только точные совпадения, но и совпадения по корню (стемминг) и синонимы. Существуют и другие метрики, но для их использования может понадобиться Gpu.
💡 Note:
METEOR – метрика, основанная на анализе n-грамм и ориентированная на использование статистической и точной оценки исходного текста. Данная метрика использует функции сопоставления синонимов вместе с точным соответствием слов.
ссылка на источник
evaluator = evaluate.load(path="meteor")
И нам также понадобится функция для того, чтобы передать её в trainer. Она будет выполняться во время обучения и считать нашу метрику:
def evaluate_fn(predict_labels: EvalPrediction):
logits = predict_labels.predictions
labels = predict_labels.label_ids
skip_token = -100
labels = np.where(labels != skip_token, labels, tokenizer.pad_token_id)
decoded_labels = tokenizer.batch_decode(labels)
predict = np.argmax(logits, axis=-1)
decoded_predictions = tokenizer.batch_decode(predict)
result = evaluator.compute(
predictions=decoded_predictions, references=decoded_labels
)
return result
Подготовка датасета
Для этого мы определим пару вспомогательных функций. Первая функция конвертирует текст в токены, а вторая преобразовывает сам датасет в класс Dataset из библиотеки от hf "datasets":
def batch_encode(batch: dict):
tokens = tokenizer(
batch["content"],
padding=True,
truncation=True,
max_length=tokenizer.model_max_length
)
return tokens
def to_hf_dataset(df: pd.DataFrame) -> Dataset:
ds_tmp = {"group_id": [], "content": []}
for group_id, group in df.groupby("group_id"):
msg = group.to_dict("records")
content = tokenizer.apply_chat_template(msg, tokenize=False)
ds_tmp["group_id"].append(group_id)
ds_tmp["content"].append(content)
dataset_hf = Dataset.from_dict(ds_tmp)
dataset_hf = dataset_hf.map(batch_encode, batched=True)
return dataset_hf
И сделаем вызов этих функций:
dataset_hf = to_hf_dataset(dataset)
eval_dataset_hf = to_hf_dataset(eval_dataset)
Проверим, что в конце вопроса у нас содержится eos token
assert dataset_hf["content"][0][-len(tokenizer.eos_token) - 1:].strip() == tokenizer.eos_token
Настройка параметров для обучения
Затем сформируем параметры для обучения:
sft_conf = SFTConfig(
output_dir="trained", # Каталог для сохранения обученной модели и артефактов
eval_strategy="steps", # Стратегия оценки модели: по шагам (каждые logging_steps)
logging_steps=50, # Частота логирования и оценки (каждые 50 шагов)
load_best_model_at_end=True, # Загружать лучшую модель по заданной метрике после обучения
eval_accumulation_steps=1, # Кол-во шагов для накопления метрик во время оценки
num_train_epochs=conf.num_train_epochs, # Количество эпох обучения (взято из конфига)
gradient_accumulation_steps=conf.gradient_accumulation_steps, # Кол-во шагов для накопления градиентов (из конфига)
warmup_steps=20, # Кол-во шагов для прогрева learning rate перед основной фазой обучения
auto_find_batch_size=True, # Автоматический подбор максимально большого batch size
per_device_train_batch_size=4, # Размер батча для обучения на одном устройстве (GPU/TPU)
per_device_eval_batch_size=1, # Размер батча для оценки на одном устройстве
eval_on_start=True, # Выполнять оценку модели перед началом обучения
save_strategy="best", # Сохранять модель только при улучшении метрики
metric_for_best_model="meteor", # Метрика, по которой определяется лучшая модель (здесь METEOR)
bf16=True, # Использовать bfloat16 для ускорения и экономии памяти
report_to="none" # Отключить отчетность в системы логирования (например, wandb, tensorboard)
)
И создадим сам trainer:
trainer = SFTTrainer(
model,
tokenizer=tokenizer,
train_dataset=dataset_hf,
eval_dataset=eval_dataset_hf,
compute_metrics=evaluate_fn,
max_seq_length=tokenizer.model_max_length,
args = sft_conf
)
Обучение
Мы подготовили всё самое необходимое и теперь можем вызывать основной метод обучения:
trainer.train()
Дальше trainer от hf сделает всё сам. В конце обучения сохраним модель:
trainer.save_model("model")
Экспорт в ollama
На данном этапе мы уже можем использовать модель через, например, hf и transformers, либо через unsloth. Я приложу один из вариантов использование модели - это экспорт модели в gguf для дальнейшего использования её в ollama. Существует несколько способов это сделать:
Экспортировать всю модель. Для этого необходимо сделать merge модели и адаптера и в дальнейшем экспортировать её в gguf.
Экспортировать только адаптер. Этот вариант более легковесный, так как нам нужно будет экспортировать только сам адаптер.
Экспорт всей модели
С помощью Python сделаем merge модели и сохранение в 16bit.
from unsloth import FastLanguageModel
model, tokenizer = FastLanguageModel.from_pretrained(".", load_in_4bit=True)
model.save_pretrained_merged("merged_model_16bit", tokenizer)
Через один из скриптов llama.cpp конвертируем модель в GGUF:
python convert_hf_to_gguf.py ../train/trained/article_v5_dora/merged_model_16bit/ -outfile article_v5.gguf -outtype bf16
Дальше создадим Modelfile для нашей модели
FROM "article_v5.gguf"
TEMPLATE """{{- if .Messages }}
{{- if or .System .Tools }}<|im_start|>system
{{- if .System }}
{{ .System }}
{{- end }}
{{- if .Tools }}
# Tools
You may call one or more functions to assist with the user query.
You are provided with function signatures within <tools></tools> XML tags:
<tools>
{{- range .Tools }}
{"type": "function", "function": {{ .Function }}}
{{- end }}
</tools>
For each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:
<tool_call>
{"name": <function-name>, "arguments": <args-json-object>}
</tool_call>
{{- end }}<|im_end|>
{{ end }}
{{- range $i, $_ := .Messages }}
{{- $last := eq (len (slice $.Messages $i)) 1 -}}
{{- if eq .Role "user" }}<|im_start|>user
{{ .Content }}<|im_end|>
{{ else if eq .Role "assistant" }}<|im_start|>assistant
{{ if .Content }}{{ .Content }}
{{- else if .ToolCalls }}<tool_call>
{{ range .ToolCalls }}{"name": "{{ .Function.Name }}", "arguments": {{ .Function.Arguments }}}
{{ end }}</tool_call>
{{- end }}{{ if not $last }}<|im_end|>
{{ end }}
{{- else if eq .Role "tool" }}<|im_start|>user
<tool_response>
{{ .Content }}
</tool_response><|im_end|>
{{ end }}
{{- if and (ne .Role "assistant") $last }}<|im_start|>assistant
{{ end }}
{{- end }}
{{- else }}
{{- if .System }}<|im_start|>system
{{ .System }}<|im_end|>
{{ end }}{{ if .Prompt }}<|im_start|>user
{{ .Prompt }}<|im_end|>
{{ end }}<|im_start|>assistant
{{ end }}{{ .Response }}{{ if .Response }}<|im_end|>{{ end }}"""
SYSTEM "You are medical assistant."
Дальше нужно добавить модель. Это можно сделать с помощью команды:
ollama create article_v5 -f Modelfile
Всё! Мы успешно добавили модель в ollama.
Экспорт только адаптера
Мы можем также экспортировать адаптер в gguf и подгрузить его в ollama. Для этого нам понадобится другой скрипт из библиотеки llama.cpp
. А именно convert_lora_to_gguf.py
. Тогда наша команда будет выглядеть так:
./llama.cpp/convert_lora_to_gguf.py article_v4
Где article_v4 – это путь к папке с адаптером (файл adapter_model.safetensor). Но здесь стоит быть аккуратным, т.к не все адаптеры могут конвертироваться в формат gguf. Например, при использовании dora, такой адапетр не может быть переконвертирован сразу в gguf. Мы получим следующую ошибку:
⚠️ Error:
ERROR:lora-to-gguf:Unexpected name 'base_model.model.model.layers.0.mlp.down_proj.lora_magnitude_vector': Not a lora_A or lora_B tensor
После выполнения команды мы получим файл с адаптером в формате gguf. Он будет находиться в папке с адаптером. В моем случае он называется Article_V4-F16-LoRA.gguf.
Дальше нам нужно будет написать Modelfile в котором мы укажем путь до адаптера и базовую модель. Для этого стоит немного переписать Modelfile из прошлого пункта и вместо
FROM "article_v5.gguf"
Написать
FROM qwen3:8b-fp16
ADAPTER Article_V4-F16-LoRA.gguf
Вот и все изменения, которые нам нужно сделать
Дальше мы также через ollama создаем модель
ollama create article_v4 -f Modelfile
На этом этапе мы научились запускать обучение, подготавливать датасет и экспортировать модель в ollama для её последующего использования. Дальше перейдем к результатам моих экспериментов. Они интересны тем, что можно сравнить точность полученных моделей при обучении с использованием LoRa/Dora, разных параметров ранка и включением в обучающие слои mlp_layers.
Метрики и результаты экспериментов 📊
Я провел серию экспериментов по обучению, чтобы мы могли сравнить разные подходы и результаты, которые мы получили.
№ модели | rank | lora_alpha | dora | mlp_layers | Время обучения |
---|---|---|---|---|---|
article_v1 | 8 | 16 | False | False | 29m 28s |
article_v2 | 8 | 16 | True | False | 59m 11s |
article_v3 | 8 | 16 | True | True | 1h 22m 12s |
article_v4 | 8 | 16 | False | True | 30m 26s |
article_v5 | 16 | 32 | True | True | 1h 22m 17s |
article_v6 | 32 | 64 | True | True | 1h 22m 25s |
article_v7 | 128 | 256 | False | True | 33m 48s |
⚠️ Warning:
При использовании dora Unsloth не оптимизирует слои модели в результате этого модель обучается значительно дольше.
В результате обучения мы получили следующие результаты

Из них мы видим, что модели, которые обучались только на слоях q_proj, k_proj, o_proj, v_proj показывают результаты хуже, чем те которые дополнительно обучались на слоях gate_proj, up_proj, down_proj. Также мы можем заметить, что в зависимости от ранка матрицы мы получаем более хорошие показатели метрики. Но у этого также есть и минусы. Например, чем больше мы rank мы используем тем больше ресурсов может потребоваться для обучения, да и вес самого адаптера тоже увеличится. Также не стоит забывать про проблему катастрофического забывания.
💡 Note:
Катастрофическое забывание - это явление, при котором нейросеть, обучаясь на новых данных или задачах, теряет способность хорошо выполнять ранее изученные задачи. Это особенно выражено в сценариях continual learning (непрерывного обучения), когда модель должна адаптироваться к новым данным без доступа ко всему предыдущему датасету. Причина забывания - обновления весов при обучении на новых данных могут нарушать те параметры, которые были важны для старых задач, что приводит к быстрой деградации знаний о них
Для примера мы задали каждой из llm один и тот же вопрос, который не входит в обучающий датасет.
Вопрос №1
Сам вопрос: Кто такой мамонт?
Ответы: Ответы сохранены в google таблицу, т.к в хабре они не очень хорошо отображаются. Табличка
Анализировать ответы я буду с помощью ChatGpt, т.к это быстрее и удобнее
Анализ от ChatGpt
Вот подробный анализ ответов моделей с указанием ошибок:
📌 Выводы:
Модель | Оценка | Проблемы |
---|---|---|
| 🟢 Хорошо | Мелкие биологические неточности (уши, копыта, термин "мамуль") |
| 🔴 Плохо | Смешение понятий: мамонты названы неандертальцами |
| 🟢 Хорошо | Научно корректный, краткий |
| 🟡 Норм | Ошибка по эпохе (неолит), остальное верно |
| 🔴 Плохо | Вымысел: палеотерии, подземное обитание, эпоха голода |
| 🟡 Норм | Ошибки в геологическом периоде и датировке |
| 🟡 Норм | Слишком кратко, не раскрыта география |
| 🟢 Хорошо | Мелкие временные неточности, в целом точно |
✅ Без существенных ошибок:
🟢 qwen3:8b-fp16
Содержание: Ответ структурирован, научно достоверен, включает описание внешности, среды обитания, причин вымирания, роли в жизни людей.
Мелкие недочёты:
Упомянуто, что на "задних лапах - копыта", что некорректно - у мамонтов, как и у слонов, все ноги имеют одинаковую анатомию с копытцевидными ногтями, а не копытами.
Уши описаны как "широкие для отвода тепла" - у мамонтов как раз маленькие уши (в отличие от африканских слонов) - для сохранения тепла, а не его отвода.
"Мамонт с мамулем" - не существует животного "мамуль" - это, видимо, выдумка или ошибка.
🟢 article_v2
Содержание: Чётко, кратко, по делу. Упомянуты классификация, физические особенности, ареал, вымирание.
Мелкие недочёты: нет значимых ошибок, ответ корректный, хотя мог бы быть чуть более подробным.
⚠️ Содержат фактические ошибки:
🔴 article_v1
❌ Грубая ошибка: утверждение, что "мамонт - это подгруппа неандертальцев" - абсолютно неверно.
→ Мамонты - это животные, а не люди. Неандертальцы - это вымершие гоминиды, а не таксономическая группа, в которую можно включать животных.❌ Вся последующая информация основана на этой ошибке: "узкое лицо", "тип волос", "размер тела" и т.д. - всё это описание человека, не животного.
💡 Вывод: Модель полностью спутала биологические таксоны мамонтов и неандертальцев.
🔴 article_v4
❌ "Мамонт - это вымершее животное, относящееся к группе палеотерев, обитавшее в недрах Земли до эпохи голода." - здесь сразу три ошибки:
Палеотерии - это отдельный вымерший род лошадеподобных млекопитающих, не имеющий отношения к мамонтам.
"Обитавшее в недрах Земли" - мамонты не жили под землёй, это травоядные наземные животные.
"До эпохи голода" - такой эпохи не существует в научной хронологии.
💡 Вывод: Ответ абсурден и биологически неверен.
🟡 article_v3
🟠 В целом ответ корректен, но краткий.
❌ Ошибка в терминологии: "до эпохи неолита" - лучше бы сказать "до начала неолита" или "до голоцена", т.к. некоторые карликовые мамонты жили ещё 4 тыс. лет назад, то есть уже в неолите.
💡 Вывод: Мелкая временная неточность, в остальном - допустимо.
🟡 article_v5
🟠 Основной текст корректен.
❌ Ошибка в периодах: "палеогеновый и неогеновый период" - мамонты не жили в палеогене, максимум - с позднего миоцена (неоген), основное распространение - плейстоцен.
❌ Формулировка "до 4000 лет назад в голоцене" - неправильная хронология: голоцен начался 11 700 лет назад, и часть мамонтов дожила до его середины, но не с начала голоцена.
💡 Вывод: Хронологические неточности.
🟡 Недостаточно раскрыты или упрощены:
🟡 article_v6
Корректный, но очень краткий.
❗ Формулировка "группа плейстоценовых млекопитающих" допустима, но лучше указать таксон - род Mammuthus, семейство слоновых.
❗ "Сибирского региона" - ограничивает географию, хотя мамонты были распространены и в Европе, и в Северной Америке.
🟢 article_v7
В целом хороший и аккуратный ответ, но:
❗ "Северной Америки и Евразии до эпохи неолита" - см. замечание выше к
article_v3
: неолита уже существовал, когда вымерли последние мамонты (остров Врангеля, ~4 тыс. лет назад).❗ Также можно уточнить, что "близкие к современным слонам" - это родственники, но не прямые предки.
Вопрос №2
Вопрос: Какую теоретическую модель гравитации предложил Максвелл в своей работе 1873 года, и как она повлияла на квантовую гравитацию Хокинга?
Ответы: Табличка
Анализ от ChatGpt
📌 Выводы:
Модель | Оценка | Проблемы |
---|---|---|
| 🟢 Хорошо | Ответ научно корректен, структурирован, ясно обозначено отсутствие модели гравитации у Максвелла |
| 🔴 Плохо | Галлюцинации: связь эфира Максвелла с Хокингом, вымышленные аналогии |
| 🟢 Хорошо | Кратко и корректно. Чётко указано, что Максвелл не занимался гравитацией |
| 🟢 Хорошо | Также научно корректный ответ, без галлюцинаций |
| 🟡 Слабо | Прямо указано отсутствие влияния, но в остальном построен на ошибочных исторических связях |
| 🔴 Плохо | Исторически неверное утверждение о геометрии и связи с Хокингом |
| 🔴 Плохо | Вымышленная связь тензоров с Максвеллом, ошибки в трактовке понятий |
| 🔴 Плохо | Галлюцинация о гравитационной теории Максвелла на эфире, не подтверждается ни источниками, ни фактами |
✅ Без ошибок (qwen3:8b-fp16
, article_v2
, article_v3
)
Указано, что Максвелл не создавал теорию гравитации;
Обосновано косвенное влияние на теорию поля и последующее развитие КТП;
Корректно отделено прямое и косвенное влияние на научные направления.
⚠️ Частично корректный (article_v4
)
Отмечено отсутствие влияния Максвелла на Хокинга;
Однако ошибочно указано, что Максвелл предлагал модель гравитационного поля.
❌ Ошибки и галлюцинации:
article_v1
: ложная связь эфира с Хокингом, вымышленные "квантовые среды";article_v5
: приписывание Максвеллу римановой геометрии;article_v6
: вымышленная тензорная модель у Максвелла;article_v7
: ложная эфирная модель и её влияние на квантовую гравитацию.
💡 Общий вывод:
Только 3 модели (Qwen3, article_v2, article_v3) ответили полностью корректно.
Остальные либо галлюцинируют, либо используют недостоверные исторические или физические связи между Максвеллом и Хокингом.
Особенно распространённая ошибка - придумывание прямого влияния теории Максвелла на Хокинга, чего не было. Максвелл - основа теории полей, но не автор гравитационных моделей.
Мой анализ
Давайте попробуем проанализировать полученные результаты:
Первое, что бросается в глаза – это забывчивость модели article_v1 и article_v3 . Модели сильно галлюцинировали. Можно также сказать, что ответ становится грубым и не таким полным, как у оригинальной модели.
Практически во всех экспериментов мы видим, что появляются какие-то неточности.
Модели стали хуже размышлять.
С увеличением ранка модель становится чуть аккуратнее и менее грубой. Хоть при этом на данных, которые модель не видела на процессе обучения, ответы становятся более короткими.
dora немного увеличила метрики и при этом местами поборолась с забывчивостью при маленьких ранках, например, это хорошо видно для второго вопроса про модель Гравитации. Модель версии v2 и v3 (в которых использовалась dora) не cгаллюцинировали в отличии от модели v1 и v4. На больших ранках dora уже не помогла и модель начала галлюцинировать.
Стоит отметить, что подбор параметров для обучения – очень важная часть. И мы должны подобрать параметры так, чтобы минимизировать ошибки и при этом побороться с проблемами. Поэтому сейчас мы перейдем к тому, ради чего это и затевалось. Обучилась ли модель необходимым данными?
Мы возьмём один вопрос из обучающего датасета и два из датасета для eval. В eval датасете находятся вопросы, которые похожи на вопросы из обучающей выборки и подразумевают такой же ответ. Например
Вопросы из датасета для обучения
Расскажи про 'F00* Деменция при болезни Альцгеймера (G30.-+)' по МКБ-10 /no_think
Что такое болезнь Альцгеймера и каковы ее основные характеристики? /no_think
Вопрос из датасета для eval
Опиши код "F00 Деменция при болезни Альцгеймера (G30.-+)" согласно МКБ-10 /no_think
Дайте определение болезни Альцгеймера и перечислите её ключевые признаки /no_think
Вопрос №3
Вопрос: Расскажи про 'F00* Деменция при болезни Альцгеймера (G30.-+)' по МКБ-10 /no_think (вопрос из датасета)
Ответы: Табличка
Анализ от ChatGpt
Вот строгое сравнение всех представленных ответов в сравнении с эталонным ("Правильный ответ"). Критерии оценки: полнота, структурированность, медицинская корректность, соответствие формулировкам МКБ-10, отсутствие выдуманных сведений.
Оценка вариантов:
qwen3:8b-fp16
Сильно упрощён, но с длинным вступлением про разницу между F и G разделами.
Много организационных, не медицинских деталей («не является стандартным в МКБ-10»), акцент на классификации, таблицы.
Нет детального описания ни клинических, ни морфологических признаков, ни дифференциальной диагностики.
Не дано специфических диагностических критериев, стадий и типов F00. Вывод: Недостаточно глубокий и медицински поверхностный ответ.
article_v1
Есть структурированность, названия подразделов.
Текст содержит много досадных ошибок и ложных сведений: «апноэ Мендельсона», «амитрофические изменения», «депрессивный/устойчивый тип БА», «глобусы Picks'a» (ошибка!), «связь с экзофтальмом», наличие «аутосомно-рецессивного типа», что не характерно для современной классификации.
Нет нормативной структуры критериев диагностики как в оригинале.
Формулировки неверны, зачастую придуманы. Вывод: Наличие значимых ошибок и вымышленных сведений делает этот вариант плохим.
article_v2
Имеется попытка воспроизвести структуру, но во многих местах фантазии: неточно описанные подразделы (F00.00, F00.01, F00.02, F00.10 и так далее), ненормативная детализация стадий, признаки не из МКБ-10, а из СВОЕЙ внутренней классификации.
Диагностические указания и клинические критерии не соответствуют оригиналу МКБ-10 (нет формулировки по пунктам), отсутствуют морфологические детали.
«F00.21* Деменция привередливого типа» - выдумка.
Значительные домыслы в структуре. Вывод: Не соответствует ключевым разделам МКБ-10, содержит придуманные подразделения.
article_v3
Стартует с корректного описания, есть отсылки к нейроморфологии, но появляются неверные или вымышленные термины: «грануловаскулярные тельца» описаны неточно, акцент на инструментальных методах (полейсцеребеллярная атаксия - не относящееся).
Нет списочной структуры диагностических критериев.
Искажения в разделах F00.2х и ниже, лишняя детализация «пятый дополнительный знак», не характерная для МКБ-10. Вывод: Присутствуют домыслы и некорректная терминология, нет нормальной структуры диагностических критериев.
article_v4
В начале использует англоязычное слово ("progresses insidiously"), иначе в целом пересказывает верно общую канву.
Структура не соответствует оригиналу: выделены категории по степени тяжести (F00.0 тяжелая, F00.1 средняя, F00.2 легкая) - это не соответствует структуре оригинального ответа.
Перечни включают много сведений, которых нет в классификации МКБ-10 (например, "потеря сознания" не характерна!).
Немного случайных диагнозов во включениях. Вывод: Не верна классификация и структура, есть фактические ошибки.
article_v5
Почти дословно повторяет "Правильный ответ", вплоть до ключевых формулировок по критериям, стадиям (F00.0х, F00.1х, F00.2х, F00.9х), особенностям течения, патогномоничным морфологическим изменениям, списку дифференциального диагноза.
Охватывает диагностические критерии списком, выделяет включаемые и исключаемые состояния, выявляет особенности смешанных форм, как требует МКБ-10.
Практически никакой фактологической ошибки, лексика максимально близка к нормативной формулировке. Вывод: Лучший вариант, структурно, содержательно и по детализации на 99% совпадает с "Правильным ответом".
article_v6
Внешне почти идентичен article_v5, также максимально точен.
Присутствует чуть менее уместная ремарка про диагностическую ценность "результатов исследований, доказывающих наличие амилоидных бляшек", но в целом оформление, структурирование, детализация находятся на том же уровне. Расхождения минимальны.
Без значительных отклонений от стандарта МКБ-10. Вывод: Отличный вариант, практически так же хорош, как v5.
article_v7
Практически идентичен article_v5 и v6, с очень минимальными изменениями формулировок (например, "сведения о наличии болезни Дауна или лимфоидоза", "атипичная деменция, тип 3"), структура полностью выдержана, критерии, дифференциальный диагноз, морфологические особенности перечислены верно.
В детализации соответствует "Правильному ответу", медико-лексический стандарт соблюден. Вывод: Также максимально полный и верный вариант.
Окончательный вывод
Лучший и полностью верный вариант - это: article_v5 (а также article_v6 и article_v7 практически идентичны). article_v5 максимально детализирован, строго следует структуре (морфологические, клинические, диагностические критерии, подразделы по типу F00), отсутствуют домыслы, присутствует полный перечень сведений необходимый по МКБ-10.
Рейтинг:
article_v5 (лучший, почти дословно эталонный ответ)
article_v6 и article_v7 (почти такие же, разница минимальна)
article_v3 и article_v4 (имеют ошибок меньше, чем остальные, но неточные и с вымыслом)
article_v1, article_v2 (ошибочные, вымышленные фрагменты)
qwen3:8b-fp16 (очень поверхностно, классификация только)
Вопрос №4
Вопрос: Опиши код "F00 Деменция при болезни Альцгеймера (G30.-+)" согласно МКБ-10 /no_think (вопрос из eval)
Ответы: Табличка
Анализ от СhatGpt
Сравнение детальности и корректности - вопрос: «Опиши код "F00 Деменция при болезни Альцгеймера (G30.-+)" согласно МКБ-10».
Правильный ответ (эталон) - большой, подробный, с перечислением диагностических критериев, уточнением вариантов (по началу, тяжести), выдачей кодировки, нюансами сочетаний, исключениями, диффдиагнозом, и пр.
Анализ ответов моделей
qwen3:8b-fp16
Содержит базовые сведения о F00/G30, упоминает связь кодов, типы G30, объясняет сочетание “+”, но без углубления в клиническую картину, диагностические критерии и подтипы.
Кратко, простым языком, очевидной основной информации достаточно для общего назначения.
article_v1
Очень кратко: «код F00 используется для диагностики деменции, связанные с болезнью Альцгеймера, независимо от формы и этапа», не дает детализации и вариантов, не раскрывает критерии.
Уровень изложения ниже даже базового.
article_v2
Схож по структуре с v1; слегка пояснено, что код связан с болезнью Альцгеймера, дополнительного кода, как в инструкции - нет.
Поверхностно, крайне кратко.
article_v3
Начинается с ошибочного описания «Дефицит мультиинфарктной деменции», уходит в описание мультиинфарктной деменции, почти не относится к Альцгеймеру.
Описан не тот код и не та патология.
Самый плохой вариант.
article_v4
Длинный, детализованный ответ с попыткой перечисления стадий и критериев (легкая, средняя тяжесть, тяжелая), но терминология и структура частично вымышленные, не соответствуют МКБ-10 и эталону.
Много клинических критериев не соответствует действительности, много искусственных делений.
Информации много, но точность крайне низкая, искажает суть.
article_v5
Стиль близкий к правильному; повторяет «Болезнь Альцгеймера - первичное дегенеративное...», описывает старт (ранний/поздний), морфологию, сочетанные состояния, критерии, встречается описание патологии мозга, нейрофибриллярных сплетений, нейротрансмиттеры.
Описаны формы - F00.0x (с ранним началом), F00.1x (с поздним), F00.2x (атипичная или смешанная), F00.9x (неуточнённая).
Список показаний для диагноза, исключения, особенности кодирования, сочетания с сосудистой деменцией и др.
Почти идентичен эталону и очень близок к идеалу.
article_v6
Вариант почти полностью идентичен правильному ответу (видимо, использован один источник или реставрация эталона).
Чрезвычайно похож по структуре, терминологии, критериям.
Максимальная детализация и соответствие.
article_v7
Тоже практически слово в слово совпадает с эталоном. Перечислены диагностические указания, формы, дифференциальный диагноз, соответствие клинико-лабораторным критериям, перечисление подтипов F00.
Соответствует эталону почти полностью.
Итоговая оценка
article_v3: Полностью неверно - отвечает не о том коде.
article_v1/v2: Очень поверхностно.
qwen3:8b-fp16: Информативнее кратких, но без глубины, подтипов, отсутствуют критерии и примеры.
article_v4: Притворная детализация, обычно термины и структура не соответствуют эталону и реальной МКБ-10.
article_v5, article_v6, article_v7: Почти идеальное совпадение с эталоном, полная детализация, соблюдён клинический и кодовый контекст.
Лучший вариант - article_v6 и article_v7 (одинаковые по содержанию, радикально совпадают с эталоном), затем article_v5.
Рейтинг:
article_v6 / article_v7 - отлично, абсолютно детальный, верный.
article_v5 - также очень корректен, практически идентичен верхним.
qwen3:8b-fp16 - базово, пригодно для общего описания, но не для специалиста.
article_v1 / article_v2 - слишком кратко, не помогает для работы с диагнозом и особенностями.
article_v3 - вообще неверно (не тот код, не та болезнь).
article_v4 - плохо: много и поверхностно выдуманной инфы, неточность.
Правильный ответ в соответствии с критериями детализации и точности совпадает с article_v6 / article_v7.
Вопрос №5
Вопрос: Дайте определение болезни Альцгеймера и перечислите её ключевые признаки /no_think (вопрос из eval)
Ответ: Табличка
Анализ от ChatGpt
Эталон:
Болезнь Альцгеймера - это первичное дегенеративное церебральное заболевание неизвестной этиологии, проявляющееся характерными нейропатологическими и нейрохимическими изменениями. Для нее типично постепенное и медленно прогрессирующее течение, часто с началом в позднем возрасте.
Оценка моделей (строгое сравнение с эталоном):
1. qwen3:8b-fp16
ОПРЕДЕЛЕНИЕ: Указано, что это хроническое прогрессирующее нейродегенеративное заболевание, причина деменции.
СИМПТОМЫ: Перечислены симптомы и стадии.
ОТКЛОНЕНИЯ: Использует формулировки из клинической практики, выходит за рамки морфологического, нейрохимического описания, гораздо более “прикладной” и расширенный, чем эталон.
Совпадает по сути, но добавляет много клинических симптомов (не свойственно эталону) и даёт описание стадий (в эталоне отсутствует).
2. article_v1
ОПРЕДЕЛЕНИЕ: Близко к эталону, но добавляет “irreversible ухудшение…”, не даёт морфологической детали.
СИМПТОМЫ: Описывает течение (постепенное, медленное), тяжесть и исход (смерть - в эталоне нет).
Нет морфологических признаков, менее полный по определению.
3. article_v2
ОПРЕДЕЛЕНИЕ: Совпадает с эталоном.
СИМПТОМЫ: Перечисляет нарушения памяти, мышления, поведения, двигательную активность.
Есть странности (“посадочным сплетением волос”).
Очень близок по структуре, но содержит одну ошибку.
4. article_v3
ОПРЕДЕЛЕНИЕ: Совпадает с эталоном.
СИМПТОМЫ: Описывает когнитивные и эмоциональные нарушения, однако термин “язвочесотка” некорректен.
Близко, но с ошибкой.
5. article_v4
ОПРЕДЕЛЕНИЕ: Совпадает с эталоном, расширено (“нейрофизиологические изменения”).
СИМПТОМЫ: Описывает нарушения памяти, мышления, поведения, “гипертензия” - не относится к Альцгеймеру.
Есть лишнее, но в целом эталонно.
6. article_v5
ОПРЕДЕЛЕНИЕ: Совпадает с эталоном.
СИМПТОМЫ: Указывает медленное течение, позднее начало, добавляет морфологические детали (амилоидные бляшки и т.д.), что есть и в эталоне.
Наиболее детальное совпадение с эталоном по структуре описания.
7. article_v6
ОПРЕДЕЛЕНИЕ: Почти идентично эталону.
СИМПТОМЫ: Кратко указаны основные характеристики, отсутствие отдельных морфологических признаков, но структура ситуация “эталонная”.
8. article_v7
Полный повтор эталонного текста.
Краткий итог
article_v7 - практически калька эталона, совпадает максимально.
article_v5 - полностью совпадает по структуре и дополнительно детализирует морфологические изменения, как и в эталоне (нейропатология - амилоидные бляшки, нейрофибриллярные сплетения, что чуть подробнее нормы).
article_v6 и article_v2/v3/v4 - близко, но article_v6 и article_v4 чуть дальше от эталонной структуры.
qwen3:8b-fp16 - качественный, но уходит далеко за пределы эталона, делая акцент на симптомах и клиническом течении, что в эталоне отсутствует.
Лучший по точному совпадению с эталоном
article_v7 - абсолютно повторяет эталонный ответ, поэтому является наилучшим при строгом сравнении с эталоном.
Последовательное место:
article_v7 (максимально идентичен эталону)
article_v5 (идентичен + чуть более детализирована морфология - допустимо, если нужен “расширенный эталон”)
Остальные - с отклонениями от эталона, ошибками или без нужной детализации.
Вывод:
article_v7 - лучший вариант, если критерий - строгое соответствие эталонному ответу.
📘 Сводный анализ ответов моделей на вопросы с использованием Chat Gpt
Общий вывод
Модели article_v5
, article_v6
и article_v7
продемонстрировали наилучшую точность, структурированность и соответствие формулировкам МКБ-10 по всем трём вопросам. Остальные модели - либо содержат критические ошибки, либо недостаточно детализированы.
Итоговая оценка моделей
Модель | Точность | Структура | Медицинская корректность | Итоговая оценка |
---|---|---|---|---|
| ✅ | ✅ | ✅ | 🥇 Эталон |
| ✅ | ✅ | ✅ | 🥇 Эталон |
| ✅ | ✅ | ✅ | 🥈 Почти эталон |
| ⚠️ | ⚠️ | ✅ | ⚠️ Поверхностный, справочный |
| ❌ | ⚠️ | ❌ | ⚠️ Структура без достоверности |
| ❌ | ❌ | ❌ | ❌ Критические ошибки |
| ❌ | ❌ | ❌ | ❌ Критические ошибки |
| ❌ | ❌ | ❌ | ❌ Не по теме, ошибки |
Группировка по качеству
🥇 Лидеры (эталонные модели)
article_v7
- полностью повторяет правильный ответ, без отклонений.article_v6
- аналогично, очень точный.article_v5
- идентичен по сути, с лёгкими допустимыми расширениями.
⚠️ Средний уровень
qwen3:8b-fp16
- минимальная польза, кратко и без ошибок, но нет глубины.article_v4
- стремится к структуре, но содержит выдумки и искажения классификации.
❌ Низкий уровень
article_v1
/article_v2
- содержат вымышленные признаки, некорректные формулировки.article_v3
- не соответствует вопросу, описывает другую патологию.
Общие наблюдения
Модели, близкие к эталону, устойчиво воспроизводят правильную структуру даже при разных формулировках вопросов.
Ошибочные модели часто создают нереальные подтипы, вводят фантазийные термины, или неправильно используют классификацию МКБ-10.
Поверхностные модели (например,
qwen3
) - пригодны для общего представления, но не для медицинского применения.
Рекомендации
Для профессионального или обучающего применения - использовать только
article_v5
,article_v6
илиarticle_v7
.Остальные варианты требуют ручной рецензии и не подходят без доработки.
📌 Выводы
Unsloth действительно ускоряет обучение LLM и позволяет использовать даже слабые GPU - особенно эффективно в связке с 4bit-квантованием. Все эксперименты проводились на RTX 4090 (24 GB VRAM).
Наилучшие результаты по точности показали модели с включёнными DoRA и MLP-слоями при
rank ≥ 32
. Эти конфигурации обеспечивают баланс между качеством генерации и стабильностью обучения.Катастрофическое забывание сохраняется, особенно при малых значениях
rank
. Это критично при работе с ограниченными данными.Экспорт в GGUF возможен для полноценных моделей, однако DoRA-адаптеры пока не поддерживаются этим форматом.
При работе с медицинскими данными особенно важно соблюдение достоверности. Только модели
article_v5
,v6
иv7
показали приемлемую точность; остальные требуют существенной доработки перед практическим использованием.Файнтюнинг не гарантирует улучшения качества и порой может привести к обратному эффекту.