Clbench Fireworks Rft
БесплатноНе проверенEnables reinforcement fine-tuning of Qwen3-8B on the CLBench poker task using the eval-protocol MCP-Gym framework on Fireworks infrastructure, with structured t
Описание
Enables reinforcement fine-tuning of Qwen3-8B on the CLBench poker task using the eval-protocol MCP-Gym framework on Fireworks infrastructure, with structured tool calls via MCP.
README
Training memory use into a small open model (Qwen3-1.7B) with Fireworks Reinforcement Fine-Tuning
(GRPO, via eval-protocol), on a task derived from CLBench's
blind_spectrum_monitoring.
The question: can RL make a model better at using memory — recalling information from early in a
multi-step task to do better later — rather than baking task skill into the weights? We measure it as
memory_gain = late-half − early-half performance, and require it to rise under training while the
scenario is randomized per rollout (so there is nothing to memorize in the weights).
Status: COMPLETE — see RESULTS_memory.md for the final, controlled result (2026-07-03). Headline: GRPO reproducibly improves the 1.7B's memory recall (carry-rate 0.89 → 0.94 in two independent runs) on never-repeating content (knowledge-baking impossible by construction) with a scrambled-memory control flat (skill drift excluded) — while one paragraph of explicit instruction still installs a stronger policy than 12 epochs of RL reach, and agent-managed notepad memory erodes under prolonged RL. Sections below describe the task and infra; historical results (pre fresh-band rigor) are marked as such.
The task
Each rollout is a series of 12 scans of ONE fixed but unknown band of ~11–14 transmitters. Each scan shows only the ~3 currently-active transmitters' noisy peaks; the rest are dormant (invisible that scan). The agent reports the persistent occupied regions. A memoryless agent (reports only the current peaks) covers ~3/12 of the band; an agent that accumulates across scans covers more — so coverage rising late-vs-early is memory.
- Reward = per-scan occupied-spectrum IoU (
spectrum_reward.py), scored in the env vs the hidden ground truth. Memoryless ≈ 0.16, full-memory → ~1.0 — a 4× signal that requires recalling dormant transmitters. (The bench's native available-IoU is a dead end: memoryless already ≈ 0.47, so it barely rewards memory.) - Proof metric =
memory_gain= late-half occ − early-half occ, tracked but never rewarded (rewarding it invites sandbagging — tanking early scans to inflate the delta).
Final results — RESULTS_memory.md (the definitive account)
The controlled experiment (fresh bands every epoch via epoch-salting, so no band is ever seen twice; scrambled-memory control arm; behavioral carry-rate instrumentation):
| arm | prompt | memory echo | outcome |
|---|---|---|---|
A fva3tx6z |
explicit | real | occ 0.472 flat — behavior saturated by instruction (carry 0.967, above the naive-oracle 0.447) |
B geote9qj |
explicit | scrambled | flat (occ 0.356, 12 epochs) — zero non-memory skill drift |
C dtbn6lhm |
weak | real | rises: occ 0.403→0.439 (R²=0.65), carry 0.888→0.938 |
C′ c4jk2e4z |
weak | real | replicates the mechanism: occ slope same sign, carry 0.900→0.935 |
Findings: (1) RL trains memory recall — replicated behaviorally, knowledge excluded by construction, skill controlled at zero; (2) the reward correctly ranks memory use within GRPO groups (corr ≈ +0.8), so reward shape was never the bottleneck; (3) instruction ≫ RL at this scale — the explicit prompt installs a stronger policy (0.472) than RL reaches from a weak base in 12 epochs (0.42–0.44); (4) RL preserves env-maintained memory but erodes agent-managed (notepad-tool) memory over long training — the channel-cost dependence result.
Historical note: earlier positive readings (btalo63n, dmzj2mz8, behavioral tables in
RUNS_spectrum.md) predate the fresh-band rigor — they reused the same 48 bands across all epochs and are
confounded by content repetition; keep them as history, cite RESULTS_memory.md as the result.
The GRPO fix that made anything train (the hard-won one)
GRPO normalizes advantages within a prompt's candidate group — those candidates must face the same
task. The env originally drew a fresh random band per rollout, so a row's 12 candidates each got a
different band → advantage was band-luck, not policy → zero gradient, frozen policy at any learning
rate (six flat runs). Fix: seed the band deterministically from the per-row session_id, so a row's
candidates share one band while different rows give different bands. This single change turned flat runs
into training. (See _band_seed in spectrum_mcp.py / spectrum_turn_processor.py.)
Why the setup diverges from CLBench (deliberate)
Four choices exist specifically to isolate and reward memory:
- Reward = occupied-IoU, not the bench's available-IoU (memory-insensitive).
- ICL-off windowing (
spectrum_context_window.py) — the model sees only[system] + [current scan], so its only cross-scan memory is the notepad/scaffold, not re-read history. - Forced dormancy (
n_active=3of ~12) — most transmitters dormant each scan, so memory is required. memory_gain(late−early) as the proof metric.
Two rollout interfaces (both cloud-runnable, no hosting)
- McpGym (
test_spectrum_rft.py+spectrum_mcp.py) — the proven path. Scans arrive as tool results (agent callssubmit_report, gets the next scan back). - Custom
SpectrumTurnRolloutProcessor(test_spectrum_turn.py+spectrum_turn_processor.py) — bench-shaped. Scans arrive asusermessages, the agent replies withassistanttool calls,submit_reportacks. Confirmed running in-cloud: the cloud runs whateverrollout_processorthe uploaded@evaluation_testnames, via pytest — no MCP server, no hosted endpoint.
The message-role of the scan (tool vs user) is the only difference between the two; it doesn't change what
the model learns. The custom processor exists to match CLBench's user/assistant turn structure.
Repo layout
Current (spectrum) working set:
| file | role |
|---|---|
spectrum_adapter.py |
env: per-row deterministic band, scan advance, occ-IoU scoring, notepad state, windowing marker |
spectrum_mcp.py |
McpGym server + tools: notepad_read, notepad_write, submit_report |
spectrum_server.py |
MCP server launcher (subprocess for the McpGym rollout) |
spectrum_reward.py |
occ-IoU reward + memory_gain / mean_occ / … metrics (parses per-scan SCAN_OCC) |
spectrum_context_window.py |
ICL-off windowing (monkeypatches the policy to window model input to the current scan) |
spectrum_turn_processor.py |
custom RolloutProcessor — bench-shaped user/assistant rollout, notepad tools inline |
test_spectrum_rft.py |
evaluator entry (McpGym path) |
test_spectrum_turn.py |
evaluator entry (custom-processor path) |
make_spectrum_dataset.py |
dataset generator (system prompt + N rows; the band comes from the env per-row seed) |
eval_bench90.sh · EVAL_bench90.md |
run a trained model on the official 90-instance bench schedule |
RUNS_spectrum.md |
detailed run-by-run results log |
spectrum_templates/ |
vendored CLBench Jinja templates (scan rendering) |
spectrum_np48.jsonl, spectrum24*.jsonl, spectrum48.jsonl |
datasets |
Earlier pivots (kept for reference, not the current path): poker_*.py / poker_*.jsonl (exploitable-
poker memory env — a 1.7B never learned the notepad, pivoted away) and memory_*.py (a synthetic
learn-and-recall probe). Plus utilities: plot_eval.py, compare_epochs.py, oracle_diag.py, etc.
How to run
# 1. generate a dataset (N rows; the band is drawn per-row in the env, so rows are interchangeable)
python make_spectrum_dataset.py --n 48 --out spectrum_np48.jsonl
# 2. register the dataset + upload the evaluator
firectl create dataset clbench-spectrum-np spectrum_np48.jsonl
python -m eval_protocol upload --entry test_spectrum_rft.py::test_spectrum_rft --force --yes
# (or test_spectrum_turn.py::test_spectrum_turn for the bench-shaped user/assistant interface)
# 3. launch the RFT job (Qwen3-1.7B, GRPO)
firectl create reinforcement-fine-tuning-job \
--base-model accounts/fireworks/models/qwen3-1p7b \
--dataset clbench-spectrum-np \
--evaluator accounts/<acct>/evaluators/test-spectrum-rft-test-spectrum-rft \
--output-model clbench-spectrum-np \
--epochs 10 --learning-rate 5e-5 --temperature 1.2 \
--max-output-tokens 1024 --response-candidates-count 12 \
--max-concurrent-rollouts 96
# 4. watch memory_gain / mean_occ / scans_completed per epoch (dashboard, or poll the job's outputMetrics)
# 5. (optional) evaluate a trained model on the OFFICIAL 90-instance bench schedule
./eval_bench90.sh "<litellm-model-id>" icl_notepad # see EVAL_bench90.md
Local pytest test_spectrum_rft.py needs a callable model; Qwen3 models are not serverless on the free
tier, so end-to-end validation happens in the cloud RFT run (the mechanics are unit-tested locally).
Differences from CLBench blind_spectrum_monitoring
Aligned: user/assistant turn structure (custom processor), scan generation + Jinja rendering (bench's own
task + templates), detector noise (p_miss=0.15, p_false_alarm=0.2).
| Aspect | CLBench default |
Ours | Type |
|---|---|---|---|
| Reward metric | available-IoU | occupied-IoU (+ memory_gain) |
deliberate — available-IoU is memory-insensitive |
| Context regime | full history (icl) |
ICL-off, windowed to current scan | deliberate — notepad is the only memory |
| Dormancy | n_active 2/3/4 by stage (of 13) |
fixed n_active=3 (of 11–14) |
deliberate — force memory |
| Notepad | notepad_update field (icl_notepad) |
notepad_read/notepad_write tools |
structural |
| Scenario/data | 3 curated variants, frozen corpus | random band per row, seeded from row_id |
structural — GRPO needs a comparable per-row band group |
| Episode | 90 scans, 3 stages (Wide→Mixed→Full), 5 permuted runs | 12 scans, 1 stationary band | structural |
| Band | 168 MHz, 13 ch (W=15 wide + narrow) | 180 MHz, 11–14 ch, fixed 8 MHz width | structural |
| Action | full ScanReport (center + variable bw) |
submit_report(center_freqs), fixed 8 MHz, ≤16 regions |
structural — simplified for a weak model |
| Thinking | agent's choice | OFF (/no_think) |
Qwen3-1.7B workaround (thinking blows the token budget) |
| Purpose | evaluation (held-out) | RFT training (GRPO, many epochs) | structural |
Limitations & honest caveats
- 1.7B ceiling. Agent-controlled notepad memory doesn't train at this size; the working results all rely on the environment helping maintain the memory (scaffold) or on full-context replay. A 4B+ base is the likely unlock (capacity-blocked when tried).
- Not the official bench number. We use random per-row bands + occ-IoU + ICL-off, not the frozen
90-instance corpus + available-IoU.
eval_bench90.shbridges to the official schedule — but note available-IoU under-shows memory (seeEVAL_bench90.md). - Noisy training curves (small magnitude, non-monotonic). Read the trend — early-vs-late halves, slope, cross-run reproducibility, matched control — not peak epochs.
- Capacity. RFT jobs can stall at model-serving deployment creation during Fireworks capacity crunches,
independent of the code (a known-good, unrelated job stalls identically). Diagnose with
percent/acceleratorSeconds/ a deployment check, and verify with an independent control job.
Infra learnings (gotchas worth knowing)
- Fireworks RFT runs
eval-protocol(confirmed:eval-protocol-0.3.23in the cloud streamlogs). It runs whateverrollout_processorthe uploaded@evaluation_testnames — including a custom in-process one (no MCP server, no hosting). The earlier belief that "the cloud won't drive a custom processor" was a capacity false-negative. - The in-training model lives in
config.completion_params, notrow.input_metadata— a custom processor must read it there (this is what McpGym does; reading the wrong place → 404 retry-hang). - Fireworks rejects
tool_choice→ setlitellm.drop_params = True(or don't pass it). totalInputRequestsis unreliable (stays 0 even for running jobs) — usepercent/acceleratorSeconds/ the streamlog instead.- Qwen3-1.7B thinking exhausts the token budget before the tool call (
finish_reason=length) →/no_think. RemoteRolloutProcessoralso yieldsuser/assistant, but needs a hosted HTTP server; the custom in-process processor is the hosting-free way to the same interface.
Установка Clbench Fireworks Rft
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/sr-networks/clbench-fireworks-rftFAQ
Clbench Fireworks Rft MCP бесплатный?
Да, Clbench Fireworks Rft MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Clbench Fireworks Rft?
Нет, Clbench Fireworks Rft работает без API-ключей и переменных окружения.
Clbench Fireworks Rft — hosted или self-hosted?
Доступен hosted-вариант: Unyly запускает сервер в облаке, локальная установка не обязательна.
Как установить Clbench Fireworks Rft в Claude Desktop, Claude Code или Cursor?
Открой Clbench Fireworks Rft на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
Notion
Read and write pages in your workspace
автор: NotionLinear
Issues, cycles, triage — from Claude
автор: LinearGoogle Drive
Search and read your Drive files
автор: Googlemindsdb/mindsdb
Connect and unify data across various platforms and databases with [MindsDB as a single MCP server](https://docs.mindsdb.com/mcp/overview).
автор: mindsdbCompare Clbench Fireworks Rft with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории productivity
