← Назад к вопросам

Обучал ли модели генеративного ИИ

1.2 Junior🔥 201 комментариев
#Машинное обучение

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Опыт обучения генеративных моделей

Да, у меня есть значительный практический опыт обучения генеративных моделей — от простых VAE до современных диффузионных моделей и больших языковых моделей.

1. Текстовые генеративные модели

Fine-tuning GPT-подобных моделей

from transformers import TextDataset, Trainer, TrainingArguments
from transformers import AutoModelForCausalLM, AutoTokenizer

# Подготовка данных
dataset = TextDataset(
    tokenizer=tokenizer,
    file_path="data.txt",
    block_size=512
)

# Настройка обучения
training_args = TrainingArguments(
    output_dir="./model_output",
    overwrite_output_dir=True,
    num_train_epochs=3,
    per_device_train_batch_size=8,
    save_steps=500,
    save_total_limit=2,
    logging_steps=100,
    learning_rate=5e-5,
    weight_decay=0.01,
    warmup_steps=500,
    use_cuda=True,
)

# Обучение
trainer = Trainer(
    model=model,
    args=training_args,
    data_collator=data_collator,
    train_dataset=dataset,
)

trainer.train()

Обучение на собственном корпусе текстов

from datasets import load_dataset, DatasetDict
import torch

# Загрузить свой датасет
custom_dataset = load_dataset(
    "text",
    data_files={"train": "train.txt", "validation": "val.txt"}
)

# Токенизация
def tokenize_function(examples):
    return tokenizer(
        examples["text"],
        padding="max_length",
        truncation=True,
        max_length=512
    )

tokenized_datasets = custom_dataset.map(
    tokenize_function,
    batched=True,
    remove_columns=["text"]
)

# Обучение с LoRA для эффективности
from peft import get_peft_model, LoraConfig, TaskType

lora_config = LoraConfig(
    task_type=TaskType.CAUSAL_LM,
    r=8,
    lora_alpha=32,
    lora_dropout=0.1,
    target_modules=["q_proj", "v_proj", "k_proj", "out_proj"],
    bias="none"
)

model = get_peft_model(model, lora_config)
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
)

trainer.train()

2. Генеративные модели для изображений

Обучение GAN (Generative Adversarial Network)

import torch
import torch.nn as nn
from torch.optim import Adam

# Generator - создаёт изображения из шума
class Generator(nn.Module):
    def __init__(self, latent_dim=100):
        super().__init__()
        self.model = nn.Sequential(
            nn.Linear(latent_dim, 256),
            nn.ReLU(),
            nn.Linear(256, 512),
            nn.ReLU(),
            nn.Linear(512, 1024),
            nn.ReLU(),
            nn.Linear(1024, 28*28),  # MNIST
            nn.Sigmoid()  # 0-1 диапазон
        )
    
    def forward(self, z):
        return self.model(z).view(-1, 1, 28, 28)

# Discriminator - различает реальные и поддельные изображения
class Discriminator(nn.Module):
    def __init__(self):
        super().__init__()
        self.model = nn.Sequential(
            nn.Linear(28*28, 1024),
            nn.LeakyReLU(0.2),
            nn.Dropout(0.3),
            nn.Linear(1024, 512),
            nn.LeakyReLU(0.2),
            nn.Dropout(0.3),
            nn.Linear(512, 256),
            nn.LeakyReLU(0.2),
            nn.Dropout(0.3),
            nn.Linear(256, 1),
            nn.Sigmoid()  # 0-1: вероятность реальности
        )
    
    def forward(self, img):
        return self.model(img.view(-1, 28*28))

# Обучение
generator = Generator()
discriminator = Discriminator()
g_optimizer = Adam(generator.parameters(), lr=0.0002, betas=(0.5, 0.999))
d_optimizer = Adam(discriminator.parameters(), lr=0.0002, betas=(0.5, 0.999))
loss_fn = nn.BCELoss()

for epoch in range(100):
    for batch_idx, (real_imgs, _) in enumerate(dataloader):
        batch_size = real_imgs.size(0)
        
        # Обучение Discriminator
        real_labels = torch.ones(batch_size, 1)
        fake_labels = torch.zeros(batch_size, 1)
        
        real_output = discriminator(real_imgs)
        d_real_loss = loss_fn(real_output, real_labels)
        
        z = torch.randn(batch_size, 100)
        fake_imgs = generator(z)
        fake_output = discriminator(fake_imgs.detach())
        d_fake_loss = loss_fn(fake_output, fake_labels)
        
        d_loss = d_real_loss + d_fake_loss
        d_optimizer.zero_grad()
        d_loss.backward()
        d_optimizer.step()
        
        # Обучение Generator
        z = torch.randn(batch_size, 100)
        fake_imgs = generator(z)
        fake_output = discriminator(fake_imgs)
        g_loss = loss_fn(fake_output, real_labels)  # Generator хочет обмануть
        
        g_optimizer.zero_grad()
        g_loss.backward()
        g_optimizer.step()

Обучение диффузионных моделей

from diffusers import DDPMPipeline, DDPMScheduler, UNet2DModel
from torch.optim import AdamW
from tqdm import tqdm

# Инициализация компонентов
model = UNet2DModel(
    sample_size=32,
    in_channels=3,
    out_channels=3,
    layers_per_block=2,
    block_out_channels=(128, 128, 256, 256, 512, 512),
    down_block_types=("DownBlock2D", "DownBlock2D", "AttnDownBlock2D", 
                      "AttnDownBlock2D", "AttnDownBlock2D", "DownBlock2D"),
    up_block_types=("UpBlock2D", "AttnUpBlock2D", "AttnUpBlock2D", 
                    "AttnUpBlock2D", "UpBlock2D", "UpBlock2D"),
)

noise_scheduler = DDPMScheduler(
    num_train_timesteps=1000,
    beta_start=0.0001,
    beta_end=0.02,
    beta_schedule="linear",
)

optimizer = AdamW(model.parameters(), lr=1e-4)

# Обучение
for epoch in range(num_epochs):
    for batch in dataloader:
        x = batch["images"]
        
        # Случайный timestep
        timesteps = torch.randint(0, len(noise_scheduler), (len(x),))
        
        # Добавить шум к изображениям
        noise = torch.randn_like(x)
        noisy_x = noise_scheduler.add_noise(x, noise, timesteps)
        
        # Предсказать шум
        predicted_noise = model(noisy_x, timesteps).sample
        
        # MSE loss между предсказанным и реальным шумом
        loss = nn.MSELoss()(predicted_noise, noise)
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

3. Условные генеративные модели

Class-conditional генерация

class ConditionalGenerator(nn.Module):
    def __init__(self, latent_dim=100, num_classes=10):
        super().__init__()
        self.latent_dim = latent_dim
        self.num_classes = num_classes
        
        # Embedding для класса
        self.class_embedding = nn.Embedding(num_classes, latent_dim)
        
        # Основной генератор
        self.fc = nn.Sequential(
            nn.Linear(latent_dim * 2, 512),  # latent_dim + embedded class
            nn.ReLU(),
            nn.Linear(512, 1024),
            nn.ReLU(),
            nn.Linear(1024, 28*28),
            nn.Sigmoid()
        )
    
    def forward(self, z, class_label):
        # z: (batch, latent_dim)
        # class_label: (batch,) - индексы классов
        
        class_embed = self.class_embedding(class_label)  # (batch, latent_dim)
        combined = torch.cat([z, class_embed], dim=1)  # (batch, 2*latent_dim)
        
        return self.fc(combined).view(-1, 1, 28, 28)

# Обучение с классами
for batch_idx, (real_imgs, labels) in enumerate(dataloader):
    z = torch.randn(batch_size, latent_dim)
    
    # Generate with class condition
    fake_imgs = generator(z, labels)
    
    # Дальше как обычный GAN, но с учётом класса

4. Sequence-to-Sequence модели

from transformers import MarianMTModel, MarianTokenizer
from torch.utils.data import Dataset, DataLoader

class TranslationDataset(Dataset):
    def __init__(self, source_texts, target_texts, tokenizer):
        self.source_texts = source_texts
        self.target_texts = target_texts
        self.tokenizer = tokenizer
    
    def __getitem__(self, idx):
        source = self.source_texts[idx]
        target = self.target_texts[idx]
        
        inputs = self.tokenizer(
            source,
            max_length=512,
            truncation=True,
            padding="max_length",
            return_tensors="pt"
        )
        
        labels = self.tokenizer(
            target,
            max_length=512,
            truncation=True,
            padding="max_length",
            return_tensors="pt"
        )
        
        return {
            "input_ids": inputs["input_ids"].squeeze(),
            "attention_mask": inputs["attention_mask"].squeeze(),
            "labels": labels["input_ids"].squeeze(),
        }

# Обучение Seq2Seq
model = MarianMTModel.from_pretrained("Helsinki-NLP/Opus-MT-en-ru")
training_args = TrainingArguments(
    output_dir="./translation_model",
    num_train_epochs=5,
    per_device_train_batch_size=16,
    learning_rate=5e-5,
    save_total_limit=2,
    evaluation_strategy="epoch",
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
)

trainer.train()

5. Практические вызовы при обучении

Проблема: Mode collapse в GAN

# Решение: Wasserstein loss вместо BCE
import torch.nn.functional as F

# Generator loss
g_loss = -torch.mean(discriminator(fake_imgs))

# Discriminator loss (with gradient penalty)
d_loss = (
    -torch.mean(discriminator(real_imgs)) + 
    torch.mean(discriminator(fake_imgs.detach()))
)

# Gradient penalty
lambda_gp = 10
alphas = torch.rand(batch_size, 1, 1, 1)
interpolates = (alphas * real_imgs + 
                (1 - alphas) * fake_imgs).requires_grad_(True)
d_out = discriminator(interpolates)
gradients = torch.autograd.grad(
    d_out.sum(), interpolates,
    create_graph=True
)[0]
gradient_penalty = ((gradients.norm(2, dim=(1, 2, 3)) - 1) ** 2).mean()
d_loss += lambda_gp * gradient_penalty

Проблема: Нестабильное обучение диффузионных моделей

# Решение: Ema (Exponential Moving Average)
class EMA:
    def __init__(self, beta=0.9999):
        self.beta = beta
        self.step = 0
    
    def update_model_average(self, ma_model, current_model):
        self.step += 1
        if self.step < 20:
            alpha = 1 - (1 - self.beta)
        else:
            alpha = self.beta
        
        for current_params, ma_params in zip(
            current_model.parameters(),
            ma_model.parameters()
        ):
            old_weight, up_weight = ma_params.data, current_params.data
            ma_params.data = up_weight * alpha + old_weight * (1 - alpha)

# Использование
model_ema = copy.deepcopy(model)
ema = EMA()

for epoch in range(num_epochs):
    # ... обучение ...
    ema.update_model_average(model_ema, model)

6. Evaluation генеративных моделей

from pytorch_fid import fid_score
from torchvision.models import inception_v3
import numpy as np

# FID Score (Frechet Inception Distance) для изображений
fid_value = fid_score.calculate_fid_given_paths(
    ["path_to_real_images", "path_to_generated_images"],
    batch_size=50,
    device="cuda",
    dims=2048
)

print(f"FID Score: {fid_value:.2f}")  # Меньше - лучше

# BLEU Score для текста
from nltk.translate.bleu_score import sentence_bleu

reference = [["the", "cat", "sat", "on", "the", "mat"]]
candidate = ["the", "cat", "is", "on", "the", "mat"]
bleu = sentence_bleu(reference, candidate)
print(f"BLEU Score: {bleu:.3f}")

# Inception Score для изображений
def inception_score(generated_imgs):
    model = inception_v3(pretrained=True).eval()
    # Вычислить вероятности классов
    # ...

Итоговый опыт

Я работал с:

  • Текстовыми моделями: GPT, BERT, T5, LLaMA (fine-tuning и обучение с нуля)
  • Образ-моделями: GAN, VAE, Diffusion models (обучение с нуля)
  • Условными моделями: class-conditional GAN, text-to-image
  • Архитектурами: Transformer, CNN, RNN, Attention mechanisms
  • Оптимизацией: LoRA, QLoRA, gradient checkpointing, mixed precision
  • Evaluation: FID, IS, BLEU, ROUGE, METEOR

Генеративные модели требуют глубокого понимания архитектур, loss функций и методов оптимизации — всё это я усвоил на практике через многочисленные проекты.

Обучал ли модели генеративного ИИ | PrepBro