Parameter Sweeps¶
Sweeps run multiple training configurations in parallel. Define which hyperparameters to search, and Canard creates one task per combination.
Basic Sweep¶
from canard import Client
client = Client(api_url="https://api.canard.cloud")
run = client.submit_training_sweep(
name="lr-sweep",
task_name="Template-Go2-Standing-Direct-v0",
code_url="https://github.com/canard-cloud/go2-standing-env",
sweep_params={
"learning_rate": [1e-4, 3e-4, 1e-3, 3e-3],
},
num_envs=4096,
max_iterations=5000,
gpu_count=2,
)
This creates 4 tasks, one per learning rate. They run in parallel on separate GPUs.
Multi-Parameter Sweep¶
Sweep across multiple parameters — Canard creates the full grid:
run = client.submit_training_sweep(
name="lr-entropy-sweep",
task_name="Template-Go2-Standing-Direct-v0",
code_url="https://github.com/canard-cloud/go2-standing-env",
sweep_params={
"learning_rate": [1e-4, 3e-4, 1e-3],
"entropy_coef": [0.005, 0.01, 0.05],
},
num_envs=4096,
max_iterations=5000,
gpu_count=2,
)
# Creates 3 x 3 = 9 tasks
Multi-Seed Evaluation¶
For publishable results, conferences require multiple seeds per configuration. Add a seed sweep:
run = client.submit_training_sweep(
name="publication-seeds",
task_name="Template-Go2-Standing-Direct-v0",
code_url="https://github.com/canard-cloud/go2-standing-env",
sweep_params={
"learning_rate": [1e-4, 3e-4, 1e-3],
"seed": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
},
num_envs=4096,
max_iterations=5000,
gpu_count=2,
)
# 3 LRs x 10 seeds = 30 tasks
Sweepable Parameters¶
Any TrainingConfig field can be swept:
| Parameter | Type | Example Values |
|---|---|---|
learning_rate |
float | [1e-4, 3e-4, 1e-3] |
clip_param |
float | [0.1, 0.2, 0.3] |
entropy_coef |
float | [0.005, 0.01, 0.05] |
gamma |
float | [0.95, 0.99, 0.999] |
lam |
float | [0.9, 0.95, 0.99] |
desired_kl |
float | [0.005, 0.01, 0.02] |
num_learning_epochs |
int | [3, 5, 8] |
num_mini_batches |
int | [2, 4, 8] |
seed |
int | [1, 2, 3, 4, 5] |
Analyzing Results¶
After the sweep completes:
run.wait_for_completion(show_progress=True)
# Get all tasks with their configs and results
tasks = run.get_tasks()
for task in tasks:
if task.status == "completed" and task.metrics:
lr = task.params.get("learning_rate", "default")
reward = task.metrics.training_progress.mean_reward
print(f"LR={lr}: reward={reward:.2f}")
Cost Estimation¶
Before submitting, estimate the cost:
from canard.models import TrainingConfig
config = TrainingConfig(
task_name="Template-Go2-Standing-Direct-v0",
num_envs=4096,
max_iterations=5000,
gpu_count=2,
)
est = config.estimate_cost(total_tasks=30)
print(f"Per task: ${est['task_cost']:.2f}")
print(f"Total: ${est['total_cost']:.2f}")
print(f"Time: ~{est['wall_time_hr']:.1f} hr (parallel)")
See Cost Estimation for details on the pricing model.