RULER produces scores >1, arbitrary outputs (7, 10, 15…), nondeterministic behavior, and malformed JSON when judge model is Qwen3-32B running on Ollama
维护者通常 1 天内回复
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 25/100
- Issue 类型
- 缺陷
- 描述清晰度
- 基本清楚
- 活跃度
- 停滞
- 技术栈
- ollama, python
调研方向
先从 ruler() 和 ruler_score_group() 开始,然后检查 issue 中描述的 acompletion 调用、response_format=Response 和 Response.model_validate_json(content) 路径。使用提供的环境详细信息,通过 Ollama 和 Qwen3-32B 重现格式错误和超出范围的响应。该 issue 没有定义一种被接受的修复方案;maintainers 必须先决定验证、解析、可配置性或文档是否属于范围。
由索引模型根据 Issue 内容生成。
描述
What happened?
I’m running ART’s RULER scoring step using a local Ollama server (on a machine with 2× H100 80GB) hosting:
- Qwen3-32B (tried both quantized + full FP16, which uses ~66GB VRAM)
- Serving as the LLM judge inside
ruler()/ruler_score_group()
However, RULER often produces invalid or nonsensical outputs, specifically:
1. RULER returns scores >1 (e.g., 7, 10, 15)
Even though the schema requires:
score: float # between 0 and 1
I frequently get outputs like:
score: 7score: 10score: 15- or other arbitrary integers / floats
Sometimes the score is actually "10" (string), "1.", "0.8x", etc.
This violates the API contract and breaks training.
2. RULER gives hallucinated/meaningless scores per trajectory
Even when trajectories look similar or follow the system instructions, the judge:
- Randomly assigns very high or very low scores
- Ignores the rubric
- Produces wildly different outputs across runs (no determinism)
- Sometimes gives no comparison at all, just arbitrary values
3. JSON returned by judge is malformed or incomplete
Very often, the content inside:
first_choice.message.content
is:
- Partial JSON
- Badly formatted JSON
- JSON containing stray characters
- Missing required fields (
trajectory_id,explanation, etc.) - A mixture of plaintext + JSON fragments
- Sometimes entirely non-JSON despite RULER passing a Pydantic
response_format
This triggers failures like:
pydantic_core._pydantic_core.ValidationError: JSON parsing error
or:
json.decoder.JSONDecodeError
I even had to introduce a fallback parser because well-formed JSON simply does not arrive reliably.
4. RULER’s behavior is nondeterministic even with same prompt + same trajectories
Across repeated runs:
- Same trajectories produce different scores
- Sometimes >1, sometimes valid (0.3), sometimes JSON errors
- Even with FP16 full-precision version of Qwen3-32B (66GB VRAM) and temperature = 0
This strongly suggests the judge model is not following the system prompt reliably.
Why I believe this is an ART / RULER robustness issue
Looking at the code inside ruler():
response = await acompletion(
model=judge_model,
messages=messages,
response_format=Response,
caching=False,
)
...
content = first_choice.message.content or "{}"
parsed = Response.model_validate_json(content)
RULER assumes:
- The backend model supports strict JSON mode
- The returned content is fully compliant with the Pydantic schema
- The judge will obey the system prompt, including scoring between 0 and 1
But these assumptions do not always hold for:
- Ollama models
- Qwen3-32B, which does not have deterministic structured output
- Non-OpenAI providers through LiteLLM
Ollama cannot guarantee strict JSON output, and model behavior varies even at temperature 0.
As a result:
- RULER collapses when JSON isn’t perfect
- Scoring becomes arbitrary / hallucinated
- Training reward curves become meaningless
This matches exactly the issues I’m seeing.
What I expected to happen
- If
response_format=Responseis provided, the judge should reliably produce JSON - Scores should always be in
[0, 1] - Behavior should be deterministic (or configurable)
- RULER should gracefully handle imperfect JSON (or allow a custom parse)
- Models that cannot reliably produce JSON should not break the entire training run
Actual behavior
- Scored values frequently outside the allowed range
- JSON formatting frequently invalid
- Judge fails to follow rubric
- Behavior nondeterministic across runs
- Leads to failed training steps, invalid reward gradients, and incorrect trajectory ranking
Why this matters
RULER is advertised as:
“A general-purpose reward function for RL agents”
But in practice, with non-OpenAI models (e.g., local HPC deployment via Ollama), RULER’s strict JSON assumptions break repeatedly.
A growing number of users want:
- local inference
- open models
- offline training
- privacy and cost control
But RULER currently assumes an OpenAI-style JSON-mode model.
Suggested solutions
Here are concrete changes that would fix or improve the situation:
1. Add clamping for scores
Automatically:
score = max(0.0, min(1.0, score))
This immediately resolves the “score > 1” crashes.
2. Add a robust JSON extraction / correction layer
e.g.:
- extract the first valid JSON block
- filter out stray characters
- fallback to regex extraction
3. Allow a user-defined parse_response() hook
For example:
async def ruler(..., parse_response: Callable[[ModelResponse], Response] = None)
4. Add a validation step in RULER that warns when the judge cannot follow JSON-mode
Instead of crashing training.
5. Recommend judges known to produce reliable JSON
Or explicitly warn that models like Qwen3-32B (via Ollama) may not be JSON-mode safe.
Environment
- 2× NVIDIA H100 80GB
- Ollama server hosting Qwen3-32B (both quantized + full FP16 variants)
- LiteLLM router
- ART latest version (2025)
- RULER used via
ruler_score_group() - Temperature = 0
I can also provide logs + trajectories if needed.
But the core issue is that RULER's strict JSON-mode expectations do not hold for many models, leading to:
- hallucinated scores
- invalid reward signals
- malformed JSON
- nondeterministic judge behavior
- 主要语言
- Python
- 星标
- 10.8k
- 派生
- 1k
- 平均合并
- 16 小时 14 分钟
- 30 天内合并 PR
- 148
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
OpenPipe/ART 的其他 Issue
-
Distributed group_mean casts group ids to float32, losing precision vs non-distributed path可能已有人在做 @OnePunchMonk 于 11 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 1 天内回复
-
Add from_entity parameter to _experimental_fork_checkpoint可能重新可做 关联的 PR 已关闭且未合并。 未关闭
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 15/100
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 15/100
维护者通常 1 天内回复
-
Nonfused column LoRA misses input-gradient SUM when TP>1 and sequence parallelism is disabled可能已有人在做 @bradhilton 于 12 天前认领。 未关闭
难度 5/5 一周以上 新手友好度 25/100
维护者通常 1 天内回复
相似的 Issue
-
Workflow.schedule stops when a cron deadline passes before sleep可能已有人在做 @HuaTNA 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 1 天内回复
-
[Bug] HiveDialect shares its colspecs dict with SQLAlchemy's DefaultDialect (python/pyhive)可能已有人在做 @rusackas 今天认领。 未关闭
难度 1/5 1 小时以内 新手友好度 80/100
维护者通常 2 天内回复
-
难度 2/5 1-3 小时 新手友好度 80/100
维护者通常 1 天内回复
-
[20.0] hr_work_entry: Duration column of Export Time Entries is truncated to whole hours可能已有人在做 @odooaktiv 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
fix formatting of the sample database page of the docs可能已有人在做 @Aaqibhafeezkhan 今天认领。 未关闭documentation good first issue help wanted
难度 1/5 1 小时以内 新手友好度 72/100
chaoss/CollectOSS#544 · 1 条评论 ·
维护者通常 1 天内回复