# Returning Results from Modal ## Basic Return Values Modal functions can return Python objects (dicts, lists, etc.): ```python @app.function(gpu="A100", image=image, timeout=3600) def train(): # ... training code ... return { "final_loss": float(metrics["final_val_loss"]), "grad_norm_std": float(metrics["grad_norm_std"]), "max_grad_norm": float(metrics["max_grad_norm"]), "training_steps": int(metrics["steps"]), } @app.local_entrypoint() def main(): results = train.remote() print(f"Results: {results}") # Save locally import json with open("results.json", "w") as f: json.dump(results, f, indent=2) ``` ## Supported Return Types | Type | Support | Notes | |------|---------|-------| | dict | Yes | Most common for metrics | | list | Yes | For sequences of results | | tuple | Yes | For multiple return values | | str, int, float | Yes | Primitive types | | numpy array | Limited | Convert to list first | | torch tensor | No | Convert to Python types | ## Converting Tensors Always convert tensors to Python types before returning: ```python @app.function(gpu="A100", image=image, timeout=3600) def train(): import torch # ... training ... # WRONG - can't return tensors # return {"loss": loss_tensor} # CORRECT - convert to float return { "loss": float(loss_tensor.item()), "losses": [float(l) for l in loss_history], } ``` ## Complete Example ```python import modal app = modal.App("model-training") image = modal.Image.debian_slim(python_version="3.11").pip_install( "torch", "einops", "numpy", "huggingface_hub", ) @app.function(gpu="A100", image=image, timeout=3600) def train_model(): # ... training code ... return { "final_loss": metrics["final_val_loss"], "training_steps": total_steps, "gpu": torch.cuda.get_device_name(0), } @app.local_entrypoint() def main(): results = train_model.remote() print(f"\nResults: {results}") import json with open("results.json", "w") as f: json.dump(results, f, indent=2) ``` ## Handling Failures If a function fails, no result is returned. Use try/except to handle errors: ```python @app.function(gpu="A100", image=image, timeout=3600) def train(): try: # ... training code ... return {"status": "success", "loss": final_loss} except Exception as e: return {"status": "error", "message": str(e)} ```