> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tuneplane.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# tp submit

> Submit a training job. Every flag is generated from the CLI itself.

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
tp submit <EXP> [options]
```

Validates and uploads the experiment, then displays a server-resolved preview for confirmation.
Only confirmation creates a queued job. Use `--yes` for an unattended submission.

The walkthrough is [submitting a job](https://docs.tuneplane.ai/en/guides/submit.md). This page is the flag reference, and
the table below comes from the CLI, so it cannot be out of date.

## Worked examples

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
# NeMo-RL GRPO on 8 GPUs
tp submit my-grpo --profile h200:8

# verl with a platform dataset and a one-off hyperparameter override
tp submit my-verl --profile h200:4 \
  --model Qwen/Qwen3.5-9B \
  --train-dataset alice/gsm8k-zh@v2 --train-data train.parquet \
  -s actor_rollout_ref.actor.optim.lr=1e-6

# heterogeneous pools, exporting when training succeeds
tp submit my-grpo --profile train=h200:8 --profile rollout=h100:2 --then export

# continue from an earlier run's checkpoint
tp submit my-dpo --profile h200:8 --init-from run/run-4f2a91/checkpoint

# your own trainer
tp submit my-custom --profile h100:1 \
  --image registry.example.com/train@sha256:abcd… \
  --observability-url https://wandb.example/my-proj
```

## Review, save and retry

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
tp submit my-grpo --profile h200:8 --preview
# Inspect the JSON file printed by the command, then confirm it:
tp submit --commit .tuneplane-data/submissions/<preview-id>.json
# Unattended submission:
tp submit my-grpo --profile h200:8 --yes
```

A preview expires after one hour. Confirmation sends its ID, digest and a stable
retry key. If the response is lost, repeat `--commit` with the **same file**;
the server returns the original receipt, even after that preview expires.
A new preview is a new submission and can create another job.

`--intent intent.json` accepts three input forms. Every form contains `form`,
`project`, and a complete `spec` (the `tuneplane/v1` JobSpec):

| Form | Additional fields |
| - | - |
| `source` | `source_file`: a local `.tar.gz`, relative to the intent file |
| `recipe` | `config`: the complete native configuration as a JSON object |
| `image` | `argv`: an explicit array of arguments; optional `working_directory` (default `/workspace`) |

Image form requires the `custom/custom` recipe. Arguments are literal: use an
explicit shell executable if a shell program is intended. OCI runtime images
must be pinned with `@sha256:` in the spec or deployment runtime registry.
The deployment must provide its standalone runner artifact before previewing.
Keep credentials in platform-managed bindings; do not put tokens into command
arguments or configuration files.

The Jobs page offers the same three forms, displays the resolved document, and
requires a separate confirmation. It can save the preview and download the
resolved source package. Browser source uploads are limited to 256 MiB; the CLI
uses the deployment upload limit. Downloading or previewing does not start work.

The public API is `POST /api/submissions/uploads`, authenticated streaming
`PUT /api/submissions/uploads/{id}` with `X-Upload-Token`,
`POST /api/submissions/previews`, and `POST /api/submissions/commits`.
`GET /api/submissions/previews/{id}/package` exports an owned, unexpired package.
After confirmation, the owner can also export through
`GET /api/jobs/{run_id}/submission/package`, independently of preview expiry.
The archive/header `POST /api/jobs` protocol is retired and returns 410.

## Notes the flag table cannot carry

* The project comes from `name` in `tuneplane.yaml`. There is no `--project`.
* `--framework-version` only does something together with `--upgrade-recipe`.
* `--observability-url` is required for a recipe declaring `external` observability and refused
  for one declaring `platform`.
* `--volume` and `--environment` take no version suffix for a volume, and require one for an
  environment.
* `--train-data` is a path *inside* the dataset once `--train-dataset` is given.

## `tp submit`

Submit a training job

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
tp submit [EXP] [options]
```

| Argument | Description |
| - | - |
| `EXP` | Experiment name or path |

| Option | Description |
| - | - |
| `--profile` | Target hardware and resources in one argument: h200 (the registry default shape), h200:4 (4 GPUs), h200:16 (2 full nodes). Repeat it to split pools per role (the heterogeneous extension point): --profile train=h200:8 --profile rollout=h100:2. Comma-separate roles that share a pool: --profile actor,rollout=h200:8 --profile teacher=h200:8 (repeatable) |
| `--method`, `-m` | Method identifier \<framework>/\<method> (e.g. nemo-rl/grpo, verl/grpo); read from the experiment directory's recipe.lock.json when omitted |
| `--set`, `-s` | Override a hyperparameter, repeatable. Types and ranges are checked locally against the method declaration, so a typo fails immediately (repeatable) |
| `--init-from` | Start from the previous stage's artifact (the SFT -> DPO -> GRPO pipeline) |
| `--model` | Base model path or Hub id; required for verl/TRL |
| `--train-data` | Training data path; required for verl/TRL. With a platform dataset declared (in the config or via --train-dataset), write the file name relative to the dataset (e.g. train.parquet) and the job side resolves it into the cache directory |
| `--validation-data` | Validation data path; required for verl/TRL, used like --train-data |
| `--train-dataset` | Platform dataset reference: pulled into the shared cache when the job starts, with \<NAME>\_DATA\_DIR injected. Prefer declaring it as data.train.dataset in the experiment config; this flag is only a temporary override |
| `--validation-dataset` | Platform dataset reference for the validation set; matches data.validation.dataset in the config |
| `--output-dataset` | Publish what this run produces as this dataset version. The job writes files into TUNEPLANE\_DATASET\_OUT\_DIR and the platform publishes them when the run succeeds -- the job is never given a credential for the registry, and the published dataset inherits the classification of the material the run read. Used by a preprocessing run over a corpus |
| `--volume` | Mount a governed directory read-only at \$VOLUMES\_DIR/\<name>; repeatable. Prefer declaring it as data.volumes in the experiment config; this flag is only a temporary override. A volume has no version -- its current contents are its contents. Run `tp volume ls` for the ids (repeatable) |
| `--environment` | Agent RL environment reference. Delivered like a corpus and for a stronger reason: a private environment is non-exportable, so the platform resolves the version into the job runtime and mounts it read-only. Run `tp env ls` to see the environments you can reference |
| `--taskset` | Immutable taskset \<owner>/\<name>@\<version> |
| `--image` | Job image (a tag is enough, e.g. registry/nemo-rl-ext:v0.7.0). Required for custom; for other frameworks it overrides the default image the console configured for them |
| `--then` | Run automatically after training succeeds (export/eval), repeatable (repeatable) |
| `--observability-url` | For an external observability recipe only; a platform recipe must not set it |
| `--framework-version` | Only together with --upgrade-recipe; on its own it does not rewrite the lock file |
| `--upgrade-recipe` | Upgrade this experiment's lock to the current catalog before submitting, reusing tp recipe upgrade |
| `--allow-dirty` | Allow uncommitted changes in the working tree (refused by default, to keep submissions traceable) |
| `--no-validate` | Skip the pre-submission validation |
| `--intent` `<file>` | Recipe, source or image submission JSON; source\_file is resolved relative to this file |
| `--commit` `<file>` | Confirm or retry a saved preview without uploading or resolving again |
| `--preview` | Resolve and save a preview without creating a Job |
| `--yes`, `-y` | Confirm the resolved submission without prompting |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.