unsloth/tmp/training_pydantic.md
2026-02-02 20:00:04 +00:00

113 lines
3 KiB
Markdown

# Training Pydantic Models Recommendation
## Current State
| Model | Purpose |
|-------|---------|
| `TrainingStartRequest` | Request payload to start training |
| `TrainingStartResponse` | Immediate response after `/start` |
| `TrainingStatusResponse` | Response for `/status` polling |
| `TrainingMetricsResponse` | Historical metrics |
| `TrainingProgressResponse` | Per-step progress data |
---
## Proposed Models
### 1. `TrainingStartRequest` — Keep as-is
Well-structured, no changes needed.
---
### 2. `TrainingJobResponse` (rename from `TrainingStartResponse`)
Returned **once** when `/train/start` is called.
```python
class TrainingJobResponse(BaseModel):
"""Immediate response when training is initiated"""
job_id: str
status: Literal["queued", "error"]
message: str
error: Optional[str] = None
```
---
### 3. `TrainingStatus` (unifies `TrainingStatusResponse` + `TrainingPhaseUpdate`)
Single model for **both streaming and polling**.
```python
class TrainingStatus(BaseModel):
"""Current training job status - works for streaming or polling"""
job_id: str
phase: Literal[
"idle",
"loading_model",
"loading_dataset",
"configuring",
"training",
"completed",
"error",
"stopped"
]
is_training_running: bool # True if training loop is actively running
message: str
error: Optional[str] = None
details: Optional[dict] = None # Phase-specific info, e.g. {"model_size": "8B"}
```
**Usage:**
- **Streaming**: Push when phase changes
- **Polling**: Return from `GET /train/status/{job_id}`
---
### 4. `TrainingProgress` (rename from `TrainingProgressResponse`)
Per-step metrics during active training.
```python
class TrainingProgress(BaseModel):
"""Training progress metrics - for streaming or polling"""
step: int
total_steps: int
loss: float
learning_rate: float
progress_percent: float
epoch: Optional[int] = None
elapsed_seconds: Optional[float] = None
eta_seconds: Optional[float] = None
```
---
### 5. `TrainingMetricsResponse` — Remove
Frontend stores history in IndexedDB.
---
## Summary
| Current | Proposed | Action |
|---------|----------|--------|
| `TrainingStartRequest` | `TrainingStartRequest` | Keep |
| `TrainingStartResponse` | `TrainingJobResponse` | Rename |
| `TrainingStatusResponse` | `TrainingStatus` | Rename + enhance |
| `TrainingMetricsResponse` | — | **Remove** |
| `TrainingProgressResponse` | `TrainingProgress` | Rename + enhance |
---
## API Flow
```
POST /train/start
└─► TrainingJobResponse { job_id, status: "queued" }
StreamingResponse / Polling:
└─► TrainingStatus { phase: "loading_model", is_training_running: false }
└─► TrainingStatus { phase: "loading_dataset", is_training_running: false }
└─► TrainingStatus { phase: "training", is_training_running: true }
└─► TrainingProgress { step: 1, loss: 2.5, ... }
└─► TrainingProgress { step: 2, loss: 2.3, ... }
└─► TrainingStatus { phase: "completed", is_training_running: false }
```