Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
72e4671
feat(agentic): program-aware admission and session KV lifecycle for a…
yuanlehome Aug 12, 2026
4d31c27
feat(docker): add Ascend/NPU multi-stage image build with Makefile en…
Michael-Salon Aug 14, 2026
134cf1d
fix: report total steps for qs-inject
Yangruipis Aug 14, 2026
633064c
feat(mtp-training): add MTP-only SFT mode
Yangruipis Aug 17, 2026
cbd77a1
feat(ce): add qwen3 9B ce and fix spec_accept_rate
li126com Aug 17, 2026
cf181ca
feat(scripts): add qwen35-4B 4xGPU colocate PPO CE script
NINGBENZHE Aug 13, 2026
c482b4b
fix(sglang): add Body() annotation to post_process_weights route for …
GUOGUOPOT Aug 17, 2026
e282a3e
feat(LoRA): Support LoRA RL MoE
GUOGUOPOT Aug 18, 2026
285cc0f
refactor(s3): use standard AWS transport
RexFlux Aug 18, 2026
5f5a2f8
feat(sglang): gate draft weights backup and eager NCCL init
NINGBENZHE Aug 15, 2026
d361a0a
feat(sft): support sequence classification
Yangruipis Aug 18, 2026
deae85d
feat(multiagent): introduce multiagent training
dirtyDan0 Aug 19, 2026
728b99f
feat(search_qa): add Search-R1 agentic OPD environment
fxsc03 Aug 19, 2026
e424f44
feat(sft): support Qwen3.8 chat template and training
NINGBENZHE Aug 19, 2026
683f01a
feat(m2po): add M2PO advantage estimator
Aug 20, 2026
cb9ef70
feat(sft): add LoRA dynamic CP launch
xiaoliang0601 Aug 14, 2026
1627f89
perf(megatron): fuse log-prob and entropy
yuanlehome Aug 20, 2026
ea4ae51
fix(save-hf): relax export strictness for structurally absent weights
Michael-Salon Aug 21, 2026
e95e4a4
fix(cp): align SFT masks with predictor offsets
Yangruipis Aug 20, 2026
55bcbcb
fix(agentic): allow whitespace message content
dirtyDan0 Aug 20, 2026
b23c7e1
fix(sglang): keep MM zero-copy on single-node TP
yuanlehome Aug 24, 2026
fad3c96
fix(agentic): defer protection to resume
dirtyDan0 Aug 24, 2026
811f3e2
fix(sft): skip loss-mask alignment for seq-cls
Yangruipis Aug 24, 2026
2b853c5
feat(rollout): scale-out weight-sync NCCL precheck
RexFlux Aug 25, 2026
111eb8e
fix(sglang): backport qwen3.5 mrope fix for multimodal requests
fxsc03 Aug 25, 2026
ff6a9d0
fix(model-source): support URI reference aliases
RexFlux Aug 26, 2026
1a07706
docs(elastic-rollout): add autoscaler recipe
RexFlux Aug 27, 2026
faf86cc
test(model-source): decouple provider fixtures
RexFlux Aug 28, 2026
ee66e08
feat(skills): add opd-tuning skill
yuanlehome Aug 28, 2026
1ab15dd
test(sync): update scale-out env stubs
NINGBENZHE Aug 28, 2026
cf09c3e
fix model provider
li126com Aug 28, 2026
1472cdf
fix(agentic): canonicalize tool arguments
dirtyDan0 Aug 26, 2026
33348da
feat(agentic): report defer and degraded admission rates
DrRyanHuang Aug 28, 2026
c8ae7fc
feat(mini-swe-agent): make agentic scheduling configurable
DrRyanHuang Aug 28, 2026
3e2ed70
fix(sync): preserve replay conflict resolutions
NINGBENZHE Aug 28, 2026
3fd0850
test(ci): guard optional backend imports
NINGBENZHE Aug 31, 2026
32212ff
ci(tests): provide class-shaped queue stubs
NINGBENZHE Aug 31, 2026
cde7c77
test(core): isolate controller affinity import
NINGBENZHE Aug 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ jobs:
os.makedirs(sp, exist_ok=True)
with open(os.path.join(sp, 'transfer_queue.py'), 'w') as f:
f.write('# CI stub for transfer_queue (internal package)\n')
f.write('class StreamingTokenBudgetSampler:\n')
f.write(' def __init__(self, *a, **k): self._states = {}\n')
f.write('class SeqlenBalancedSampler(StreamingTokenBudgetSampler): pass\n')
f.write('class _Stub:\n')
f.write(' def __getattr__(self, name): return self\n')
f.write(' def __call__(self, *a, **k): return self\n')
Expand Down
121 changes: 121 additions & 0 deletions .opencode/agents/agentic-expert.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
description: Agentic rollout expert. Fire when assessing or integrating an agent app
(harness), reviewing relax/agentic runtime changes, reasoning about SessionForest
context and export, or diagnosing prelaunch, partial rollout, protected Sessions,
external capacity, and Agentic cleanup.
mode: subagent
temperature: 0.1
tools:
write: false
edit: false
---

# Agentic Rollout Expert

You are the read-only domain expert for Relax resident Agentic rollout. Trace contracts across the agent app, Chat
Completions ingress, SessionForest, Group and Session ownership, SGLang requests, export, reward, and transfer. Base every
conclusion on the current checkout and exact runtime path.

## When to Activate

Use this expert for:

- assessing whether an existing agent app (harness) can connect through `--use-agentic-rollout`;
- reviewing code under `relax/agentic/**`;
- auditing exact `messages`, `tools`, `chat_template_kwargs`, parser behavior, and context topology;
- choosing implicit versus explicit export and checking multi-context requirements;
- reasoning about Prepare, first-request barriers, Runtime lease, result publication, and cleanup;
- prelaunch, partial rollout, pending/active protection, fully async retention, and timeout ownership;
- external agent slot calculations and conditionally triggered internal-scale checks;
- diagnosing Agentic hangs before routing an established Ray failure to `ray-expert`.

## Scope Boundaries

- Use `ray-expert` for Ray Core, Serve scheduling, placement, actor failure, object refs, and cluster operations after the
problem is shown to belong to Ray.
- Use `algorithm-expert` for reward algorithms, advantage normalization, policy loss, RM internals, and passrate math.
- Use `launcher-expert` for top-level service deployment and GPU/resource orchestration.
- Use `megatron-expert` or `fsdp-expert` for training-backend internals.
- Remain read-only. Do not edit code, launch jobs, or mutate external state.

## Required Method

1. Inspect the current branch, HEAD, worktree diff, and relevant source before using prior conclusions.
2. Trace the concrete ownership path:

```text
dataset Group -> Prepare -> Session process -> Chat request -> backend
-> Session cleanup/result -> Group release -> Reward -> Transfer
```

3. Keep these dimensions separate:

- logical prompt Group;
- Relax Session and agent process;
- Chat/backend request;
- SessionForest context;
- exported physical training row.

4. Treat `messages + tools + chat_template_kwargs` as the model-visible state identity. Inspect actual request payloads,
not internal agent message classes.
5. Distinguish the Relax-facing client wall-clock timeout from the agent process active-time `--agent-timeout`.
6. Resolve train and per-dataset Eval Group sizes before calculating external slots or resident scale.
7. State whether each conclusion is source-confirmed, inferred from a blocking path, or still unverified at runtime.

Read `skills/agentic-rollout/SKILL.md` and only the references activated by the current task. Current source overrides the
skill when they disagree.

## Core Contracts

- A Group is assigned wholly to one SessionShard and leases only after every original Session reaches its first request.
- The process started by Relax is the Session entry point. The agent may run locally or elsewhere, while requests must
reach `RELAX_BASE_URL` and the entry process exits when the task finishes.
- Intentional nonlinear histories are supported. Implicit export is reserved for audited linear history; nonlinear
training contexts require exact explicit export.
- Multiple exports from one Session share a logical identity and require the multi-context credit and batching contract.
- Protected Sessions bypass later partial aborts while their active process timeout continues; step close waits for
protected Groups to finalize.
- A progress bar at 100% proves target finalized Sessions, not complete resident cleanup.

## Failure Routing

Start with the first blocked owner:

```text
agent input/client -> first-request barrier -> Session gate -> admission/permit
-> SGLang request -> process/finalization cleanup -> Reward -> Transfer
```

Route outward only after evidence identifies another domain. Examples:

- actor mailbox, Serve replica, placement, or Ray task state -> `ray-expert`;
- custom advantage, Group RM, normalization, or loss weighting -> `algorithm-expert`;
- cluster launch, service deployment, or GPU allocation -> `launcher-expert`.

## Review Output

Return:

```text
Current checkout:
Agentic verdict: PASS | NEEDS_CHANGES | UNSAFE | UNVERIFIED
Owning layer:
Confirmed mechanism:
User-visible impact:
Required change or evidence:
Cross-domain route:
Validation limits:
```

Keep user-facing conclusions first. Introduce internal Shard or RPC details only when they are implicated by the target
scale or failure.

## Key Sources

- `relax/agentic/rollout.py`
- `relax/agentic/pipeline/`
- `relax/agentic/session/service.py`
- `relax/agentic/session/state.py`
- `relax/agentic/runner/ipc.py`
- `relax/utils/arguments.py`
- `docs/en/guide/agentic-rollout.md`
4 changes: 3 additions & 1 deletion .opencode/agents/ray-expert.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ Use this agent when:
- Working with Ray cluster lifecycle (`ray start`, `ray stop`, `ray status`)
- Debugging actor/task state via `ray list actors`, `ray list tasks`

**Not for**: Megatron internals (use `megatron-expert`), FSDP internals (use `fsdp-expert`), RL algorithm logic (use `algorithm-expert`), or high-level orchestration design (use `launcher-expert`).
**Not for**: Agentic rollout semantics (use `agentic-expert`), Megatron internals (use `megatron-expert`), FSDP
internals (use `fsdp-expert`), RL algorithm logic (use `algorithm-expert`), or high-level orchestration design (use
`launcher-expert`). Use this expert when an Agentic investigation has identified an underlying Ray mechanism.

## Ray in Relax: Overview

Expand Down
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ Fire the appropriate **expert subagent** or **load a skill** based on what you'r
| Task Launch & service deployment | `launcher-expert` | |
| Ray framework (Core, Serve, Jobs, placement) | `ray-expert` | |
| Development & code changes | `ray-expert` | `dev` |
| Agentic rollout integration, runtime & hangs | `agentic-expert` | `agentic-rollout` |
| Distributed training hang debugging | `ray-expert` | `debug-hang` |
| Code review of git changes | -- | `code-review` |
| Creating new skills | -- | `creating-skills` |
Expand Down
66 changes: 64 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
.PHONY: help install test lint format clean docs docs-dev docs-build docs-preview check-registry check-train-image docker-train docker-dev
.PHONY: help install test lint format clean docs docs-dev docs-build docs-preview check-registry check-train-image check-ascend-qs-base-image check-qs-dockerfile docker-train docker-dev docker-ascend docker-qs-ascend

DOCKER ?= docker
DOCKERFILE ?= docker/Dockerfile
ASCEND_DOCKERFILE ?= docker/Dockerfile.npu
SOC_VERSION ?= ascend910_9391
ASCEND_DOCKER_BUILDKIT ?= 1
DOCKER_BUILD_PROGRESS ?= plain
DOCKER_BUILD_ARGS ?=
DO_PUSH ?= 1
Expand All @@ -13,7 +16,19 @@ IMAGE_REGISTRY := $(patsubst %/,%,$(strip $(REGISTRY)))
DEFAULT_TRAIN_IMAGE := $(IMAGE_REGISTRY)/$(IMAGE_REPOSITORY):train-$(BUILD_DATE)-$(GIT_SHORT_HASH)
DEV_IMAGE := $(IMAGE_REGISTRY)/$(IMAGE_REPOSITORY):dev-$(BUILD_DATE)-$(GIT_SHORT_HASH)

ifeq ($(origin TRAIN_IMAGE),undefined)
# Ascend/NPU images share the same repository as GPU; the ascend- tag prefix keeps
# aarch64 artifacts from ever overwriting the amd64 train-/dev- tags.
ASCEND_DEV_IMAGE := $(IMAGE_REGISTRY)/$(IMAGE_REPOSITORY):ascend-dev-$(BUILD_DATE)-$(GIT_SHORT_HASH)
ASCEND_QS_IMAGE := $(IMAGE_REGISTRY)/$(IMAGE_REPOSITORY):ascend-qs-$(BUILD_DATE)-$(GIT_SHORT_HASH)

# QS wrapping reuses the external relax-ci Dockerfile.qs (verified pure-python /
# arch-independent, so ARM64-safe). CI is responsible for checking out relax-ci and
# pointing ASCEND_QS_DOCKERFILE at its docker/Dockerfile.qs; the Relax repo embeds neither
# the external repo nor its credentials. ASCEND_QS_BASE_IMAGE defaults to the dev image.
ASCEND_QS_DOCKERFILE ?=
ASCEND_QS_BASE_IMAGE ?= $(ASCEND_DEV_IMAGE)

ifeq ($(strip $(TRAIN_IMAGE)),)
TRAIN_IMAGE := $(DEFAULT_TRAIN_IMAGE)
BUILD_DEFAULT_TRAIN := 1
else
Expand All @@ -40,6 +55,10 @@ help:
@echo " REGISTRY=... make docker-train - Build and push the Docker train stage"
@echo " REGISTRY=... make docker-dev - Build and push the Docker development image"
@echo " REGISTRY=... TRAIN_IMAGE=... make docker-dev - Build dev from an existing train image"
@echo " REGISTRY=... make docker-ascend - Build and push the complete Ascend/NPU image"
@echo " REGISTRY=... ASCEND_QS_DOCKERFILE=... make docker-qs-ascend - Wrap an Ascend dev image into a QS image (optional)"
@echo " Ascend targets accept BASE_IMAGE=... and SOC_VERSION=... (default ascend910_9391)"
@echo " Ascend targets use BuildKit by default; set ASCEND_DOCKER_BUILDKIT=0 for legacy DinD"
@echo " Set DO_PUSH=0 before make to skip pushing Docker images"
@echo " Existing remote images are skipped; DO_PUSH=0 checks local images"

Expand Down Expand Up @@ -84,6 +103,13 @@ check-registry:
check-train-image:
@test -n "$(strip $(TRAIN_IMAGE))" || { echo "TRAIN_IMAGE must not be empty" >&2; exit 2; }

check-ascend-qs-base-image:
@test -n "$(strip $(ASCEND_QS_BASE_IMAGE))" || { echo "ASCEND_QS_BASE_IMAGE must not be empty" >&2; exit 2; }

check-qs-dockerfile:
@test -n "$(strip $(ASCEND_QS_DOCKERFILE))" || { echo "ASCEND_QS_DOCKERFILE is required (path to relax-ci docker/Dockerfile.qs)" >&2; exit 2; }
@test -f "$(strip $(ASCEND_QS_DOCKERFILE))" || { echo "ASCEND_QS_DOCKERFILE not found: $(ASCEND_QS_DOCKERFILE)" >&2; exit 2; }

docker-train: check-registry
@echo "[docker] output train image: $(TRAIN_IMAGE)"
@set -e; \
Expand Down Expand Up @@ -118,3 +144,39 @@ docker-dev: check-registry check-train-image
.; \
if [ "$(DO_PUSH)" != "0" ]; then $(DOCKER) push "$(DEV_IMAGE)"; fi; \
fi

docker-ascend: check-registry
@echo "[docker] output ascend image: $(ASCEND_DEV_IMAGE)"
@set -e; \
if $(IMAGE_INSPECT) "$(ASCEND_DEV_IMAGE)" >/dev/null 2>&1; then \
echo "[docker] skip existing $(IMAGE_LOCATION) ascend image: $(ASCEND_DEV_IMAGE)"; \
else \
DOCKER_BUILDKIT=$(ASCEND_DOCKER_BUILDKIT) $(DOCKER) build --progress=$(DOCKER_BUILD_PROGRESS) \
-f $(ASCEND_DOCKERFILE) \
--target relax \
-t "$(ASCEND_DEV_IMAGE)" \
--build-arg SOC_VERSION="$(SOC_VERSION)" \
$(PROXY_BUILD_ARGS) $(BASE_IMAGE_BUILD_ARG) $(DOCKER_BUILD_ARGS) \
.; \
if [ "$(DO_PUSH)" != "0" ]; then $(DOCKER) push "$(ASCEND_DEV_IMAGE)"; fi; \
fi

# Optional: wrap an Ascend dev image into an internal QS image using relax-ci's
# Dockerfile.qs. ASCEND_QS_DOCKERFILE must point at a relax-ci checkout; ASCEND_QS_BASE_IMAGE
# defaults to the dev image built above but can be any existing Ascend dev image.
docker-qs-ascend: check-registry check-qs-dockerfile check-ascend-qs-base-image
@echo "[docker] input ascend dev image: $(ASCEND_QS_BASE_IMAGE)"
@echo "[docker] output ascend qs image: $(ASCEND_QS_IMAGE)"
@set -e; \
if $(IMAGE_INSPECT) "$(ASCEND_QS_IMAGE)" >/dev/null 2>&1; then \
echo "[docker] skip existing $(IMAGE_LOCATION) ascend qs image: $(ASCEND_QS_IMAGE)"; \
else \
DOCKER_BUILDKIT=$(ASCEND_DOCKER_BUILDKIT) $(DOCKER) build --progress=$(DOCKER_BUILD_PROGRESS) \
--no-cache \
-f "$(ASCEND_QS_DOCKERFILE)" \
-t "$(ASCEND_QS_IMAGE)" \
--build-arg BASE_IMAGE="$(ASCEND_QS_BASE_IMAGE)" \
$(PROXY_BUILD_ARGS) $(DOCKER_BUILD_ARGS) \
"$(dir $(ASCEND_QS_DOCKERFILE))"; \
if [ "$(DO_PUSH)" != "0" ]; then $(DOCKER) push "$(ASCEND_QS_IMAGE)"; fi; \
fi
Loading
Loading