Download main.py from Ugas/routing-agent: direct link, hf CLI and curl.
- Browser
- Download file 4.32 kB
-
https://huggingface.co/Ugas/routing-agent/resolve/main/main.py
- Command line
-
hf download hf://Ugas/routing-agent/main.py
-
curl -L -o main.py https://huggingface.co/Ugas/routing-agent/resolve/main/main.py
4.32 kB
| #!/usr/bin/env python3 | |
| import os | |
| import sys | |
| import argparse | |
| import csv | |
| import torch | |
| ROOT = os.path.dirname(__file__) | |
| def build_dataset_from_csv(csv_path): | |
| dataset = [] | |
| with open(csv_path, newline='', encoding='utf-8') as f: | |
| reader = csv.DictReader(f) | |
| for row in reader: | |
| q = row.get('question') or row.get('Question') | |
| lbl = row.get('label') or row.get('Label') | |
| if q is None or lbl is None: | |
| continue | |
| try: | |
| lbl = int(lbl) | |
| except Exception: | |
| continue | |
| dataset.append({'question': q, 'label': lbl}) | |
| return dataset | |
| class EmbedderWrapper: | |
| """Wrap a SentenceTransformer instance to ensure tensors are on `device`. | |
| The wrapper exposes `encode(texts, convert_to_tensor=True, **kwargs)` same as | |
| the SentenceTransformer API and will move returned torch.Tensor to the device. | |
| """ | |
| def __init__(self, embedder, device): | |
| self.embedder = embedder | |
| self.device = device | |
| def encode(self, texts, convert_to_tensor=True, **kwargs): | |
| emb = self.embedder.encode(texts, convert_to_tensor=convert_to_tensor, **kwargs) | |
| # Move tensor outputs to device (if it's a torch.Tensor) | |
| if convert_to_tensor and hasattr(emb, 'to'): | |
| try: | |
| emb = emb.to(self.device) | |
| except Exception: | |
| pass | |
| return emb | |
| def main(): | |
| parser = argparse.ArgumentParser(description='Run SFT training for RouterNetwork') | |
| parser.add_argument('--csv', default='processed_dataset.csv', help='Path to CSV dataset') | |
| parser.add_argument('--model_name', default='all-MiniLM-L6-v2', help='SentenceTransformer model name') | |
| parser.add_argument('--epochs', type=int, default=5) | |
| parser.add_argument('--lr', type=float, default=1e-3) | |
| parser.add_argument('--checkpoint', default='router_checkpoint.pt', help='Checkpoint output path') | |
| parser.add_argument('--device', default=None, help='Device to use (cpu or cuda). Auto-detect if unset') | |
| args = parser.parse_args() | |
| # Ensure routing_agent directory is importable such that its modules' imports work | |
| routing_agent_path = os.path.join(ROOT, 'routing_agent') | |
| if routing_agent_path not in sys.path: | |
| sys.path.insert(0, routing_agent_path) | |
| # Import modules from routing_agent (sft_trainer expects to import model as a top-level module) | |
| try: | |
| import sft_trainer | |
| import model as model_mod | |
| except Exception as e: | |
| print('Failed importing routing_agent modules:', e) | |
| sys.exit(1) | |
| # Device selection | |
| if args.device: | |
| device = torch.device(args.device) | |
| else: | |
| device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') | |
| # Build dataset | |
| csv_path = os.path.join(ROOT, args.csv) if not os.path.isabs(args.csv) else args.csv | |
| if not os.path.exists(csv_path): | |
| print('Dataset CSV not found at', csv_path) | |
| sys.exit(1) | |
| dataset = build_dataset_from_csv(csv_path) | |
| if len(dataset) == 0: | |
| print('No valid rows found in dataset. Exiting.') | |
| sys.exit(1) | |
| # Initialize embedder | |
| try: | |
| from sentence_transformers import SentenceTransformer | |
| except Exception as e: | |
| print('sentence-transformers not installed or failed to import:', e) | |
| sys.exit(1) | |
| embedder = SentenceTransformer(args.model_name) | |
| embedder_wrapper = EmbedderWrapper(embedder, device) | |
| # Infer embedding dim and instantiate model from the same module sft_trainer expects | |
| try: | |
| embed_dim = embedder.get_sentence_embedding_dimension() | |
| except Exception: | |
| # fallback to common dim | |
| embed_dim = 384 | |
| model = model_mod.RouterNetwork(embedding_dim=embed_dim, num_classes=3).to(device) | |
| # Run SFT training | |
| print(f"Starting SFT training on device={device} with model={args.model_name} | epochs={args.epochs} | lr={args.lr}") | |
| sft_trainer.train_sft(model, embedder_wrapper, dataset, epochs=args.epochs, lr=args.lr) | |
| # Save checkpoint | |
| try: | |
| torch.save(model.state_dict(), args.checkpoint) | |
| print('Saved checkpoint to', args.checkpoint) | |
| except Exception as e: | |
| print('Failed to save checkpoint:', e) | |
| if __name__ == '__main__': | |
| main() | |