LLMの学習方法は大きく分けて3つある
1. 事前学習(Pre-training)
目的:
「言語の基礎的な知識」を身につける段階
文法・語彙・一般常識・文脈の理解などを、膨大なテキストから学ぶ
方法:
教師なし学習(Self-supervised learning)
入力文の一部を隠して、隠された部分を予測する(=マスク言語モデル、例:BERT)
次の単語を予測する(=自己回帰モデル、例:GPT系列)
データ:
インターネット上のテキスト(Webページ、書籍、Wikipediaなど)
数百億〜数兆トークン規模
2. ファインチューニング(Fine-tuning)
目的:
事前学習で得た「言語の基礎力」を、特定の目的や用途に合わせて調整
方法:
教師あり学習(Supervised fine-tuning)
入力と正解(出力)のペアを与える。
例:「質問 → 回答」「命令 → 応答」
少量の高品質データで調整。
3.人間のフィードバックによる強化学習(RLHF: Reinforcement Learning from Human Feedback)
目的:
モデルの出力を「人間にとって好ましい形」にする。
(=有用で、正確で、安全で、自然な応答にする)
① SFTモデル(ファインチューニング済)を使って、複数の応答候補を生成。
② 人間の評価者が「どの回答が良いか」を順位付け。
**③ 報酬モデル(Reward Model)**を学習。
→ 「この応答が好ましい」と判断するスコア関数を作る。
**④ 強化学習(PPOなど)**でモデルを更新し、報酬が高い出力を出すように最適化。
### Pretraining
import torch import torch.nn as nn import torch.optim as optim text = "I love AI . AI loves people ." vocab = list(set(text.split())) word2idx = {w:i for i,w in enumerate(vocab)} idx2word = {i:w for w,i in word2idx.items()} def make_data(text): words = text.split() X, Y = [], [] for i in range(len(words)-2): X.append([word2idx[words[i]], word2idx[words[i+1]]]) Y.append(word2idx[words[i+2]]) return torch.tensor(X), torch.tensor(Y) X, Y = make_data(text) class TinyLM(nn.Module): def __init__(self, vocab_size, hidden_size=8): super().__init__() self.emb = nn.Embedding(vocab_size, hidden_size) self.fc = nn.Linear(hidden_size*2, vocab_size) def forward(self, x): x = self.emb(x).view(x.size(0), -1) return self.fc(x) model = TinyLM(len(vocab)) criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.01) for epoch in range(200): output = model(X) loss = criterion(output, Y) optimizer.zero_grad() loss.backward() optimizer.step() test = torch.tensor([[word2idx["I"], word2idx["love"]]]) pred = torch.argmax(model(test), dim=1) print("Predicted next word:", idx2word[pred.item()])
### Fine tuning
train_data = [ ("Hello", "Hi there!"), ("How are you?", "I'm fine, thank you."), ("Bye", "Goodbye!") ] from transformers import AutoTokenizer, AutoModelForCausalLM, Trainer, TrainingArguments tokenizer = AutoTokenizer.from_pretrained("gpt2") model = AutoModelForCausalLM.from_pretrained("gpt2") # データを整形 inputs = [tokenizer(f"User: {q}\nAI:", return_tensors="pt") for q, _ in train_data] labels = [tokenizer(a, return_tensors="pt")["input_ids"] for _, a in train_data] # 学習っぽいループ for i, (inp, lab) in enumerate(zip(inputs, labels)): out = model(**inp, labels=lab) loss = out.loss loss.backward() print("Fine-tuning step complete ✅")
### RLHF
import random # モデルの応答候補 responses = ["Sure, here’s an example.", "I don’t know.", "You’re stupid."] # 人間が選んだランキング(良い順) human_ranking = {"Sure, here’s an example.": 1, "I don’t know.": 0, "You’re stupid.": -1} # 報酬モデル(スコア関数)を模擬 def reward(response): return human_ranking[response] # 強化学習っぽい更新(高報酬応答を強化) policy = {r: 0.0 for r in responses} for _ in range(10): r = random.choice(responses) policy[r] += reward(r) * 0.1 print("Learned policy:", policy)