Что такое weak supervision для разметки данных для fine-tuning и как его применить?

Краткий тезис

Weak supervision (слабая супервизия) — это подход к автоматической разметке данных, при котором вместо ручного труда инженеров используются эвристики, правила, внешние базы знаний и простые модели (labeling functions). Полученные «шумные» метки затем агрегируются и очищаются статистической моделью (model|generative model), что позволяет за 10% времени создать датасет, близкий по качеству к полностью ручной разметке. Для fine-tuning LLM weak supervision критически важен: он даёт возможность быстро собрать сотни тысяч примеров под конкретную задачу (инструкции, ранжирование контекстов, оценку ответов) без дорогой ручной аннотации. Основные инструменты — Snorkel, Skweak, Flywheel.


1. Понятие weak supervision

Weak supervision — это парадигма data-centric AI, в которой размеченные данные создаются не человеком, а набором «слабых» источников информации. Слабые источники могут быть:

  • Эвристическими правилами: if len(text) > 500: label = 'long'
  • Регулярными выражениями: if re.search(r'error|exception', text): label = 'bug_report'
  • Внешними моделями: предсказания предобученного классификатора или LLM (например, GPT-4 с промптом)
  • Знаниями из баз данных: метки из существующих таблиц, краудсорсинга или логов

Каждый источник несовершенен (шумный, может быть смещён), но в совокупности они позволяют восстановить истинную метку с достаточной точностью.

2. Зачем weak supervision для fine-tuning

Fine-tuning LLM требует большого количества качественных пар (запрос → целевой ответ). evaluation|Ручная разметка:

  • дорогая (эксперт-аннотатор может размечать ~50 примеров/час)
  • медленная (недели для 10k примеров)
  • трудно масштабируется (при смене домена нужно заново)

Weak supervision решает эти проблемы:

  • скорость: генерация меток для 100k примеров занимает минуты
  • стоимость: нулевая (если правила написаны инженером)
  • гибкость: можно быстро переразметить датасет для нового сценария

Для fine-tuning это означает возможность итеративно улучшать модель: если валидация показывает слабые места, вы добавляете новые labeling functions и перезапускаете пайплайн разметки — без повторного обращения к аннотаторам.

3. Основные компоненты weak supervision

3.1 Labeling Functions (LFs)

Labeling function (функция разметки) — это произвольная функция, которая принимает на вход пример (текст, изображение) и возвращает:

  • метку (например, 1 или 0)
  • None (воздержание от метки, если функция не уверена)

LFs могут пересекаться, конфликтовать или быть коррелированными. Пример для задачи классификации запросов (техподдержка vs нет):

import re

def lf_contains_error(text):
    if re.search(r'\b(error|fail|crash)\b', text, re.IGNORECASE):
        return 'tech_support'
    return None

def lf_short_question(text):
    if len(text) < 20:
        return 'general'
    return None

def lf_contains_code(text):
    if '```' in [text](/wiki/text) or re.search(r'\b(def |import |class )', [text](/wiki/text)):
        return 'tech_support'
    return None

3.2 Generative Model (генеративная модель)

Сырые [[Вики/labels|метки]] от [[Вики/rules|LFs]] противоречивы. [[Вики/generative model|Generative model]] — вероятностная [[Вики/model|модель]], которая оценивает [[Вики/accuracy|точность]] каждой LF и их корреляции, чтобы вывести зашумлённую, но консолидированную метку для каждого примера. Это может быть:

  • Простое [[Вики/Voting|голосование]] ([[Вики/Consensus|majority vote]])
  • [[Вики/model|Модель]] логистической регрессии на эмбеддингах [[Вики/rules|LFs]]
  • Специализированная [[Вики/model|модель]] (как в [[Вики/Snorkel|Snorkel]] — [[Вики/factor graph|факторный граф]])

На выходе [[Вики/generative model|generative model]] даёт для каждого примера [[Вики/probability distribution|распределение]] вероятностей по классам (например, P([[Вики/tag|label]]=tech_support)=0.85).

3.3 Denoising (очистка от шума)

После агрегации [[Вики/labels|метки]] обычно дополнительно фильтруются:

  • только примеры с высокой уверенностью (probability > 0.9)
  • [[Вики/duplicate detection|удаление дубликатов]] и конфликтных
  • [[Вики/human-in-the-loop|ручная валидация]] небольшой выборки (100-500 примеров) для оценки качества

4. Этапы применения (пайплайн Snorkel)

  1. Сбор неразмеченных данных — пул примеров (например, все тикеты техподдержки за год).
  2. Написание [[Вики/rules|LFs]] — 10-50 простых правил, основанных на знаниях о домене.
  3. Применение [[Вики/rules|LFs]] — каждая LF проходится по всем примерам, создавая матрицу меток (примеры × [[Вики/rules|LFs]]).
  4. [[Вики/training|Обучение]] [[Вики/generative model|generative model]] — [[Вики/model|модель]] учится по матрице предсказывать истинную метку, оценивая [[Вики/Noise|шум]] и корреляции.
  5. Получение вероятностных меток — для каждого примера получаем P([[Вики/tag|label]] | [[Вики/rules|LFs]]).
  6. Фильтрация/отбор — оставляем только надёжные примеры.
  7. [[Вики/SFT|Fine-tuning]] — обучаем [[Вики/model|модель]] на полученном датасете.

5. Сравнение подходов к разметке

МетодСкорость (10k примеров)СтоимостьКачествоМасштабируемость
[[Вики/Human evaluation|Ручная разметка]]несколько недельвысокаявысокоенизкая
[[Вики/multiple annotators|Crowdsourcing]] (Amazon MTurk)днисредняясреднеесредняя
[[Вики/weak supervision|Weak supervision]] (Snorkel)часынизкаясреднее/высокоевысокая
LLM-based labeling (GPT-4)минутысредняя (токены)высокое (но дорого)очень высокая
[[Вики/active learning|Активное обучение]]смешаннаясредняявысокоесредняя

[[Вики/weak supervision|Weak supervision]] занимает нишу: высокая скорость при низкой стоимости, качество, достаточное для [[Вики/fine-tuning|fine-tuning]] (часто ~80-95% от ручной).

6. Преимущества и риски

Преимущества:

  • Снижение затрат на разметку на 80-90%
  • Скорость итераций (вы меняете [[Вики/rules|LFs]] → новый [[Вики/dataset|датасет]] за час)
  • Возможность разметки в доменах, где нет экспертов (медицина, юриспруденция) — достаточно написать [[Вики/Rule-based executor|правила]] по документации
  • Комбинация с [[Вики/GPT-4o|LLM]]: [[Вики/GPT-4o|LLM]] может выступать как одна из [[Вики/rules|LFs]]

Риски и [[Вики/constraints|ограничения]]:

  • Шумные [[Вики/labels|метки]]: если все [[Вики/rules|LFs]] смещены одинаково, [[Вики/generative model|generative model]] не сможет «выпрямить» [[Вики/labels|метки]]
  • Нужен этап валидации: хотя бы небольшая ручная [[Вики/sampling|выборка]] для калибровки
  • Сложность написания хороших [[Вики/rules|LFs]] для сложных концепций (например, сарказм)
  • Возможен [[Вики/bias|перекос]] в сторону простых правил (oversimplification)

7. Пример кода (Snorkel)

Упрощённая реализация пайплайна для разметки датасета вопросов.

import [snorkel](/wiki/Snorkel)
from [snorkel](/wiki/Snorkel).labeling import labeling_function, [PandasLFApplier](/wiki/PandasLFApplier), [LFAnalysis](/wiki/LFAnalysis)
from [snorkel](/wiki/Snorkel).labeling.[model](/wiki/model) import LabelModel

# Определяем LFs
@labeling_function()
def lf_contains_error([text](/wiki/text)):
    return 1 if 'ошибка' in [text](/wiki/text).lower() else -1  # 1 = tech, -1 = воздержание

@labeling_function()
def lf_long_text([text](/wiki/text)):
    return 1 if len([text](/wiki/text)) > 200 else -1

@labeling_function()
def lf_question_mark([text](/wiki/text)):
    return 0 if '?' in [text](/wiki/text) else -1   # 0 = general

# Применяем
applier = [PandasLFApplier](/wiki/PandasLFApplier)([lf_contains_error, lf_long_text, lf_question_mark])
L_train = applier.apply(df'[text](/wiki/text)')

# Анализ
summary = [LFAnalysis](/wiki/LFAnalysis)(L_train, lfs).lf_summary()
print(summary)

# Обучаем generative [model](/wiki/model)
label_model = LabelModel([cardinality](/wiki/cardinality)=2, verbose=True)
label_model.fit(L_train, n_epochs=500, log_freq=100, [seed](/wiki/seed)=123)
preds = label_model.predict(L_train, tie_break_policy='[abstain](/wiki/ABSTAIN)')
[probabilities](/wiki/probabilities) = label_model.[predict_proba](/wiki/predict_proba)(L_train)

8. Применение к fine-tuning LLM

8.1 Instruction tuning (Supervised Fine-Tuning, SFT)

[[Вики/weak supervision|Weak supervision]] подходит для создания датасета ([[Вики/instruction|instruction]] → [[Вики/Answer|answer]]). Например:

  • [[Вики/rules|Правила]]: если текст содержит "напиши статью" → [[Вики/tag\|метка]] "creative_writing"
  • [[Вики/GPT-4o|LLM]] как LF: [[Вики/prompt|промпт]] к [[Вики/gpt-3.5-turbo|GPT-4]] "К какому типу относится [[Вики/Prompt engineering|запрос]]: [[Вики/Agentic planning|planning]], editing, coding?" — один из источников меток.

[[Вики/aggregation|Агрегация]] меток от разных [[Вики/rules|LFs]] даёт размеченный [[Вики/dataset|датасет]] для [[Вики/fine-tuning|SFT]].

8.2 Preference tuning (DPO, RLHF)

Для обучения предпочтений нужны пары (хороший ответ/плохой ответ). [[Вики/weak supervision|Weak supervision]] может:

  • Вычислять [[Вики/confidence score|score]] от нескольких эвристик (длина, наличие цитат, читаемость)
  • Использовать другую LLM как judge (LLM-as-a-judge) — это тоже слабая метка
  • Агрегировать через generative model в бинарное предпочтение

8.3 Fine-tuning для RAG

Для RAG-системы нужно размечать релевантность (документ релевантен запросу или нет). Weak supervision:

  • BM25 + косинусное сходство (как эвристика)
  • Правила: если в документе есть ключевые слова запроса → релевантен
  • LLM промпт: "Ответь Yes/No — отвечает ли документ на вопрос?"

Snorkel легко справляется с таким сценарием.

9. Альтернативы weak supervision

  • [[Вики/active learning|Active learning]]: модель сама выбирает, какие примеры разметить человеку. Дороже, но качественнее.
  • Data augmentation: генерация синтетических примеров из размеченного ядра. Не требует меток, но может создавать нереалистичные образцы.
  • Zero-shot / few-shot LLM: использовать LLM напрямую для разметки. Быстро, но дорого и не всегда точно (зависит от модели).
  • [[Вики/fine-tuning|Transfer learning]]: брать предобученную модель и дообучать на малом размеченном датасете — это не разметка, а уже обучение.

Weak supervision часто комбинируют с другими методами: например, сначала размечают слабо 100k примеров, потом обучают модель, а активным обучением доразмечают сложные случаи.

10. Инструменты и фреймворки

  • [[Вики/Snorkel|Snorkel]] (Stanford) — основной фреймворк для weak supervision. Поддержка текста, изображений, таблиц. Модуль snorkel.labeling + LabelModel.
  • [[Вики/Skweak|Skweak]] — лёгкая альтернатива для текста, основанная на spaCy. Подходит для NER и классификации.
  • [[Вики/Flywheel|Flywheel]] — коммерческая платформа с weak supervision и active learning.
  • [[Вики/Label Studio|Label Studio]] — позволяет писать правила и комбинировать с ручной разметкой.
  • [[Вики/датасеты|Hugging Face Datasets]] — есть интеграция с Snorkel.

11. Оценка качества слабой разметки

Даже без золотого стандарта можно оценить:

  • [[Вики/coverage|Coverage]] — доля примеров, которые помечены хотя бы одной LF (желательно >80%)
  • Conflicts — доля примеров с противоречивыми метками
  • Accuracy of LF on small validation set — если есть 100-500 ручных меток, считаем точность каждой LF и generative model
  • [[Вики/Inter-annotator agreement|Inter-annotator agreement]] (между LFs) — высокая корреляция может говорить о смещении
  • [[Вики/downstream metrics|Downstream performance]] — лучшее измерение: после fine-tuning считаем метрики на тестовом наборе

12. Связь с Agentic RAG

В контексте Agentic RAG weak supervision может размечать:

  • [[Вики/AI agents|Действия агента]] (search, calculator, code_execute) на основе логов
  • Релевантность контекстов для retrieval (к какому шагу агента относится документ)
  • Оценку успешности траектории (агент решил задачу или нет) — по правилам (наличие ответа, отсутствие ошибок)

Snorkel легко интегрируется в пайплайн сбора данных для RL-based fine-tuning агентов.


Пет-проект для закрепления

[[Вики/Task|Задача]]: Создать датасет для fine-tuning LLM, которая будет отвечать на технические вопросы (классифицировать вопросы как "требующие кода" или "теоретические").

Инструменты: Python, Snorkel, pandas, небольшой датасет из Stack Overflow (5-10k вопросов).

Шаги:

  1. Загрузить неразмеченные вопросы из stackoverflow_posts.csv.
  2. Написать 5-7 labeling functions:
    • lf_has_code — содержит ``` или inline code
    • lf_mentions_language — Python, JavaScript, C++ и т.д.
    • lf_short_general — < 20 слов → отметка "теоретический"
    • lf_contains_error — error, exception, bug → "код"
    • lf_question_type — "как", "почему" → скорее теория
  3. Применить LFs, обучить LabelModel, получить вероятности.
  4. Отфильтровать примеры с уверенностью >0.9 (останется ~60-80%).
  5. Создать файл labeled_questions.json с колонками: question, label (0/1), confidence.
  6. Fine-tune небольшого LLM (например, T5, Gemma-2B) на этих данных для классификации.

Ожидаемый результат:

  • Размеченный датасет ~5000 примеров за 1 час работы (написание LFs + выполнение)
  • Точность на ручной валидации (300 примеров) ~85%
  • Fine-tuned модель с accuracy ~82% (против 90% при полной ручной разметке, но в 10 раз быстрее)

Связь с другими вопросами

ВопросТема
257Data augmentation для fine-tuning
259Active learning для разметки
260RLHF и сбор данных для предпочтений
261Synthetic data generation (LLM as judge)
256Instruction tuning: сбор датасета
262Data quality и чистка датасета

Навигация