2.4 KiBLFS
2.4 KiBLFS
Returning Results from Modal
Basic Return Values
Modal functions can return Python objects (dicts, lists, etc.):
@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:
@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
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:
@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)}