تحليل آلية تدريب KataGo
يقدم هذا المقال تحليلاً معمقاً لآلية تدريب KataGo، لمساعدتك على فهم مبادئ عمل تدريب اللعب الذاتي.
يعتمد KataGo على التعلّم المعزَّز عبر اللعب الذاتي: يُنتج نموذج أولي عدداً كبيراً من سجلات المباريات عبر اللعب الذاتي، وبعد جمع البيانات يُدرَّب باستخدام دالتي خسارة السياسة والقيمة لإنتاج نموذج أقوى، ثم تتكرر هذه الدورة لتحقيق تقدم مستمر؛ وتزداد ذاكرة GPU والوقت اللازمان للتدريب مع كبر حجم النموذج (مثلاً من b6c96 إلى b40c256).
نظرة عامة على التدريب
دورة التدريب
نموذج أولي → لعب ذاتي → جمع البيانات → تحديث التدريب → نموذج أقوى → تكرار
المفاهيم المقابلة:
- اللعب الذاتي ↔ تقارب النقطة الثابتة
- منحنى قوة اللعب ↔ نمو المنحنى S
- MDP ↔ سلسلة ماركوف
متطلبات الأجهزة
| حجم النموذج | ذاكرة GPU | وقت التدريب |
|---|---|---|
| b6c96 | 4 GB | عدة ساعات |
| b10c128 | 8 GB | 1-2 يوم |
| b18c384 | 16 GB | 1-2 أسبوع |
| b40c256 | 24 GB+ | عدة أسابيع |
إعداد البيئة
تثبيت التبعيات
# بيئة Python
conda create -n katago python=3.10
conda activate katago
# PyTorch (إصدار CUDA)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
# تبعيات أخرى
pip install numpy h5py tqdm tensorboard
الحصول على كود التدريب
git clone https://github.com/lightvector/KataGo.git
cd KataGo/python
إعدادات التدريب
هيكل ملف الإعدادات
# configs/train_config.yaml
# بنية النموذج
model:
num_blocks: 10 # عدد الكتل المتبقية
trunk_channels: 128 # عدد قنوات الجذع
policy_channels: 32 # عدد قنوات رأس السياسة
value_channels: 32 # عدد قنوات رأس القيمة
# معلمات التدريب
training:
batch_size: 256
learning_rate: 0.001
lr_schedule: "cosine"
weight_decay: 0.0001
epochs: 100
# معلمات اللعب الذاتي
selfplay:
num_games_per_iteration: 1000
max_visits: 600
temperature: 1.0
temperature_drop_move: 20
# إعدادات البيانات
data:
max_history_games: 500000
shuffle_buffer_size: 100000
جدول أحجام النماذج
| الاسم | num_blocks | trunk_channels | عدد المعلمات |
|---|---|---|---|
| b6c96 | 6 | 96 | ~1M |
| b10c128 | 10 | 128 | ~3M |
| b18c384 | 18 | 384 | ~20M |
| b40c256 | 40 | 256 | ~45M |
المفاهيم المقابلة:
- حجم الشبكة مقابل قوة اللعب: قياس السعة
- قوانين القياس العصبية: العلاقة اللوغاريتمية المزدوجة
عملية التدريب
الخطوة 1: تهيئة النموذج
# init_model.py
import torch
from model import KataGoModel
config = {
'num_blocks': 10,
'trunk_channels': 128,
'input_features': 22,
'policy_size': 362, # 361 + pass
}
model = KataGoModel(config)
torch.save(model.state_dict(), 'model_init.pt')
print(f"عدد معلمات النموذج: {sum(p.numel() for p in model.parameters()):,}")
الخطوة 2: توليد بيانات اللعب الذاتي
# بناء محرك C++
cd ../cpp
mkdir build && cd build
cmake .. -DUSE_BACKEND=CUDA
make -j$(nproc)
# تنفيذ اللعب الذاتي
./katago selfplay \
-model ../python/model_init.pt \
-output-dir ../python/selfplay_data \
-config selfplay.cfg \
-num-games 1000
إعدادات اللعب الذاتي (selfplay.cfg):
maxVisits = 600
numSearchThreads = 4
# إعدادات الحرارة (زيادة الاستكشاف)
chosenMoveTemperature = 1.0
chosenMoveTemperatureEarly = 1.0
chosenMoveTemperatureHalflife = 20
# ضوضاء Dirichlet (زيادة التنوع)
rootNoiseEnabled = true
rootDirichletNoiseTotalConcentration = 10.83
rootDirichletNoiseWeight = 0.25
المفاهيم المقابلة:
- الاستكشاف مقابل الاستغلال: معلمة الحرارة
- ضوضاء Dirichlet: استكشاف عقدة الجذر
الخطوة 3: تدريب الشبكة العصبية
# train.py
import torch
from torch.utils.data import DataLoader
from model import KataGoModel
from dataset import SelfPlayDataset
# تحميل البيانات
dataset = SelfPlayDataset('selfplay_data/')
dataloader = DataLoader(dataset, batch_size=256, shuffle=True)
# تحميل النموذج
model = KataGoModel(config)
model.load_state_dict(torch.load('model_init.pt'))
model = model.cuda()
# المحسّن
optimizer = torch.optim.Adam(
model.parameters(),
lr=0.001,
weight_decay=0.0001
)
# جدولة معدل التعلم
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
optimizer,
T_max=100,
eta_min=0.00001
)
# دورة التدريب
for epoch in range(100):
model.train()
total_loss = 0
for batch in dataloader:
inputs = batch['inputs'].cuda()
policy_target = batch['policy'].cuda()
value_target = batch['value'].cuda()
ownership_target = batch['ownership'].cuda()
# التمرير الأمامي
policy_pred, value_pred, ownership_pred = model(inputs)
# حساب الخسارة
policy_loss = torch.nn.functional.cross_entropy(
policy_pred, policy_target
)
value_loss = torch.nn.functional.mse_loss(
value_pred, value_target
)
ownership_loss = torch.nn.functional.mse_loss(
ownership_pred, ownership_target
)
loss = policy_loss + value_loss + 0.5 * ownership_loss
# التمرير العكسي
optimizer.zero_grad()
loss.backward()
torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
optimizer.step()
total_loss += loss.item()
scheduler.step()
print(f"Epoch {epoch}: Loss = {total_loss / len(dataloader):.4f}")
# حفظ نقطة التحقق
torch.save(model.state_dict(), f'model_epoch{epoch}.pt')
المفاهيم المقابلة:
- نزول التدرج: optimizer.step()
- الزخم: محسّن Adam
- تناقص معدل التعلم: CosineAnnealingLR
- قص التدرج: clip_grad_norm_
الخطوة 4: التقييم والتكرار
# تقييم النموذج الجديد مقابل القديم
./katago match \
-model1 model_epoch99.pt \
-model2 model_init.pt \
-num-games 100 \
-output match_results.txt
إذا كان معدل فوز النموذج الجديد > 55%، فإنه يحل محل النموذج القديم ويدخل في الجولة التالية من التكرار.
شرح تفصيلي لدوال الخسارة
خسارة السياسة (Policy Loss)
# خسارة الانتروبيا المتقاطعة
policy_loss = -sum(target * log(pred))
الهدف: جعل التوزيع الاحتمالي المتوقع قريباً من نتائج بحث MCTS.
المفاهيم المقابلة:
- انتروبيا السياسة: الانتروبيا المتقاطعة
- تباعد KL: مسافة التوزيع
خسارة القيمة (Value Loss)
# متوسط الخطأ التربيعي
value_loss = (pred - actual_result)^2
الهدف: التنبؤ بالنتيجة النهائية للمباراة (فوز/خسارة/تعادل).
خسارة الملكية (Ownership Loss)
# التنبؤ بملكية كل نقطة
ownership_loss = mean((pred - actual_ownership)^2)
الهدف: التنبؤ بالملكية النهائية لكل موقع.
التقنيات المتقدمة
1. زيادة البيانات
استغلال تناظر اللوحة:
def augment_data(board, policy, ownership):
"""زيادة البيانات لـ 8 تحولات من مجموعة D4"""
augmented = []
for rotation in range(4):
for flip in [False, True]:
# التدوير والانعكاس
aug_board = transform(board, rotation, flip)
aug_policy = transform(policy, rotation, flip)
aug_ownership = transform(ownership, rotation, flip)
augmented.append((aug_board, aug_policy, aug_ownership))
return augmented
المفاهيم المقابلة:
- تناظر اللوحة: مجموعة D4
- زيادة البيانات: استغلال التناظر
2. التعلم المتدرج
من البسيط إلى المعقد:
# التدريب أولاً بعدد زيارات أقل
schedule = [
(100, 10000), # 100 زيارة، 10000 مباراة
(200, 20000), # 200 زيارة، 20000 مباراة
(400, 50000), # 400 زيارة، 50000 مباراة
(600, 100000), # 600 زيارة، 100000 مباراة
]
المفاهيم المقابلة:
- منهج التدريب: التعلم المتدرج
3. التدريب بالدقة المختلطة
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
with autocast():
policy_pred, value_pred, ownership_pred = model(inputs)
loss = compute_loss(...)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
4. التدريب متعدد GPU
import torch.distributed as dist
from torch.nn.parallel import DistributedDataParallel
# تهيئة التوزيع
dist.init_process_group(backend='nccl')
# تغليف النموذج
model = DistributedDataParallel(model)
المراقبة والتصحيح
مراقبة TensorBoard
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter('runs/training')
# تسجيل الخسارة
writer.add_scalar('Loss/policy', policy_loss, step)
writer.add_scalar('Loss/value', value_loss, step)
writer.add_scalar('Loss/total', total_loss, step)
# تسجيل معدل التعلم
writer.add_scalar('LR', scheduler.get_last_lr()[0], step)
tensorboard --logdir runs
المشاكل الشائعة
| المشكلة | السبب المحتمل | الحل |
|---|---|---|
| الخسارة لا تنخفض | معدل التعلم منخفض/مرتفع جداً | ضبط معدل التعلم |
| الخسارة متذبذبة | حجم الدفعة صغير جداً | زيادة حجم الدفعة |
| فرط التخصيص | بيانات غير كافية | توليد المزيد من بيانات اللعب الذاتي |
| قوة اللعب لا تتحسن | عدد الزيارات قليل جداً | زيادة maxVisits |
المفاهيم المقابلة:
- فرط التخصيص: التكيف المفرط
- التنظيم: weight_decay
- تأثير معدل التعلم: ضبط المعلمات
اقتراحات للتجارب الصغيرة
إذا كنت تريد فقط التجربة، يُنصح بـ:
- استخدام لوحة 9×9: تقليل كبير في الحسابات
- استخدام نموذج صغير: b6c96 كافٍ للتجربة
- تقليل عدد الزيارات: 100-200 زيارة
- ضبط نموذج مدرب مسبقاً: أسرع من البدء من الصفر
# إعدادات لوحة 9×9
boardSize = 9
maxVisits = 100
قراءات إضافية
- دليل قراءة الكود المصدري — فهم هيكل الكود
- المشاركة في مجتمع المصادر المفتوحة — الانضمام للتدريب الموزع
- ابتكارات KataGo الرئيسية — سر الكفاءة 50 ضعفاً