skills/valohai/valohai-skills/valohai-migrate-parameters

valohai-migrate-parameters

SKILL.md

Valohai Parameter Migration

Migrate hardcoded values in ML code to Valohai-managed parameters. Parameters cover both hyperparameters (learning rate, epochs, batch size) and configuration values (model name, output format, feature flags, thresholds, file paths). This makes jobs configurable without code changes, enables experiment tracking, hyperparameter sweeps, and reproducibility.

Philosophy

Valohai follows a YAML-over-SDK approach. Your ML code should not be entangled with the platform. Parameters are declared in valohai.yaml and injected as command-line arguments. Your code uses standard Python argparse to receive them.

Step-by-Step Instructions

1. Identify Hardcoded Values

Scan the user's ML code for hardcoded values that should be configurable. Parameters are not just for hyperparameters — any value that a user might want to change between runs belongs here:

  • Training hyperparameters: learning rate, batch size, epochs, dropout rate, weight decay
  • Model architecture: hidden layers, units per layer, activation functions, model type/name
  • Data processing: train/test split ratio, image size, sequence length, number of workers
  • Optimization: optimizer type, scheduler type, warmup steps, gradient clipping
  • Configuration values: output format, confidence thresholds, feature flags, model name/path, random seed, number of threads/workers, log level
  • Any magic numbers in training loops, model definitions, or scripts

2. Add argparse to the Python Code

Convert hardcoded values to command-line arguments using Python's standard argparse:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--learning_rate", type=float, default=0.001)
parser.add_argument("--epochs", type=int, default=10)
parser.add_argument("--batch_size", type=int, default=32)
parser.add_argument("--optimizer", type=str, default="adam")
parser.add_argument("--use_augmentation", action="store_true")
args = parser.parse_args()

Then replace every hardcoded reference with the parsed argument:

# Before
learning_rate = 0.001

# After
learning_rate = args.learning_rate

3. Declare Parameters in valohai.yaml

Add a parameters section to the step definition:

- step:
    name: train-model
    image: tensorflow/tensorflow:2.6.0
    command:
      - pip install -r requirements.txt
      - python train.py {parameters}
    parameters:
      - name: learning_rate
        type: float
        default: 0.001
      - name: epochs
        type: integer
        default: 10
      - name: batch_size
        type: integer
        default: 32
      - name: optimizer
        type: string
        default: adam
      - name: use_augmentation
        type: flag
        default: false

Command Interpolation: How Parameters Get Passed

Valohai supports several placeholders in the command field. Understanding the difference is critical to avoid argument parsing errors.

SYNTAX WARNING: The delimiter is always a colon (:), never brackets or parentheses. {parameter-value:name} is correct. {parameter-value[name]} and {parameter(name)} are WRONG and will silently fail.

{parameters} - Preferred approach

Expands to ALL parameters with their pass-as format (default: --name=value). This is the safest and most common approach:

command:
  - python train.py {parameters}
# Expands to: python train.py --learning_rate=0.001 --epochs=10 --optimizer=adam

{parameter:name} - Single parameter with pass-as format

Expands to the full --name=value formatted string for one parameter. Useful when parameters need to go in specific positions:

command:
  - python train.py --model /valohai/inputs/model/*.onnx {parameter:conf} {parameter:iou}
# Expands to: python train.py --model /valohai/inputs/model/*.onnx --conf=0.5 --iou=0.7

{parameter-value:name} - Raw value only

Expands to just the raw value, without the --name= prefix. Use this when you need to embed the value into a custom argument format:

command:
  - python train.py --threshold {parameter-value:threshold}
# Expands to: python train.py --threshold 0.5

Common mistake: using {parameter:name} where {parameter-value:name} is needed

# WRONG - double-passes the flag name, causes "expected one argument" errors
command:
  - python main.py --conf={parameter:conf}
# Expands to: python main.py --conf=--conf=0.5   <-- BROKEN

# CORRECT - use {parameter-value:name} for raw values
command:
  - python main.py --conf={parameter-value:conf}
# Expands to: python main.py --conf=0.5

# BEST - just use {parameter:name} on its own or {parameters} for all
command:
  - python main.py {parameter:conf} {parameter:iou}
# Expands to: python main.py --conf=0.5 --iou=0.7

Rule of thumb: Use {parameters} to pass all parameters. Use {parameter:name} when you need specific parameters in specific positions. Only use {parameter-value:name} when embedding a value into a custom format. Never combine --flag={parameter:name} - that double-wraps the argument. Always use colons{parameter-value:name} not {parameter-value[name]}.

4. Parameter Types Reference

Type YAML Python argparse CLI Example Notes
Integer type: integer type=int --epochs=100 Whole numbers
Float type: float type=float --lr=0.001 Decimal numbers
String type: string type=str --model=resnet Text values
Flag type: flag action='store_true' --augment When false, nothing is passed

5. Advanced Parameter Options

Constrained Ranges

parameters:
  - name: learning_rate
    type: float
    default: 0.001
    min: 0.0001
    max: 0.1
  - name: batch_size
    type: integer
    default: 32
    min: 8
    max: 512

Choices (Dropdown in UI)

parameters:
  - name: optimizer
    type: string
    default: adam
    choices:
      - adam
      - sgd
      - rmsprop
      - adamw

Optional Parameters

parameters:
  - name: pretrained_model
    type: string
    optional: true

Flag with Boolean Pass-Through

By default, flags only pass the flag name when true and pass nothing when false. For explicit true/false:

parameters:
  - name: verbose
    type: flag
    default: false
    pass-true-as: --verbose=True
    pass-false-as: --verbose=False

Custom Pass Format

parameters:
  - name: seed
    type: integer
    default: 42
    pass-as: --random-seed={v}

Multiple Values

parameters:
  - name: layers
    type: integer
    default: 128
    multiple: separate
    multiple-separator: ","

6. Alternative: Config File Approach

If the code cannot use argparse (e.g., it reads a config file), Valohai also creates config files automatically:

import json

# Valohai creates this file automatically from the parameter values
with open("/valohai/config/parameters.json") as f:
    params = json.load(f)
    learning_rate = params["learning_rate"]
    epochs = params["epochs"]

Or with YAML:

import yaml

with open("/valohai/config/parameters.yaml") as f:
    params = yaml.safe_load(f)

Common Patterns

PyTorch Training Script

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--epochs", type=int, default=10)
parser.add_argument("--learning_rate", type=float, default=0.001)
parser.add_argument("--batch_size", type=int, default=32)
parser.add_argument("--weight_decay", type=float, default=1e-5)
parser.add_argument("--optimizer", type=str, default="adam", choices=["adam", "sgd", "adamw"])
args = parser.parse_args()

# Use args throughout your training code
optimizer = torch.optim.Adam(model.parameters(), lr=args.learning_rate, weight_decay=args.weight_decay)
train_loader = DataLoader(dataset, batch_size=args.batch_size)

for epoch in range(args.epochs):
    train(model, train_loader, optimizer)

TensorFlow/Keras Training Script

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--epochs", type=int, default=50)
parser.add_argument("--learning_rate", type=float, default=0.001)
parser.add_argument("--batch_size", type=int, default=64)
parser.add_argument("--dropout_rate", type=float, default=0.5)
args = parser.parse_args()

model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=args.learning_rate), ...)
model.fit(x_train, y_train, epochs=args.epochs, batch_size=args.batch_size)

Validate the YAML

IMPORTANT: After adding parameters to valohai.yaml, always run vh lint to validate the configuration before attempting to run:

vh lint

This catches common issues like invalid parameter types, missing fields, bad indentation, and duplicate names. Fix any errors before proceeding.

Overriding Parameters at Runtime

Once parameters are defined, users can override them without changing code:

# Via CLI
vh execution run train-model --epochs=100 --learning_rate=0.0001 --adhoc

# Parameters also appear in the Valohai web UI for easy changes

Edge Cases

  • If code already uses argparse, just add the matching parameters section to valohai.yaml - no code changes needed
  • Parameter names in YAML must match the argparse argument names (without the -- prefix)
  • Use underscores in parameter names for consistency (both --learning_rate and --learning-rate work)
  • Flag parameters: when false, nothing is passed to the command line (the argparse default handles it)
  • The {parameters} placeholder is optional - if omitted, Valohai appends parameters to the last command
Weekly Installs
5
First Seen
6 days ago
Installed on
opencode5
gemini-cli5
claude-code5
github-copilot5
codex5
kimi-cli5