|
Разработка Датасетов для тренинга локальных моделей ИИ.
Разрабатываю Датасеты (Datasets) для тренировки (Fine Tuning) локальных моделей ИИ (LoRA, QLoRA). Датасеты в несколько тысяч JSON примеров. Специализированные наборы примеров для дообучения. Разработка Python скриптов для дообучения.
Оптимальные методы дообучения
Полное дообучение (Full Fine-Tuning) всех параметров модели требует огромных ресурсов.
Токенизация IP-адресов
Главная проблема токенизации IP-адресов в LLM (включая Qwen 2.5) заключается в том, что токенизатор Byte-Pair Encoding (BPE) бьет IP-адрес на случайные куски. Например, адрес 192.168.1.15 может превратиться в токены ["192", ".16", "8.", "1", "15"]. Из-за этого модель плохо понимает границы октетов, путает маски и «галлюцинирует» в цифрах.
Один из способов решить эту проблему при дообучении:
Добавление специальных токенов (Самый надежный способ)Вы можете заставить токенизатор воспринимать критически важные элементы как неделимые атомарные токены.Что добавить: Все 4 октета со всеми возможными точками.
Реализация в коде:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")
# Создаем список токенов для всех возможных вариантов октетов с точками
# Например: ".0", ".1", ... ".255" и "0.", "1.", ... "255."
special_tokens = []
for i in range(256):
special_tokens.extend([f".{i}", f"{i}.", f"/{i}"]) # Добавляем и маски /24, /32
# Добавляем в токенизатор
tokenizer.add_tokens(special_tokens)
# ВАЖНО: После добавления токенов нужно расширить эмбеддинги модели перед обучением
# model.resize_token_embeddings(len(tokenizer))
Результат: Токенизатор перестанет разрывать связку «точка+цифра» случайным образом. Каждый октет и маска станут четкими визуальными границами для ИИ.
Пример Промпта >>
Dataset Development (Удаленная работа)
Удаленная работа >>
Для дообучения Qwen 2.5 (7B) под анализ сетевых таблиц лучше всего использовать фреймворк Unsloth. Он работает в 2–3 раза быстрее стандартного Hugging Face / TRL, использует гораздо меньше видеопамяти и нативно поддерживает расширение эмбеддингов для наших кастомных IP-токенов.
Ниже представлен готовый, рабочий Python-скрипт. Этот скрипт объединяет первый метод решения проблемы токенизации (добавление специальных IP-токенов) и конфигурацию LoRA высокой емкости.
Готовый скрипт обучения (train_qwen_network.py)
import torch
from datasets import load_dataset
from trl import SFTTrainer
from transformers import TrainingArguments, AutoTokenizer
from unsloth import FastLanguageModel
# 1. Настройки конфигурации
max_seq_length = 4096 # Длина контекста для больших таблиц show ip route
dtype = None # Автоопределение (Float16 для Tesla T4/V100, Bfloat16 для Ampere+)
load_in_4bit = True # Использовать 4-битное квантование (QLoRA) для экономии VRAM
# 2. Загрузка модели и токенизатора через Unsloth
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="Qwen/Qwen2.5-7B-Instruct",
max_seq_length=max_seq_length,
dtype=dtype,
load_in_4bit=load_in_4bit,
)
# 3. Решение проблемы токенизации: добавляем неделимые IP-токены
print("Добавление кастомных IP-токенов в словарь...")
special_tokens = []
for i in range(256):
special_tokens.extend([f".{i}", f"{i}.", f"/{i}"])
# Добавляем маски и специфичные для Cisco префиксы, чтобы они не дробились
special_tokens.extend(["/8", "/16", "/24", "/30", "/32"])
tokenizer.add_tokens(special_tokens)
# Расширяем матрицу эмбеддингов модели под новый размер словаря
model.resize_token_embeddings(len(tokenizer))
# 4. Настройка параметров LoRA под сетевую специфику
model = FastLanguageModel.get_peft_model(
model,
r=64, # Высокий ранг для точного запоминания структуры таблиц
target_modules=[ # Адаптируем все линейные слои Qwen
"q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"
],
lora_alpha=128, # Пропорционально рангу (r * 2)
lora_dropout=0, # Ноль для строгого синтаксического обучения без хаоса
bias="none",
use_gradient_checkpointing="unsloth", # Максимальная экономия памяти
random_state=3407,
)
# 5. Подготовка шаблона данных (ChatML формат)
# Скрипт ожидает JSONL-файл, где каждая строка содержит "system", "user" и "assistant"
def format_prompts(examples):
texts = []
for sys, usr, ast in zip(examples["system"], examples["user"], examples["assistant"]):
text = (
f"<|im_start|>system\n{sys}<|im_end|>\n"
f"<|im_start|>user\n{usr}<|im_end|>\n"
f"<|im_start|>assistant\n{ast}<|im_end|>"
)
texts.append(text)
return {"text": texts}
# Замените 'dataset.jsonl' на путь к вашему файлу
dataset = load_dataset("json", data_files="dataset.jsonl", split="train")
dataset = dataset.map(format_prompts, batched=True)
# 6. Конфигурация процесса обучения (Hyperparameters)
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=dataset,
dataset_text_field="text",
max_seq_length=max_seq_length,
dataset_num_proc=2,
packing=False, # Не упаковываем короткие маршруты вместе, чтобы не путать контекст
args=TrainingArguments(
per_device_train_batch_size=2, # Можно увеличить до 4, если позволяет VRAM
gradient_accumulation_steps=4, # Итоговый батч равен 2 * 4 = 8
warmup_steps=10, # Плавный старт
max_steps=100, # Количество шагов (настройте под размер датасета)
learning_rate=2e-4, # Стандартный шаг для LoRA
fp16=not torch.cuda.is_bf16_supported(),
bf16=torch.cuda.is_bf16_supported(),
logging_steps=1, # Логи на каждом шаге
optim="adamw_8bit", # Оптимизатор, экономящий VRAM
weight_decay=0.01,
lr_scheduler_type="linear",
seed=3407,
output_dir="qwen2.5-cisco-lora-output",
),
)
# 7. Запуск обучения
print("Старт дообучения модели...")
trainer_stats = trainer.train()
# 8. Сохранение результатов
# Сохраняем только обученные LoRA-веса и обновленный токенизатор
model.save_pretrained("qwen2.5_7b_cisco_lora")
tokenizer.save_pretrained("qwen2.5_7b_cisco_lora")
print("Обучение завершено. Адаптер сохранен!")
Как запустить этот скрипт:
Установите необходимые библиотеки (лучше в чистом окружении conda или venv):
pip install unsloth "xformers<0.0.27" trl datasets transformers accelerate bitsandbytes
Подготовьте файл dataset.jsonl в той же папке. Каждая строка должна быть валидным JSON объектом (с полями system, user, assistant).
Запустите: python train_qwen_network.py
После дообучения.
По поводу объединения матриц: физически объединять веса сразу во время обучения не нужно, но для продакшена (использования) это крайне рекомендуется. У вас есть два пути работы с результатом:
Вариант 1. Запуск «на лету» (Без объединения)
При инференсе вы можете загружать оригинальную (базовую) модель Qwen 2.5 в режиме «только для чтения» и динамически подгружать ваш маленький адаптер.
Плюсы: Адаптер весит всего 50–200 МБ. Вы можете обучить 10 разных адаптеров (для Cisco, для Juniper, для логов Linux) и переключать их на одной и той же базовой модели, экономя место на диске.
Минусы: Запуск через стандартный Hugging Face transformers будет работать медленнее. Обычные легковесные движки вроде Ollama не умеют эффективно работать с раздельными LoRA-весами для Qwen.
Вариант 2. Объединение весов (Merge LoRA) - Рекомендуемый путь
Вы берете оригинальные веса Qwen 2.5 (15 ГБ) и математически вшиваете в них обученные коэффициенты вашего адаптера. На выходе получается одна монолитная модель, которая теперь «из коробки» идеально понимает таблицы Cisco.
Плюсы: Максимальная скорость работы. Модель можно запустить через vLLM, TGI, LM Studio или конвертировать в формат GGUF для работы внутри Ollama.
Минусы: Итоговая модель весит столько же, сколько базовая (около 15 ГБ для версии 7B).
Как объединить веса (Код на Python)
Поскольку обучение мы запускали через Unsloth, процесс слияния (Merge) делается буквально одной строчкой кода. Создайте файл merge_weights.py и запустите его после завершения обучения:
from unsloth import FastLanguageModel
max_seq_length = 4096
# 1. Загружаем базовую модель И наш сохраненный адаптер вместе
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "qwen2.5_7b_cisco_lora", # Путь к сохраненному адаптеру из прошлого шага
max_seq_length = max_seq_length,
dtype = None,
load_in_4bit = False, # ДЛЯ СЛИЯНИЯ МОДЕЛЬ ДОЛЖНА БЫТЬ В 16-бит (не в 4-бит!)
)
# 2. Сохраняем объединенную модель в 16-битном формате (Float16 или Bfloat16)
# Unsloth автоматически выполнит математическое слияние весов перед записью на диск
print("Запуск процесса слияния весов...")
model.save_pretrained_merged(
"qwen2.5-7b-cisco-final-merged",
tokenizer,
save_method = "merged_16bit",
)
print("Готово! Монолитная модель сохранена в папку qwen2.5-7b-cisco-final-merged")
После выполнения этого скрипта папка qwen2.5-7b-cisco-final-merged будет содержать полноценную, готовую к любым инсталляциям модель.
Удаленная работа
ROUTING Datasets
cisco_routing_summarization_v2_dataset_KIMI5.jsonl >>
cisco_routing_summarization_dataset_KIMI1.jsonl >>
cisco_routing_extended_dataset_KIMI2.jsonl >>
cisco_routing_blackhole_dataset_KIMI3.jsonl >>
cisco_routing_ad_conflicts_dataset_KIMI4.jsonl >>
routing_table_dataset_KIMI6.jsonl >>
routing_protocol_specific_dataset_Z-AI-12.jsonl >>
routing_protocol_specific_dataset_QWEN12.jsonl >>
routing_protocol_specific_dataset_KIMI12.jsonl >>
routing_metric_anomalies_dataset_Z-AI-9.jsonl >>
routing_metric_anomalies_dataset_Z-AI-8.jsonl >>
routing_metric_anomalies_dataset_KIMI8.jsonl >>
routing_load_balancing_dataset_KIMI6.jsonl >>
routing_inefficiencies_dataset_KIMI7.jsonl >>
routing_healthy_tables_dataset_Z-AI-10.jsonl >>
routing_healthy_tables_dataset_KIMI10.jsonl >>
routing_edge_cases_dataset_Z-AI-11.jsonl >>
routing_edge_cases_dataset_QWEN11.jsonl >>
routing_edge_cases_dataset_KIMI11.jsonl >>
routing_discontiguous_networks_dataset_KIMI9.jsonl >>
AI Fine Tuning >>
Удаленная работа >>
Prompts Developer >>
Screenplay >>
Proxmox Virtual Environment >>
https://huggingface.co/
|
|