Trackio documentation

تشغيل تجارب التعلم الآلي باستخدام الوكلاء

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

تشغيل تجارب التعلم الآلي باستخدام الوكلاء

صُمِّم Trackio من الأساس لدعم تجارب تعلّم الآلة المستقلة التي يقودها وكلاء نماذج اللغة الكبيرة. يغطي هذا الدليل كيفية تنظيم كود التدريب، وإعداد التنبيهات، وربط حلقة التغذية الراجعة بحيث يستطيع الوكيل إطلاق التجارب، ومراقبتها، والاستجابة للمشكلات، والتكرار على المعاملات الفائقة — كل ذلك دون تدخل بشري.

لماذا نستخدم Trackio للوكلاء؟

يفترض معظم متتبعات التجارب أن شخصًا ما يراقب لوحة التحكم. تمنح Trackio الوكلاء وصولًا برمجيًا من الدرجة الأولى عبر قنوات متعددة:

  • سطر الأوامر مع إخراج بصيغة JSON — يدعم كل أمر في trackio الخيار --json، مما يجعل تحليل المخرجات سهلاً بأي لغة
  • واجهة برمجة تطبيقات بايثون — يوفر trackio.Api() وصولاً مباشراً إلى التشغيلات والمقاييس والتنبيهات
  • واجهة HTTP API / MCP — يعرض لوحة تحكم Trackio نقاط نهاية لواجهة Gradio API، ويمكن تشغيله كخادم MCP بحيث تستطيع نماذج اللغة الكبيرة استدعاء الأدوات مباشرة
  • التنبيهات عبر خطافات الويب — يمكن للوكلاء إدراج استدعاءات trackio.alert() مثل عبارات الطباعة والاستعلام عنها لاحقًا
  • التصفية منذ since — استطلاع فعّال للتنبيهات الجديدة دون إعادة قراءة السجل الكامل

حلقة تغذية راجعة للوكيل

يبدو حلقة التجربة الذاتية النموذجية على النحو التالي:

┌─────────────────────────────────────┐
│  1. Agent writes training script    │
│     with trackio.init(), log(),     │
│     and alert() calls               │
├─────────────────────────────────────┤
│  2. Agent launches the script       │
├─────────────────────────────────────┤
│  3. Agent polls for alerts and      │
│     metrics while training runs     │
├─────────────────────────────────────┤
│  4. Agent reads results, decides    │
│     next hyperparameters            │
├─────────────────────────────────────┤
│  5. Agent writes a new script       │
│     and repeats from step 1         │
└─────────────────────────────────────┘

يستعرض بقية هذا الدليل كل خطوة مع أكواد عملية.

الخطوة 1: هيكلة كود التدريب للوكلاء

الاستنتاج الأساسي هو أن الوكيل يمكنه إدراج استدعاءات trackio.alert() بنفس الطريقة التي يُدرج بها عبارات print() لأغراض التصحيح. التنبيهات أكثر هيكلية من عبارات الطباعة: فهي تتضمن عنواناً، ووصفاً اختيارياً، ومستوى خطورة، وتُحفظ تلقائياً ويمكن الاستعلام عنها.

إليك سكربت تدريب مكتوب بالطريقة التي كان سيكتبها وكيل، مع تنبيهات عند كل نقطة قرار:

import trackio
import torch

trackio.init(
    project="cifar10-hparam-search",
    name="run-lr0.001-bs64",
    config={
        "learning_rate": 0.001,
        "batch_size": 64,
        "optimizer": "adamw",
        "epochs": 50,
        "weight_decay": 1e-4,
    },
)

model = build_model()
optimizer = torch.optim.AdamW(
    model.parameters(), lr=0.001, weight_decay=1e-4
)

best_val_loss = float("inf")
patience_counter = 0
patience_limit = 5

for epoch in range(50):
    train_loss = train_one_epoch(model, train_loader, optimizer)
    val_loss, val_acc = evaluate(model, val_loader)

    trackio.log({
        "train_loss": train_loss,
        "val_loss": val_loss,
        "val_accuracy": val_acc,
        "learning_rate": optimizer.param_groups[0]["lr"],
    })

    # Alert on loss divergence
    if train_loss > 10.0:
        trackio.alert(
            title="Training diverged",
            text=f"train_loss={train_loss:.4f} at epoch {epoch}. "
                 "Learning rate is likely too high.",
            level=trackio.AlertLevel.ERROR,
        )
        break

    # Alert when validation stops improving
    if val_loss < best_val_loss:
        best_val_loss = val_loss
        patience_counter = 0
        torch.save(model.state_dict(), "best_model.pt")
    else:
        patience_counter += 1
        if patience_counter >= patience_limit:
            trackio.alert(
                title="Early stopping triggered",
                text=f"No improvement for {patience_limit} epochs. "
                     f"Best val_loss={best_val_loss:.4f} at epoch "
                     f"{epoch - patience_limit}.",
                level=trackio.AlertLevel.WARN,
            )
            break

    # Alert on overfitting
    if epoch > 10 and (train_loss < 0.1 and val_loss > 1.5):
        trackio.alert(
            title="Overfitting detected",
            text=f"train_loss={train_loss:.4f} vs val_loss={val_loss:.4f}. "
                 "Consider adding regularization or reducing model capacity.",
            level=trackio.AlertLevel.WARN,
        )

    # Alert on good results
    if val_acc > 0.93:
        trackio.alert(
            title="High accuracy reached",
            text=f"val_accuracy={val_acc:.4f} at epoch {epoch}.",
            level=trackio.AlertLevel.INFO,
        )

trackio.alert(
    title="Training complete",
    text=f"Final val_loss={val_loss:.4f}, val_accuracy={val_acc:.4f}. "
         f"Best val_loss={best_val_loss:.4f}.",
    level=trackio.AlertLevel.INFO,
)
trackio.finish()

التنبيهات هنا ليست موجهة للبشر فحسب — بل هي إشارات منظمة سيقوم الوكيل بقراءتها لاحقًا لاتخاذ قرار بشأن الإجراء التالي.

إرشادات لتنبيهات صديقة للوكلاء

  • استخدم ERROR للحالات التي يجب أن توقف التشغيل (انحراف، خسارة NaN، نفاد الذاكرة).
  • استخدم WARN للحالات التي تشير إلى ضرورة تغيير المعلمات الفائقة (الإفراط في التخصيص، التوقف المبكر، بطء التقارب).
  • استخدم INFO للمعالم الرئيسية (اكتمال التدريب، الوصول إلى دقة عالية، حفظ نقطة التفتيش).
  • تضمين قيم رقمية في text حتى يتمكن الوكيل من تحليلها والاستدلال عليها.
  • تضمين اقتراحات قابلة للتنفيذ في text (مثل “معدل التعلم مرتفع على الأرجح”) لمساعدة الوكيل على تحديد ما يجب تغييره.

الخطوة 2: تشغيل السكربت

يمكن للوكيل تشغيل السكربت في عملية فرعية أو عملية في الخلفية. في معظم أطر عمل الوكلاء، يكون الأمر بسيطاً كتنفيذ أمر shell:

python train.py

إذا كان الوكيل يستخدم نموذج Llama متصلًا عبر MCP، فيمكنه أيضًا تشغيل السكربتات من خلال أداة shell.

الخطوة 3: المراقبة أثناء التدريب

أثناء تشغيل التدريب، يستعلم الوكيل عن التنبيهات والمقاييس. ويجعل علم --since هذه العملية فعّالة — إذ تُعاد فقط التنبيهات الجديدة منذ آخر فحص.

الاستطلاع عبر سطر الأوامر

# First poll — get all alerts
trackio get alerts --project "cifar10-hparam-search" --run "run-lr0.001-bs64" --json

# Subsequent polls — only new alerts
trackio get alerts --project "cifar10-hparam-search" --since "2025-06-15T14:30:00" --json

الاستطلاع عبر واجهة برمجة تطبيقات بايثون

import trackio
from datetime import datetime, timezone

api = trackio.Api()
last_check = None

while training_is_running():
    alerts = api.alerts(
        "cifar10-hparam-search",
        run="run-lr0.001-bs64",
        since=last_check,
    )
    if alerts:
        last_check = alerts[0]["timestamp"]  # alerts are sorted newest-first
        for a in alerts:
            print(f"[{a['level'].upper()}] {a['title']}: {a['text']}")

            if a["level"] == "error":
                # Stop the run and re-plan
                handle_error(a)

    time.sleep(30)

الاستطلاع عبر MCP

إذا كان لوحة تحكم Trackio تعمل كخادم MCP، فيمكن للوكيل استدعاء أداة get_alerts مباشرةً عبر بروتوكول MCP. راجع Trackio كواجهة برمجة تطبيقات وخادم MCP لتعليمات الإعداد.

الخطوة 4: قراءة النتائج واتخاذ الخطوات التالية

بعد انتهاء التشغيل، يقرأ الوكيل النتائج الكاملة:

# Get run summary (metrics, config, step count)
trackio get run --project "cifar10-hparam-search" --run "run-lr0.001-bs64" --json

# Get the loss curve
trackio get metric --project "cifar10-hparam-search" --run "run-lr0.001-bs64" --metric "val_loss" --json

# Get all alerts (the most useful signal for decision-making)
trackio get alerts --project "cifar10-hparam-search" --run "run-lr0.001-bs64" --json

توفر التنبيهات ملخصًا موجزًا لما حدث أثناء التدريب. وبدلًا من تحليل آلاف قيم المقاييس، يمكن للوكيل قراءة عدد قليل من التنبيهات لفهم:

  • هل انبثقت عملية التدريب؟ → اخفض معدل التعلم
  • هل حدث فرط ملاءمة؟ → أضف التنظيم أو قلل السعة
  • هل توقف مبكرًا؟ → المعلمات الفائقة ضمن النطاق الصحيح لكنها قد تحتاج إلى ضبط
  • هل حققت دقة عالية؟ → هذه الإعدادات تعمل بشكل جيد

الخطوة 5: التكرار على المعلمات الفائقة

يستخدم الوكيل التنبيهات من التشغيل السابق لاختيار معاملات فائقة جديدة. فيما يلي مثال ملموس على منطق القرار الذي قد يتبعه الوكيل:

import json
import subprocess
import trackio

api = trackio.Api()

# Read alerts from the last run
alerts = api.alerts("cifar10-hparam-search", run="run-lr0.001-bs64")

# Read the config from the last run
runs = api.runs("cifar10-hparam-search")
last_run = [r for r in runs if r.name == "run-lr0.001-bs64"][0]
config = last_run.config

# Decision logic based on alerts
new_config = dict(config)
for alert in alerts:
    if "diverged" in alert["title"].lower():
        new_config["learning_rate"] = config["learning_rate"] * 0.1
    elif "overfitting" in alert["title"].lower():
        new_config["weight_decay"] = config.get("weight_decay", 1e-4) * 10
    elif "early stopping" in alert["title"].lower():
        new_config["learning_rate"] = config["learning_rate"] * 0.5
    elif "high accuracy" in alert["title"].lower():
        # This config is good — try fine-tuning
        new_config["learning_rate"] = config["learning_rate"] * 0.5
        new_config["epochs"] = config["epochs"] + 20

ثم يولّد الوكيل سكربت تدريب جديدًا مع الإعداد المحدّث ويشغّله، مع تكرار الحلقة.

مقارنة التشغيلات

بعد عدة تكرارات، يمكن للوكيل مقارنة جميع التشغيلات في المشروع:

# List all runs
trackio list runs --project "cifar10-hparam-search" --json

# Get a summary of each run
trackio get run --project "cifar10-hparam-search" --run "run-lr0.001-bs64" --json
trackio get run --project "cifar10-hparam-search" --run "run-lr0.0001-bs64" --json

أو في بايثون:

api = trackio.Api()
runs = api.runs("cifar10-hparam-search")

for run in runs:
    alerts = run.alerts()
    errors = [a for a in alerts if a["level"] == "error"]
    warns = [a for a in alerts if a["level"] == "warn"]
    infos = [a for a in alerts if a["level"] == "info"]
    print(f"{run.name}: {len(errors)} errors, {len(warns)} warnings, {len(infos)} info")

إرسال التنبيهات إلى الوكيل عبر الخطافات

إذا كان إطار عمل الوكيل لديك يحتوي على نقطة نهاية HTTP أو يمكنه استلام رسائل من Slack/Discord، يمكنك استخدام webhooks لدفع التنبيهات إلى الوكيل في الوقت الفعلي بدلاً من الاستعلام الدوري:

trackio.init(
    project="cifar10-hparam-search",
    webhook_url="https://hooks.slack.com/services/T.../B.../xxx",
)

بهذه الطريقة، تُستلم التنبيهات في قناة Slack يراقبها الوكيل، مما يُغلق الحلقة دون الحاجة إلى أي استعلام دوري. راجع دليل التنبيهات للحصول على تعليمات تفصيلية لإعداد Slack وDiscord.

مثال كامل: البحث المستقل عن المعلمات الفائقة

إليك مثالًا كاملًا ومستقلًا يربط كل شيء معًا. يعمل هذا النص البرمجي على إجراء بحث شبكي بسيط للمعاملات الفائقة مع قرارات آلية مبنية على التنبيهات:

import trackio
import random
import time

def run_experiment(config):
    """Simulate a training run. Replace with real training code."""
    run = trackio.init(
        project="auto-hparam-search",
        config=config,
    )

    lr = config["learning_rate"]
    best_val_loss = float("inf")
    patience = 0

    for epoch in range(config["epochs"]):
        # Simulated metrics — replace with real training
        noise = random.gauss(0, lr * 10)
        train_loss = max(0.01, 1.0 / (epoch + 1) + noise)
        val_loss = train_loss + random.uniform(0, 0.3)
        val_acc = max(0, min(1, 1.0 - val_loss + random.uniform(-0.05, 0.05)))

        trackio.log({
            "train_loss": train_loss,
            "val_loss": val_loss,
            "val_accuracy": val_acc,
        })

        if train_loss > 5.0:
            trackio.alert(
                title="Training diverged",
                text=f"train_loss={train_loss:.4f}, lr={lr}",
                level=trackio.AlertLevel.ERROR,
            )
            break

        if val_loss < best_val_loss:
            best_val_loss = val_loss
            patience = 0
        else:
            patience += 1
            if patience >= 5:
                trackio.alert(
                    title="Early stopping",
                    text=f"Best val_loss={best_val_loss:.4f}",
                    level=trackio.AlertLevel.WARN,
                )
                break

        time.sleep(0.05)

    trackio.alert(
        title="Run complete",
        text=f"Final val_loss={val_loss:.4f}, val_acc={val_acc:.4f}, "
             f"best_val_loss={best_val_loss:.4f}",
        level=trackio.AlertLevel.INFO,
    )
    trackio.finish()
    return run.name


def analyze_and_decide(api, project, run_name, config):
    """Read alerts from a run and suggest new hyperparameters."""
    alerts = api.alerts(project, run=run_name)

    new_config = dict(config)
    for alert in alerts:
        title = alert["title"].lower()
        if "diverged" in title:
            new_config["learning_rate"] *= 0.1
        elif "early stopping" in title:
            new_config["learning_rate"] *= 0.5
        elif "run complete" in title and "val_acc" in (alert.get("text") or ""):
            # Slight refinement
            new_config["learning_rate"] *= 0.8
            new_config["epochs"] += 10

    return new_config


api = trackio.Api()
project = "auto-hparam-search"

config = {
    "learning_rate": 0.01,
    "batch_size": 64,
    "epochs": 30,
}

for iteration in range(5):
    print(f"\n--- Iteration {iteration + 1} ---")
    print(f"Config: {config}")

    run_name = run_experiment(config)
    config = analyze_and_decide(api, project, run_name, config)

هذا المثال مكتفٍ ذاتياً ويستخدم مقاييس محاكاة. استبدل جسم الدالة run_experiment بكود التدريب الفعلي لديك، وسيبقى النمط كما هو.

استخدام التنبيهات مع Transformers وTRL

عند استخدام report_to="trackio" مع Trainer الخاص بـ Hugging Face، يتولى TrackioCallback المدمج معالجة trackio.init() وtrackio.log() وtrackio.finish() تلقائيًا. وبما أن trackio.init() يُستدعى قبل بدء التدريب، يتم تعيين التشغيل الحالي، ويعمل trackio.alert() من أي مستدعٍ آخر في نفس العملية.

لإضافة تنبيهات، اكتب TrainerCallback صغيرًا وقم بتمريره إلى Trainer عبر callbacks=:

Transformers

import trackio
from transformers import Trainer, TrainerCallback, TrainingArguments

class AlertCallback(TrainerCallback):
    def on_log(self, args, state, control, logs=None, **kwargs):
        if "trackio" not in args.report_to or logs is None:
            return
        loss = logs.get("loss")
        if loss is not None and loss > 5.0:
            trackio.alert(
                title="Training loss spike",
                text=f"loss={loss:.4f} at step {state.global_step}. "
                     "Consider lowering the learning rate.",
                level=trackio.AlertLevel.ERROR,
            )

    def on_evaluate(self, args, state, control, metrics=None, **kwargs):
        if "trackio" not in args.report_to or metrics is None:
            return
        eval_loss = metrics.get("eval_loss")
        if eval_loss is not None and eval_loss > 2.0:
            trackio.alert(
                title="High eval loss",
                text=f"eval_loss={eval_loss:.4f} at step {state.global_step}.",
                level=trackio.AlertLevel.WARN,
            )

trainer = Trainer(
    model=model,
    args=TrainingArguments(
        report_to="trackio",
        project="my-project",
        output_dir="./output",
        num_train_epochs=3,
        eval_strategy="steps",
        eval_steps=100,
    ),
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    callbacks=[AlertCallback()],
)
trainer.train()

لا يحتاج الوكيل الذي يولّد هذا الكود سوى إلى تعريف فئة AlertCallback بالشروط الصحيحة، ثم إضافتها إلى قائمة callbacks. يبقى النمط نفسه بغض النظر عن النموذج أو مجموعة البيانات.

TRL

يعمل النهج نفسه مع مدرّبي TRL مثل GRPOTrainer أو SFTTrainer. إليك مثالاً على التعلّم المعزّز مع تنبيهات على انهيار المكافأة والانحراف المعلوماتي (KL divergence):

import trackio
from transformers import TrainerCallback

class RLAlertCallback(TrainerCallback):
    def on_log(self, args, state, control, logs=None, **kwargs):
        if "trackio" not in args.report_to or logs is None:
            return

        reward = logs.get("train/reward")
        if reward is not None and reward < -1.0:
            trackio.alert(
                title="Reward collapse",
                text=f"reward={reward:.4f} at step {state.global_step}. "
                     "Consider lowering the learning rate or checking the "
                     "reward model.",
                level=trackio.AlertLevel.ERROR,
            )

        kl = logs.get("train/kl")
        if kl is not None and kl > 10.0:
            trackio.alert(
                title="KL divergence too high",
                text=f"kl={kl:.4f} at step {state.global_step}. "
                     "The policy is drifting too far from the reference model.",
                level=trackio.AlertLevel.WARN,
            )

        completion_length = logs.get("train/completion_length")
        if completion_length is not None and completion_length < 5.0:
            trackio.alert(
                title="Completions too short",
                text=f"Mean completion length={completion_length:.1f} tokens. "
                     "The model may be collapsing to short outputs.",
                level=trackio.AlertLevel.WARN,
            )

ثم مرّرها إلى أي مُدرّب من مُدرّبي TRL:

from trl import GRPOTrainer, GRPOConfig

trainer = GRPOTrainer(
    model=model,
    config=GRPOConfig(
        report_to="trackio",
        project="rl-experiment",
        output_dir="./output",
    ),
    train_dataset=dataset,
    callbacks=[RLAlertCallback()],
)
trainer.train()

نصائح للوكلاء الذين يكتبون استدعاءات التنبيه

  • اجعل الشروط بسيطة. يجب أن يفحص كل كتلة if مقياسًا واحدًا مقابل حدّ واحد. وهذا يسهّل على الوكيل إضافة الشروط أو حذفها أو تعديلها بين التشغيلات.
  • تضمين قيمة المقياس والخطوة في text. يمنح هذا الوكيل أرقامًا محددة للتفكير بها عند تحديد المعلمات الفائقة التالية.
  • تضمين اقتراحات قابلة للتنفيذ. يساعد النص مثل «فكّر في خفض معدل التعلم» الوكيل على تحديد ما يجب تغييره في الخطوة التالية.
  • استخدم on_evaluate لمقاييس التقييم. مقاييس التقييم متاحة فقط في on_evaluate، وليس في on_log. تظهر مقاييس التدريب مثل loss في on_log.

ملخص أفضل الممارسات

  1. استخدم التنبيهات كإشارات منظمة، وليس مجرد إشعارات. شمل القيم الرقمية والاقتراحات القابلة للتنفيذ في text حتى يتمكن الوكيل من تحليلها والتصرف بناءً عليها.

  2. استخدم مستويات الخطورة بشكل متسق. ERROR = توقف وغيّر النهج. WARN = اضبط المعاملات. INFO = تم بلوغ مرحلة.

  3. استخدم الاستعلام الدوري مع since لتحقيق الكفاءة. احفظ الطابع الزمني للتنبيه الأخير الذي تمت معالجته وقم بتمريره كـsince في الاستعلام الدوري التالي لتجنب إعادة قراءة التنبيهات القديمة.

  4. احتفظ بجميع التشغيلات في نفس المشروع. يتيح ذلك للوكيل مقارنة التشغيلات جنبًا إلى جنب ورؤية التاريخ الكامل لما تم تجربته.

  5. سجّل الإعدادات مع كل تشغيل. مرّر دائمًا config= إلى trackio.init() حتى يتمكن الوكيل من قراءة المعلمات الفائقة التي أنتجت كل نتيجة.

  6. استخدم سطر الأوامر مع --json في سكربتات الوكلاء. مخرجات JSON موثوقة للتحليل ولن تتأثر إذا تغيّر التنسيق المقروء آليًا.

  7. فكّر في استخدام MCP للتكامل الوثيق. إذا كان إطار عمل الوكيل لديك يدعم MCP، فإن تشغيل trackio show --mcp-server يتيح للوكيل استدعاء أدوات Trackio مباشرة دون إنشاء عمليات فرعية.

Update on GitHub