AdmiralTaco Claude Opus 4.8 commited on
Commit
bd56f62
·
1 Parent(s): 6b7cda8

Fix gpt-oss empty turns: reasoning_effort=low via chat-template kwarg

Browse files

At the harmony default (medium) effort, gpt-oss-20b spent the whole 512-token
budget in its analysis channel and never emitted assistantfinal, so the
normalizer dropped the output and Oona sat every turn out (trace health gate
measured 10/10 empty; she appeared in 1/10 attract frames). A plain
"Reasoning: low" line in the system message does nothing (the template routes
system content to the developer block), so the knob is passed server-side as
a chat-template kwarg, baked via TTW_REASONING_EFFORT into the engine image
(deployed; TypeError fallback for older vLLM). Live-verified: Oona returns
clean JSON with 4 valid offers; republished traces show 0/10 empty for
OpenAI (all four labs healthy). README deploy line updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Files changed (2) hide show
  1. README.md +1 -1
  2. serve_council.py +23 -1
README.md CHANGED
@@ -112,7 +112,7 @@ pip install -r requirements.txt
112
  # No GPU, dummy agents (for trying the UI):
113
  TTW_DUMMY=1 python app.py
114
  # The multi-model council on Modal (deploy each engine, then enable the council):
115
- TTW_APP_NAME=ttw-serve-gptoss TTW_MODEL=openai/gpt-oss-20b TTW_CUDA_DEVEL=1 python -m modal deploy serve_council.py
116
  TTW_APP_NAME=ttw-serve-minicpm TTW_MODEL=openbmb/MiniCPM3-4B TTW_CUDA_DEVEL=1 TTW_TRUST_REMOTE=1 python -m modal deploy serve_council.py
117
  TTW_APP_NAME=ttw-serve-nemotron TTW_MODEL=nvidia/Nemotron-Mini-4B-Instruct TTW_CUDA_DEVEL=1 python -m modal deploy serve_council.py
118
  TTW_APP_NAME=ttw-serve-qwen TTW_MODEL=AdmiralTaco/ttw-trader-0.5b TTW_CUDA_DEVEL=1 python -m modal deploy serve_council.py
 
112
  # No GPU, dummy agents (for trying the UI):
113
  TTW_DUMMY=1 python app.py
114
  # The multi-model council on Modal (deploy each engine, then enable the council):
115
+ TTW_APP_NAME=ttw-serve-gptoss TTW_MODEL=openai/gpt-oss-20b TTW_CUDA_DEVEL=1 TTW_REASONING_EFFORT=low python -m modal deploy serve_council.py
116
  TTW_APP_NAME=ttw-serve-minicpm TTW_MODEL=openbmb/MiniCPM3-4B TTW_CUDA_DEVEL=1 TTW_TRUST_REMOTE=1 python -m modal deploy serve_council.py
117
  TTW_APP_NAME=ttw-serve-nemotron TTW_MODEL=nvidia/Nemotron-Mini-4B-Instruct TTW_CUDA_DEVEL=1 python -m modal deploy serve_council.py
118
  TTW_APP_NAME=ttw-serve-qwen TTW_MODEL=AdmiralTaco/ttw-trader-0.5b TTW_CUDA_DEVEL=1 python -m modal deploy serve_council.py
serve_council.py CHANGED
@@ -39,6 +39,15 @@ CUDA_DEVEL = os.environ.get("TTW_CUDA_DEVEL", "0") == "1"
39
  CUDA_TAG = os.environ.get("TTW_CUDA_TAG", "12.4.1-devel-ubuntu22.04")
40
  # Some models ship custom modeling code (MiniCPM3); vLLM needs explicit opt-in.
41
  TRUST_REMOTE = os.environ.get("TTW_TRUST_REMOTE", "0") == "1"
 
 
 
 
 
 
 
 
 
42
 
43
  app = modal.App(APP_NAME)
44
 
@@ -69,6 +78,7 @@ def build_image() -> modal.Image:
69
  "TTW_MAX_LEN": str(MAX_LEN),
70
  "TTW_DTYPE": DTYPE,
71
  "TTW_TRUST_REMOTE": "1" if TRUST_REMOTE else "0",
 
72
  }
73
  )
74
  )
@@ -113,7 +123,19 @@ class Engine:
113
  params = self.SamplingParams(
114
  temperature=temperature, top_p=0.9, max_tokens=max_tokens
115
  )
116
- outputs = self.llm.chat(conversations, params)
 
 
 
 
 
 
 
 
 
 
 
 
117
  return [o.outputs[0].text for o in outputs]
118
 
119
 
 
39
  CUDA_TAG = os.environ.get("TTW_CUDA_TAG", "12.4.1-devel-ubuntu22.04")
40
  # Some models ship custom modeling code (MiniCPM3); vLLM needs explicit opt-in.
41
  TRUST_REMOTE = os.environ.get("TTW_TRUST_REMOTE", "0") == "1"
42
+ # Chat-template reasoning effort (gpt-oss harmony: low/medium/high; empty = leave
43
+ # the template default). At the default (medium) gpt-oss-20b spends the whole
44
+ # per-turn budget in its analysis channel and never emits `assistantfinal`, so
45
+ # the council's harmony normalizer drops the output and Oona sits every turn out
46
+ # (measured: 10/10 empty turns). Deploy the gptoss engine with
47
+ # TTW_REASONING_EFFORT=low to reach the final answer inside the budget. A plain
48
+ # "Reasoning: low" line in the system message does NOT work: the template routes
49
+ # system content to the developer block; the knob must be a template kwarg.
50
+ REASONING_EFFORT = os.environ.get("TTW_REASONING_EFFORT", "")
51
 
52
  app = modal.App(APP_NAME)
53
 
 
78
  "TTW_MAX_LEN": str(MAX_LEN),
79
  "TTW_DTYPE": DTYPE,
80
  "TTW_TRUST_REMOTE": "1" if TRUST_REMOTE else "0",
81
+ "TTW_REASONING_EFFORT": REASONING_EFFORT,
82
  }
83
  )
84
  )
 
123
  params = self.SamplingParams(
124
  temperature=temperature, top_p=0.9, max_tokens=max_tokens
125
  )
126
+ effort = os.environ.get("TTW_REASONING_EFFORT", "")
127
+ if effort:
128
+ try:
129
+ outputs = self.llm.chat(
130
+ conversations, params,
131
+ chat_template_kwargs={"reasoning_effort": effort},
132
+ )
133
+ except TypeError:
134
+ # Older vLLM without chat_template_kwargs: serve without the
135
+ # knob rather than fail the whole engine.
136
+ outputs = self.llm.chat(conversations, params)
137
+ else:
138
+ outputs = self.llm.chat(conversations, params)
139
  return [o.outputs[0].text for o in outputs]
140
 
141