muhammadjalaludin
Implement service layers for backup, model management, file handling, tokenization, and training
1424118 Download api/train.py from kota101/ta_ml: direct link, hf CLI and curl.
- Browser
- Download file 5.27 kB
-
https://huggingface.co/spaces/kota101/ta_ml/resolve/main/api/train.py
- Command line
-
hf download hf://spaces/kota101/ta_ml/api/train.py
-
curl -L -o train.py https://huggingface.co/spaces/kota101/ta_ml/resolve/main/api/train.py
5.27 kB
| # ta_ml/api/train.py | |
| """ | |
| API endpoints for model training. | |
| """ | |
| import logging | |
| from typing import List, Tuple | |
| import pandas as pd | |
| from fastapi import (APIRouter, BackgroundTasks, Body, Depends, File, | |
| HTTPException, UploadFile, status) | |
| from api.dependencies import get_training_service | |
| from data.file_handler import FileHandler, FileHandlerError | |
| from models.api import (TrainDirectRequest, TrainingResponse) | |
| from services.training_service import TrainingService | |
| logger = logging.getLogger(__name__) | |
| router = APIRouter(prefix="/train", tags=["Training"]) | |
| def _extract_data_from_df(df: pd.DataFrame) -> Tuple[List[str], List[str]]: | |
| """Helper to extract texts and labels from a DataFrame.""" | |
| if "text" in df.columns and "label" in df.columns: | |
| return df["text"].dropna().astype(str).tolist(), df["label"].dropna().astype(str).tolist() | |
| # Fallback for wide format | |
| texts, labels = [], [] | |
| label_columns = [col for col in df.columns if col.lower() not in [ | |
| "nomor", "no"]] | |
| if not label_columns: | |
| raise HTTPException( | |
| status_code=400, detail="Could not find 'text'/'label' columns or any other valid label columns.") | |
| for _, row in df.iterrows(): | |
| for col in label_columns: | |
| if pd.notna(row[col]): | |
| texts.append(str(row[col])) | |
| labels.append(col) | |
| if not texts: | |
| raise HTTPException( | |
| status_code=400, detail="No valid text-label pairs found in the file.") | |
| return texts, labels | |
| def _run_training_task( | |
| training_service: TrainingService, | |
| texts: List[str], | |
| labels: List[str] | |
| ): | |
| """The actual training function to be run in the background.""" | |
| try: | |
| logger.info(f"Background training started for {len(texts)} samples.") | |
| metrics = training_service.train_model(texts, labels) | |
| logger.info( | |
| f"Background training finished successfully. F1 Score: {metrics.f1_score:.4f}") | |
| except Exception as e: | |
| logger.error(f"Background training task failed: {e}", exc_info=True) | |
| async def train_from_file( | |
| background_tasks: BackgroundTasks, | |
| file: UploadFile = File(..., | |
| description="A CSV or Excel file with training data."), | |
| training_service: TrainingService = Depends(get_training_service), | |
| ): | |
| try: | |
| df = FileHandler.read_to_dataframe(file) | |
| texts, labels = _extract_data_from_df(df) | |
| except FileHandlerError as e: | |
| raise HTTPException(status_code=400, detail=str(e)) | |
| except HTTPException as e: | |
| raise e | |
| background_tasks.add_task( | |
| _run_training_task, training_service, texts, labels) | |
| return TrainingResponse(message="Training has been accepted and started in the background. Check logs for completion status.") | |
| async def train_from_data( | |
| request: TrainDirectRequest, | |
| background_tasks: BackgroundTasks, | |
| training_service: TrainingService = Depends(get_training_service), | |
| ): | |
| if len(request.texts) != len(request.labels): | |
| raise HTTPException( | |
| status_code=400, detail="The 'texts' and 'labels' lists must have the same number of items.") | |
| background_tasks.add_task( | |
| _run_training_task, training_service, request.texts, request.labels) | |
| return TrainingResponse(message="Training has been accepted and started in the background. Check logs for completion status.") | |