Что такое языковая модель?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Языковая модель: определение и принципы
Языковая модель (Language Model, LM) — это вероятностная модель, которая предсказывает вероятность последовательности слов. Проще говоря, она учится на больших текстовых данных и затем может предсказывать следующее слово на основе предыдущих, или оценивать вероятность того или иного текста. Языковые модели — это фундамент современного NLP и лежат в основе ChatGPT, BERT и других революционных систем.
Математическое определение
Вероятность последовательности
Для последовательности слов w₁, w₂, ..., wₙ языковая модель вычисляет:
P(w₁, w₂, ..., wₙ) = P(w₁) × P(w₂|w₁) × P(w₃|w₁,w₂) × ... × P(wₙ|w₁,...,wₙ₋₁)
Где каждый следующий токен зависит от всех предыдущих. Это формулируется через цепное правило вероятности.
Пример
Текст: "The cat sat on the mat"
P(The cat sat on the mat) =
P(The) ×
P(cat|The) ×
P(sat|The, cat) ×
P(on|The, cat, sat) ×
P(the|The, cat, sat, on) ×
P(mat|The, cat, sat, on, the)
Хорошая языковая модель должна давать высокую вероятность реальным предложениям и низкую — бессмыслице.
Типы языковых моделей
1. N-gram модели (классический подход)
Предполагают, что следующее слово зависит только от последних n-1 слов:
from collections import defaultdict
class NGramLanguageModel:
def __init__(self, n=3): # bigram (n=2), trigram (n=3)
self.n = n
self.counts = defaultdict(int)
self.context_counts = defaultdict(int)
def train(self, tokens):
# Подсчитываем частоты n-грамм
for i in range(len(tokens) - self.n + 1):
context = tuple(tokens[i:i+self.n-1]) # предыдущие n-1 токена
word = tokens[i+self.n-1] # предсказываемое слово
self.counts[(context, word)] += 1
self.context_counts[context] += 1
def probability(self, word, context):
# P(word|context) = count(context, word) / count(context)
context = tuple(context)
if self.context_counts[context] == 0:
return 0.0 # Неизвестный контекст
return self.counts[(context, word)] / self.context_counts[context]
# Пример
model = NGramLanguageModel(n=3) # Trigram
tokens = ['the', 'cat', 'sat', 'on', 'the', 'mat']
model.train(tokens)
# P(mat | the, on)
prob = model.probability('mat', ['the', 'on'])
print(f"P(mat|the, on) = {prob}")
Проблемы n-грамм
- Длинные зависимости — trigram не видит дальше 2 слов
- Спарсность — редкие контексты имеют низкую статистику
- Взрыв комбинаций — число возможных n-грамм растёт экспоненциально
2. Нейронные языковые модели
LSTM Language Model
import torch
import torch.nn as nn
class LSTMLanguageModel(nn.Module):
def __init__(self, vocab_size, embedding_dim=128, hidden_dim=256):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embedding_dim)
self.lstm = nn.LSTM(
input_size=embedding_dim,
hidden_size=hidden_dim,
num_layers=2,
batch_first=True
)
self.linear = nn.Linear(hidden_dim, vocab_size)
def forward(self, input_ids):
# input_ids: (batch_size, seq_len)
embedded = self.embedding(input_ids)
lstm_out, _ = self.lstm(embedded)
logits = self.linear(lstm_out)
return logits
# Обучение
model = LSTMLanguageModel(vocab_size=10000)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
loss_fn = nn.CrossEntropyLoss()
# На каждом шаге обучения
for epoch in range(10):
for batch_input, batch_target in train_loader:
logits = model(batch_input) # (batch_size, seq_len, vocab_size)
loss = loss_fn(logits.view(-1, 10000), batch_target.view(-1))
loss.backward()
optimizer.step()
optimizer.zero_grad()
3. Transformer Language Model (GPT-style)
from transformers import GPT2LMHeadModel, GPT2Tokenizer
# Загружаем предварительно обученную модель
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
model = GPT2LMHeadModel.from_pretrained('gpt2')
# Генерация текста
prompt = "The future of AI is"
input_ids = tokenizer.encode(prompt, return_tensors='pt')
# Генерируем 50 токенов
output = model.generate(
input_ids,
max_length=50,
temperature=0.7, # креативность
top_p=0.9, # nucleus sampling
do_sample=True
)
generated_text = tokenizer.decode(output[0], skip_special_tokens=True)
print(generated_text)
4. Masked Language Model (BERT-style)
from transformers import BertForMaskedLM, BertTokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertForMaskedLM.from_pretrained('bert-base-uncased')
# Предсказание замаскированного слова
text = "The cat [MASK] on the mat"
input_ids = tokenizer.encode(text, return_tensors='pt')
with torch.no_grad():
outputs = model(input_ids)
logits = outputs[0]
# Находим индекс [MASK]
mask_idx = tokenizer.encode(text).index(tokenizer.mask_token_id)
predicted_id = torch.argmax(logits[0, mask_idx]).item()
predicted_word = tokenizer.decode([predicted_id])
print(f"Предсказанное слово: {predicted_word}") # sat
Метрики оценки языковых моделей
Perplexity (Растерянность)
Основная метрика — мера того, насколько хорошо модель предсказывает тестовый набор.
import math
def calculate_perplexity(model, test_sequence):
"""
Perplexity = exp(-1/N * Σ log P(wᵢ|w₁,...,wᵢ₋₁))
"""
total_log_prob = 0
with torch.no_grad():
for i in range(1, len(test_sequence)):
context = test_sequence[:i]
target = test_sequence[i]
# Получаем вероятность
logits = model(context.unsqueeze(0))
log_prob = torch.log_softmax(logits, dim=-1)[0, -1, target]
total_log_prob += log_prob.item()
avg_log_prob = total_log_prob / len(test_sequence)
perplexity = math.exp(-avg_log_prob)
return perplexity
# Обычные значения:
# - Good model: perplexity ~20-50
# - Bad model: perplexity >100
Приложения языковых моделей
1. Машинный перевод
# Encoder-Decoder модель
# Encoder: понимает исходный язык
# Decoder: языковая модель целевого языка
2. Автодополнение и прогноз текста
# T9 на телефонах, IntelliSense в IDE, Google Search
3. Генерация текста
# GPT, DALL-E descriptions, ChatGPT
4. Определение аномалий в тексте
# Спам, бот-атаки, фишинг
# Низкая вероятность = странный текст
5. Оценка сходства текстов
# Сравнение вероятностей двух текстов
Эволюция языковых моделей
1990s: N-гrams
↓
2000s: Neural Language Models (RNN, LSTM)
↓
2017: Transformer (Attention is All You Need)
↓
2018: BERT (bidirectional)
↓
2018-2020: GPT-2, GPT-3 (autoregressive, мощные)
↓
2023+: Large Language Models (GPT-4, Claude, LLaMA)
- Миллиарды параметров
- Instruction tuning и RLHF
- In-context learning
Ключевые свойства современных языковых моделей
- Масштабируемость — больше параметров = лучше
- Предварительное обучение — на миллиардах токенов текста
- Fine-tuning — адаптация к специфическим задачам
- Zero-shot/Few-shot — работают без примеров через промпты
- Emergent abilities — появляются новые способности с масштабом
Практический пример: построение простой LM
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset
class SimpleLanguageModel(nn.Module):
def __init__(self, vocab_size=1000, embedding_dim=100):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embedding_dim)
self.linear = nn.Linear(embedding_dim, vocab_size)
def forward(self, x):
emb = self.embedding(x)
return self.linear(emb)
# Обучение на текстовом корпусе
model = SimpleLanguageModel()
optimizer = torch.optim.Adam(model.parameters())
loss_fn = nn.CrossEntropyLoss()
for epoch in range(10):
for batch_x, batch_y in train_loader:
logits = model(batch_x)
loss = loss_fn(logits.view(-1, vocab_size), batch_y.view(-1))
loss.backward()
optimizer.step()
optimizer.zero_grad()
print(f"Trained language model with {sum(p.numel() for p in model.parameters())} parameters")
Итог
Языковые модели — это мощный инструмент, который преобразовал NLP. Они работают благодаря способности учиться закономерностям в языке из огромных объёмов текста. От простых n-грамм до современных LLM с триллионами параметров, языковые модели остаются центром современного AI и продолжают определять границы возможного в обработке естественного языка.