85742ab165
Deploy Documentation / deploy (push) Has been cancelled
CPU Test / Test (Utilities, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (LLM proxy, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Others, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Store, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Utilities, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Weave, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (AgentOps, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (LLM proxy, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (Others, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (Weave, latest, Python 3.13) (push) Has been cancelled
Dashboard / Chromatic (push) Has been cancelled
CPU Test / Lint - fast (push) Has been cancelled
CPU Test / Lint - next (push) Has been cancelled
CPU Test / Lint - slow (push) Has been cancelled
CPU Test / Lint - JavaScript (push) Has been cancelled
CPU Test / Build documentation (push) Has been cancelled
CPU Test / Test (AgentOps, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (LLM proxy, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (Others, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (Store, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (Weave, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (AgentOps, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Store, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (Utilities, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (Weave, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (AgentOps, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (LLM proxy, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (Others, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (Store, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (Utilities, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (JavaScript) (push) Has been cancelled
116 lines
4.4 KiB
Python
116 lines
4.4 KiB
Python
# Copyright (c) Microsoft. All rights reserved.
|
|
|
|
"""This sample provides an all-in-one script for SFT algorithm.
|
|
|
|
It's equivalent to running the following commands in parallel:
|
|
|
|
```bash
|
|
agl store
|
|
python sft_rollout_runners.py
|
|
python sft_algorithm.py
|
|
```
|
|
"""
|
|
|
|
from typing import Optional
|
|
|
|
from math_agent import GsmProblem, load_math_dataset, math_agent
|
|
from rich.console import Console
|
|
from sft_algorithm import sft_one_iter
|
|
|
|
from agentlightning import Trainer, setup_logging
|
|
from agentlightning.adapter import TraceToTripletBase
|
|
from agentlightning.algorithm import Algorithm
|
|
from agentlightning.llm_proxy import LLMProxy
|
|
from agentlightning.types import Dataset
|
|
|
|
console = Console()
|
|
|
|
|
|
class UnslothSupervisedFinetuning(Algorithm):
|
|
"""Supervised Fine-Tuning (SFT) algorithm implementation using Unsloth.
|
|
|
|
This class implements a complete SFT training loop that:
|
|
1. Runs rollouts with the current model
|
|
2. Collects and ranks training data by reward
|
|
3. Fine-tunes the model on top-performing examples
|
|
4. Iterates for multiple rounds of improvement
|
|
|
|
Args:
|
|
max_iterations: The maximum number of SFT iterations to perform.
|
|
vllm_port: The port to use for the vLLM inference server.
|
|
train_triplet_fraction: The fraction of top-performing triplets to use for training (0.0 to 1.0).
|
|
initial_model_path: The path to the initial model to start training from.
|
|
"""
|
|
|
|
def __init__(self, *, max_iterations: int, vllm_port: int, train_triplet_fraction: float, initial_model_path: str):
|
|
# LLM proxy and data adapter are created by the trainer and we can directly use them
|
|
self.max_iterations = max_iterations
|
|
self.vllm_port = vllm_port
|
|
self.train_triplet_fraction = train_triplet_fraction
|
|
self.initial_model_path = initial_model_path
|
|
|
|
async def run(
|
|
self, train_dataset: Optional[Dataset[GsmProblem]] = None, val_dataset: Optional[Dataset[GsmProblem]] = None
|
|
):
|
|
"""Execute the SFT training loop. Managed by trainer.
|
|
|
|
Args:
|
|
train_dataset: The training dataset of GSM problems to use for rollouts.
|
|
val_dataset: Optional validation dataset (not currently used in SFT).
|
|
|
|
Raises:
|
|
ValueError: If train_dataset is None, or required components are missing.
|
|
"""
|
|
store = self.get_store()
|
|
llm_proxy = self.get_llm_proxy()
|
|
data_adapter = self.get_adapter()
|
|
|
|
# SFT trainer relies on the adapter to convert the trace data to triplets
|
|
if not isinstance(data_adapter, TraceToTripletBase):
|
|
raise ValueError("Data adapter must be a TracerTraceToTriplet.")
|
|
if train_dataset is None:
|
|
raise ValueError("Train dataset must be provided.")
|
|
if val_dataset is not None:
|
|
console.print("[bold red][Algo][/bold red] Validation dataset is not supported in SFT.")
|
|
if llm_proxy is None:
|
|
raise ValueError("LLM proxy must be provided.")
|
|
|
|
console.print(f"[bold red][Algo][/bold red] Starting SFT with {self.max_iterations} iterations.")
|
|
console.print(f"[bold red][Algo][/bold red] Initial model path: {self.initial_model_path}")
|
|
model_path = self.initial_model_path
|
|
for iteration in range(self.max_iterations):
|
|
model_path = await sft_one_iter(
|
|
iteration=iteration,
|
|
store=store,
|
|
model_path=model_path,
|
|
train_dataset=train_dataset,
|
|
llm_proxy=llm_proxy,
|
|
data_adapter=data_adapter,
|
|
triplet_fraction=self.train_triplet_fraction,
|
|
vllm_port=self.vllm_port,
|
|
)
|
|
|
|
console.print(f"[bold red][Algo][/bold red] Final model path: {model_path}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
setup_logging()
|
|
|
|
algo = UnslothSupervisedFinetuning(
|
|
max_iterations=2,
|
|
vllm_port=12316,
|
|
train_triplet_fraction=0.5,
|
|
initial_model_path="models/version_0",
|
|
)
|
|
trainer = Trainer(
|
|
n_runners=4,
|
|
algorithm=algo,
|
|
llm_proxy=LLMProxy(port=12358),
|
|
# Uncomment the following two lines if you want to rely on proxy-side trace data collection
|
|
# Otherwise, the rollout runner will have an agentops tracer to collect the trace data,
|
|
# and the adapter will be a TracerTraceToTriplet that parses the trace data generated by this tracer
|
|
# adapter=LlmProxyTraceToTriplet(),
|
|
# tracer=OtelTracer(),
|
|
)
|
|
trainer.fit(math_agent, load_math_dataset())
|