Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ jobs:
run: python -m pytest
- name: Example contract smoke
run: bash examples/native/cpu_contract_smoke.sh
- name: New user Hello World
run: harborrl hello --out-dir /tmp/harborrl-hello
- name: Training dry run
run: python -m harborrl.cli train --config examples/native/train_qwen_native.yaml --dry-run
- name: Public tree audit
Expand Down Expand Up @@ -77,6 +79,8 @@ jobs:
python -m venv /tmp/harborrl-wheel
/tmp/harborrl-wheel/bin/pip install dist/*.whl
/tmp/harborrl-wheel/bin/harborrl --help
cd /tmp
/tmp/harborrl-wheel/bin/harborrl hello --out-dir /tmp/harborrl-wheel-hello
- uses: actions/upload-artifact@v4
with:
name: harborrl-dist
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,14 @@ HarborRL supports flexible combinations of **Models × Algorithms × Tasks × Ha

For the offline options catalog, interactive configuration, and answer-file setup,
see the [configuration CLI guide](docs/configuration-wizard.md).
Start with `harborrl options` or `harborrl init --help`.
Start with `harborrl hello` for a CPU walkthrough requiring no model, GPU or task
JSON. It executes scripted attempts and a real verifier, then exports a GRPO batch
with fixture tokens. Continue with `harborrl options` or `harborrl init --help`.
The wizard detects one shared Local environment, calculates model fingerprints,
and supports incomplete drafts (`:save` / `--resume`).

Run `harborrl web` to open the local browser console for configuration, validation,
dry-runs, training launch, and logs. See the [web console guide](docs/web-console.md)
drafts, filled Local/Sandbox examples, Hello World, dry-runs, training launch, and logs. See the [web console guide](docs/web-console.md)
for remote-controller access and lifecycle details.

If you want an AI agent to help deploy this repository and verify training,
Expand Down
8 changes: 6 additions & 2 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,12 @@ HarborRL 支持 **Models × Algorithms × Tasks × Harnesses (MATH)** 的灵活
[docs/agents/environment-check.md](docs/agents/environment-check.md)。

离线选项目录、交互式配置和 answer-file 配置方式见[配置 CLI 指南](docs/configuration-wizard.md)。
可以从 `harborrl options` 或 `harborrl init --help` 开始。
运行 `harborrl web` 可打开本地浏览器控制台,完成配置、校验、dry-run、训练启动和日志查看;
首次使用可以先运行 `harborrl hello`:无需模型、GPU 或已有 task JSON,
即可执行脚本任务、真实 verifier、0/1 奖励收集和使用示例 token 的 GRPO batch 导出。
接着使用 `harborrl options` 或 `harborrl init --help`。Local 模式会检测并共用
一套源码目录与 Python;模型指纹自动计算,未填完的草稿支持 `:save` 保存和 `--resume` 恢复。
运行 `harborrl web` 可打开浏览器控制台,查看或套用 Local/Sandbox 示例、
随时保存草稿、一键运行 Hello World,并完成校验、dry-run、训练启动和日志查看;
远程访问与生命周期说明见 [Web 控制台指南](docs/web-console.md)。

推荐的实际操作流程是把下面这段提示词交给 agent,并把尖括号内容替换成你的机器信息:
Expand Down
87 changes: 68 additions & 19 deletions docs/configuration-wizard.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,28 @@

The configuration tools run with the core package (Python 3.10+ and PyYAML).
They enumerate implemented capabilities, check configuration offline, and create
consistent training schema 2 / deployment schema 1 files. They do not install
software, download tasks or models, connect over SSH, or allocate Sandbox/GPU jobs.
consistent training schema 2 / deployment schema 1 files. Catalog, preview and
validation stay offline. Model preparation explicitly runs the selected Python
locally or over SSH to fingerprint an existing tokenizer. It does not download
models or allocate Sandbox/GPU jobs.

## First run without a task JSON or GPU

Install the core package and try the bundled CPU walkthrough:

```bash
python -m pip install -e .
harborrl hello --out-dir ./hello-first
harborrl web --workspace ./harborrl-web
```

Hello World executes two scripted attempts at creating a file, runs the actual
task verifier, collects rewards 0 and 1, assembles native IR and exports a GRPO
batch. It uses fixture token evidence, marked `CONTRACT_READY`; it does not perform
model inference or update GPU weights. All files stay under the new output
directory. The generated `catalog.json` and `claude-code-profile.json` can be reused
when configuring real training. The command also works from an installed wheel
outside a source checkout, on Windows or Linux.

## Browse and validate

Expand Down Expand Up @@ -58,12 +78,13 @@ compatibility is additionally checked by the existing training dry-run.
2. Prepare a pinned Claude Code profile. See
[the native examples](../examples/native) for profile structure. It must match
the agent and task requirements of your deployment.
3. Stage checkpoint and reference directories on the GPU target. In its existing
training environment, load the actual local tokenizer with the same options as
the runtime and call `harborrl.rollout.runtime.tokenizer_fingerprint(tokenizer)`.
Its return values are `tokenizer_digest, template_digest`. This is an explicit
preparation step, not an operation performed by the wizard. Hashing a filename
or guessing an arbitrary 64-character value does not establish compatibility.
3. Stage checkpoint and reference directories on the GPU target. The wizard
calculates both tokenizer fingerprints automatically, using that target's
Python with Transformers installed. No manual SHA-256 entry is needed. In Web,
choose **Prepare model** after setting the checkpoint and environment. The
operation loads tokenizer files offline with `trust_remote_code=False` and calls
the same fingerprint function as the rollout runtime. A missing dependency or
checkpoint produces an actionable error; the draft can still be saved.
4. Identify controller/GPU/runner Python executables, checkout paths, SSH aliases
and shared storage. Service origins must include their declared ports and be
reachable by the participating machines.
Expand All @@ -79,13 +100,36 @@ harborrl init --out-dir ./site-new
harborrl init --answers my-answers.yaml --out-dir ./site-new
```

Interactive mode asks for deployment roles, existing inputs, model fingerprints,
GPU layout and a few sampling settings, then previews both configurations and
requires `yes` to publish. Entering no or EOF cancels. Non-terminal use requires
`--answers`; missing required answers never fall back to prompting.
Interactive mode explains each required field. Local asks for one shared source
directory and Python interpreter, detected from the host running the wizard;
Controller, GPU and rollout all use those values. Storage is configured
separately. Service modes ask for each remote role and its reachable origins.
The wizard prepares model fingerprints automatically, previews both
configurations and requires `yes` to publish.

Progress is saved after every answer to `OUT_DIR.draft.json`. Type `?` for help,
`:skip` to leave a field empty, or `:save` to save and exit. Ctrl+C or EOF after
choosing a deployment also keeps the draft. Resume it later:

```bash
harborrl init --out-dir ./site-new --resume ./site-new.draft.json
harborrl init --out-dir ./empty-site --save-draft
harborrl init --out-dir ./local-example --example local
harborrl init --out-dir ./sandbox-example --example sandbox
```

`--example` saves a filled reference draft using the current host's detected
environment. Replace example paths and hosts before resuming. `--draft-file`
chooses a different progress file. Incomplete drafts never become runnable
bundles. Draft updates check revisions and reject stale writers.

Non-terminal generation accepts `--answers` or `--resume`. Missing fingerprints
trigger explicit tokenizer preparation; `--prepare-model` recalculates existing
values. Missing required answers never fall back to prompting. Use `--save-draft`
to store incomplete answers without running preparation or final validation.

Start from one of these complete answer templates and replace every `REPLACE_*`
value and example path before running:
Start from one of these reference answer templates and replace example paths
before running:

- [embedded-local](../examples/options/embedded-local.answers.yaml): one machine,
local Harbor runner, colocated training/serving by default.
Expand All @@ -94,13 +138,18 @@ value and example path before running:
- [service-sandbox-local-runner](../examples/options/service-sandbox.answers.yaml):
controller and runner here, SSH GPU target, Sandbox task execution.

Templates deliberately contain invalid digest placeholders. They cannot claim
training readiness without your real inputs. Default one-GPU colocate is a
configuration starting point, not a Qwen model memory-fit recommendation.
Templates leave fingerprints empty for automatic preparation. Web also offers
filled Local and Sandbox recipes with notes, download and apply actions.
GPU allocations illustrate topology; confirm memory requirements for your model
before training. For Local Docker, the gateway advertised origin must be
reachable inside task containers. On Linux, configure the host-gateway mapping
if using `host.docker.internal`, or choose a reachable host address.

Answers allow only `answers_version: 1`, `preset`, `training`, `deployment`, and
optional `sandbox_config`. Overrides use the existing schema section/field names;
unknown keys fail. No expressions or shell commands are evaluated. Gateway fields,
optional `sandbox_config` and `local_environment`. Local's `local_environment`
contains `source_dir` and `python` and applies to all three roles, taking precedence
over advanced per-role overrides. Overrides use the existing schema field names;
unknown keys fail. Answer values are not evaluated as shell expressions. Gateway fields,
shared run root, GPU budget and worker destinations are derived when only one
side is provided. Contradictory explicit values fail. Supply matching origin URLs
when changing ports. Paths in training overrides are relative to the **final
Expand Down
48 changes: 32 additions & 16 deletions docs/web-console.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,48 @@ harborrl web --workspace ./harborrl-web

This opens a browser on an available loopback port. Keep the terminal running.
`--port 8765` chooses a fixed port; `--no-browser` prints the URL without opening
it. The workspace stores saved configuration bundles and execution records.
it. The workspace stores drafts, saved configuration bundles and execution records.
One console process owns a workspace at a time. The web console uses the core
Python dependencies; Node, a frontend build and CDN access are not required.

## Configure and launch

1. Select Local, SSH workers, or Sandbox. Fill controller/GPU/runner paths and
service origins. Source and interpreter paths refer to the selected machine.
The controller source directory and Python executable select the checkout and
environment used by the launched CLI.
2. Provide existing checkpoint/reference directories, a pinned task catalog,
harness profile and real tokenizer/template fingerprints. The
[configuration CLI guide](configuration-wizard.md) describes preparing these
inputs. The console never downloads or generates model inputs.
3. Choose GPU layout, tensor parallelism, rollout batches and sampling settings.
1. New users can first select **Run Hello World**. It needs no task JSON, model
or GPU and opens the Runs view with actual execution logs. This CPU walkthrough
runs scripted attempts and a real verifier, then exports a GRPO batch using
clearly marked fixture tokens; it does not run model inference or training.
2. Open **Local example** or **Sandbox example** to view, download or apply a
filled best-practice recipe. Replace example model paths and service hostnames.
In Local, source directory and Python are detected on the machine running the
console and edited once for Controller, GPU and rollout. Storage is separate.
SSH workers and Sandbox expose the paths belonging to their remote roles.
3. Provide checkpoint/reference directories. **Use bundled Hello World task &
profile** creates valid input files locally, or supply your own pinned catalog
and profile. Select **Prepare model** to calculate both fingerprints using the
real tokenizer and selected GPU Python, over SSH when needed. No manual SHA-256
entry is shown. Changing the checkpoint or target environment clears the old
fingerprints. See [the CLI guide](configuration-wizard.md) for prerequisites.
4. Choose GPU layout, tensor parallelism, rollout batches and sampling settings.
Allocation defaults are configuration values, not a model memory-fit estimate.
4. Review the generated YAML and validation. **Check local files** additionally
5. Review the generated YAML and validation. Missing fields appear in a prominent
list with bold labels, help and links that focus the relevant input. Required
inputs also have inline explanations. **Check local files** additionally
checks references on the controller. Deferred GPU, connectivity, model and
Sandbox checks remain explicit. Save the bundle under a new configuration name.
5. Run **Dry-run** to build the actual CLI launch plan. **Doctor** performs live
Sandbox checks remain explicit. **Create runnable configuration** publishes the
validated bundle.
6. Run **Dry-run** to build the actual CLI launch plan. **Doctor** performs live
checks after confirmation. **Start training** requires a separate confirmation
and invokes the existing `harborrl train` flow, including its preflight.

Configuration names are limited to letters, digits, underscores and hyphens.
Saved configurations are not overwritten. Reopen one to launch it again, or edit
and save under a new name. The advanced answers editor and YAML/JSON import use
Use **Save draft** at any step, including an empty or incomplete configuration.
Drafts appear separately from Runnable configurations in the sidebar; reopen one
to continue and save another revision under the same name. They survive server
restarts. Stale revisions from another tab are rejected so work is not silently
overwritten. Drafts cannot start Dry-run, Doctor or training.

Runnable configurations are immutable. Reopen one to launch it again, or edit it
and publish a new numbered version. The advanced answers editor and YAML/JSON import use
the existing `answers_version: 1` contract. Download an individual generated file
or export answers from the editor. Advanced remote Sandbox runners can be
specified through imported answers; the form preset defaults to a local runner.
Expand All @@ -48,7 +64,7 @@ the project's supported Linux training environment.

## Runs and shutdown

Only one execution is active per workspace, including doctor and dry-run. This
Only one execution is active per workspace, including Hello World, doctor and dry-run. This
prevents duplicate launches within this console; it is not a cluster-wide GPU
scheduler. Other CLI processes or different workspaces can still use the same
resources, and operators must coordinate those allocations.
Expand Down
26 changes: 14 additions & 12 deletions examples/options/embedded-local.answers.yaml
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
# Replace every example path and REPLACE_* value. No model fit is implied.
# Reference recipe. Replace example paths; init calculates model fingerprints.
answers_version: 1
preset: embedded-local
local_environment:
source_dir: /srv/harborrl/source
python: /opt/harborrl/bin/python
training:
tasks:
catalog: /srv/harborrl/inputs/tasks.jsonl
harness:
profile: /srv/harborrl/inputs/claude-code.json
harbor:
python: /opt/harbor/bin/python
model:
checkpoint: /srv/models/qwen
reference: /srv/models/qwen-reference
args_file: qwen3-8B
gateway:
tokenizer_digest: REPLACE_WITH_ACTUAL_TOKENIZER_SHA256
template_digest: REPLACE_WITH_ACTUAL_TEMPLATE_SHA256
host: 0.0.0.0
advertised_url: http://host.docker.internal:49184
tokenizer_digest: null
template_digest: null
deployment:
layout: colocate
num_gpus: 1
num_gpus: 4
sampling:
group_size: 2
groups_per_batch: 1
deployment:
manager:
source_dir: /srv/harborrl/source
controller_python: /opt/controller/bin/python
gpu_target:
source_dir: /srv/harborrl/source
train_python: /opt/training/bin/python
storage:
run_root: /srv/harborrl/runs
# Linux Docker must map host.docker.internal to host-gateway, or use a reachable host address.
# The interactive wizard detects the source and Python on its own host.
# Four GPUs is a layout example; confirm model memory requirements with Doctor.
6 changes: 3 additions & 3 deletions examples/options/service-sandbox.answers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ training:
reference: /srv/models/qwen-reference
args_file: qwen3-8B
gateway:
tokenizer_digest: REPLACE_WITH_ACTUAL_TOKENIZER_SHA256
template_digest: REPLACE_WITH_ACTUAL_TEMPLATE_SHA256
tokenizer_digest: null # Calculated automatically with the GPU Python over SSH.
template_digest: null
deployment:
layout: colocate
num_gpus: 1
num_gpus: 4
deployment:
manager:
source_dir: /srv/shared/harborrl
Expand Down
4 changes: 2 additions & 2 deletions examples/options/service-ssh.answers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ training:
reference: /srv/models/qwen-reference
args_file: qwen3-8B
gateway:
tokenizer_digest: REPLACE_WITH_ACTUAL_TOKENIZER_SHA256
template_digest: REPLACE_WITH_ACTUAL_TEMPLATE_SHA256
tokenizer_digest: null # Calculated automatically with the GPU Python over SSH.
template_digest: null
deployment:
layout: split
num_gpus: 8
Expand Down
6 changes: 5 additions & 1 deletion harborrl/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@

def main(argv=None):
argv = list(sys.argv[1:] if argv is None else argv)
if argv and argv[0] == "hello":
from harborrl.hello import main as hello_main

return hello_main(argv[1:])
if argv and argv[0] == "web":
from harborrl.webui.cli import main as web_main

Expand All @@ -32,7 +36,7 @@ def main(argv=None):
return hub_main(argv[1:])
parser = argparse.ArgumentParser(
prog="harborrl", description=__doc__, allow_abbrev=False,
epilog="Configuration tools: harborrl options --help; harborrl validate --help; harborrl init --help; harborrl web --help."
epilog="New here? harborrl hello. Configuration tools: harborrl options --help; harborrl validate --help; harborrl init --help; harborrl web --help."
)
parser.add_argument("-model", help="Slime model preset to select")
parser.add_argument("-harness", help="agent harness to select")
Expand Down
Loading
Loading