About OpenMed
OpenMed builds open models and open-source tools for clinical and biomedical text that run on your own hardware.
Results
Same model architecture, tokenizer, chat template and sampling for every row; only weight values differ. One sample per
question with seed 0 (MedQA also with seeds 1 and 2). Thinking on, temperature 0.6, top_p 0.95, top_k 20, presence
penalty 1.5, at most 32,768 new tokens (the paper's evaluation protocol). The prompt is OpenMed's fixed MedQA exam prompt
(below), and an answer is graded from the text after </think>: its last Answer: X line, X in A to D. Answers cut at the
token limit and answers with no gradable line count as wrong, as in the paper.
Table with columns: Checkpoint, MedQA (seed 0), MedQA, median of 3 seeds (range), MedMCQA, MMLU medical, MedQA answers cut at 32,768 tokens, MedQA answers with no gradable line| Checkpoint | MedQA (seed 0) | MedQA, median of 3 seeds (range) | MedMCQA | MMLU medical | MedQA answers cut at 32,768 tokens | MedQA answers with no gradable line |
|---|
| OpenMed WSP Clinical 0.8B (this model) | 39.0% | 38.6% (37.0% to 39.0%) | 39.9% | 55.4% | 19.6% | 0.0% |
| Random patch, same size, random direction (seed 1) | 25.7% | n/a | 28.3% | 45.4% | 19.2% | 31.7% |
| Random patch, same size, random direction (seed 2) | 23.8% | n/a | 30.5% | 45.7% | 18.2% | 33.7% |
| Qwen3.5-0.8B as released | 24.4% | 23.1% (22.1% to 24.4%) | 30.6% | 43.4% | 18.3% | 32.9% |
Paired tests on the same questions (seed 0; exact McNemar on the questions only one checkpoint got right; bootstrap 95%
CI over questions, 10,000 resamples):
Table with columns: Comparison, Benchmark, n, Before, After, Difference (95% CI), Only before right / only after right, McNemar p| Comparison | Benchmark | n | Before | After | Difference (95% CI) | Only before right / only after right | McNemar p |
|---|
| Qwen3.5-0.8B -> WSP Clinical 0.8B | MedQA-USMLE (4 options) | 1,273 | 24.4% | 39.0% | +14.6 pts (+11.6 to +17.5) | 105 / 291 | 2.6e-21 |
| Qwen3.5-0.8B -> WSP Clinical 0.8B | MedMCQA | 1,000 | 30.6% | 39.9% | +9.3 pts (+6.2 to +12.4) | 87 / 180 | 1.3e-08 |
| Qwen3.5-0.8B -> WSP Clinical 0.8B | MMLU | 1,089 | 43.4% | 55.4% | +11.9 pts (+8.9 to +15.0) | 88 / 218 | 6.9e-14 |
| random patch 1 -> WSP Clinical 0.8B | MedQA-USMLE (4 options) | 1,273 | 25.7% | 39.0% | +13.3 pts (+10.5 to +16.3) | 106 / 276 | 1.4e-18 |
| random patch 1 -> WSP Clinical 0.8B | MedMCQA | 1,000 | 28.3% | 39.9% | +11.6 pts (+8.5 to +14.7) | 75 / 191 | 7.7e-13 |
| random patch 1 -> WSP Clinical 0.8B | MMLU | 1,089 | 45.4% | 55.4% | +10.0 pts (+7.0 to +13.1) | 100 / 209 | 5.4e-10 |
| random patch 2 -> WSP Clinical 0.8B | MedQA-USMLE (4 options) | 1,273 | 23.8% | 39.0% | +15.2 pts (+12.3 to +18.1) | 88 / 282 | 8.3e-25 |
| random patch 2 -> WSP Clinical 0.8B | MedMCQA | 1,000 | 30.5% | 39.9% | +9.4 pts (+6.0 to +12.8) | 106 / 200 | 8.4e-08 |
| random patch 2 -> WSP Clinical 0.8B | MMLU | 1,089 | 45.7% | 55.4% | +9.6 pts (+6.5 to +12.7) | 96 / 201 | 1.1e-09 |
Also accepting Answer: <B>, Answer: (b), Answer: <letter>B and \boxed{B} after </think>. The gap between this
and the main score shows how much of a checkpoint's score is lost to the format of its final line rather than to the
choice itself.
Table with columns: Checkpoint, MedQA, MedMCQA, MMLU medical| Checkpoint | MedQA | MedMCQA | MMLU medical |
|---|
| OpenMed WSP Clinical 0.8B (this model) | 39.0% | 39.9% | 55.4% |
| Random patch, same size, random direction (seed 1) | 33.8% | 32.7% | 51.9% |
| Random patch, same size, random direction (seed 2) | 31.6% | 34.5% | 52.2% |
| Qwen3.5-0.8B as released | 32.5% | 34.8% | 50.0% |
Nothing else broke (general benchmarks, one sample, seed 0)
Table with columns: Checkpoint, MATH-500, MATH-500 cut at 32,768 tokens, IFEval (strict, prompt level)| Checkpoint | MATH-500 | MATH-500 cut at 32,768 tokens | IFEval (strict, prompt level) |
|---|
| OpenMed WSP Clinical 0.8B (this model) | 7.0% | 93.8% | 23.1% |
| Qwen3.5-0.8B as released | 7.4% | 93.6% | 20.2% |
What the edit does
OpenMed's fixed exam prompt ends with "finish with one last line exactly like: Answer: ". Under the evaluation's sampling, Qwen3.5-0.8B often copies the placeholder instead of filling it in and ends with Answer: <B> or Answer: <letter>, which no grader reads as a letter. The editor traced the copy to the attention output projection of the last layer (layer 23, all eight heads): at the final Answer: they attend to the prompt's < and write the direction that raises the logit of <. The presence penalty makes it worse, because the four letters have usually appeared in the thinking already while < has not.
The edit removes that one direction from the layer's attention output: W <- W - u u^T W, with u the output direction of the token ' <' made orthogonal to the letters A to D. We checked it independently: the main output direction of every edited tensor's change lines up with the output direction of < (eval/direction_check.json).
Table with columns: Tensor, Shape, bfloat16 entries changed, Relative change, sha256 (edited, bfloat16 bytes)| Tensor | Shape | bfloat16 entries changed | Relative change | sha256 (edited, bfloat16 bytes) |
|---|
model.language_model.layers.23.self_attn.o_proj.weight | 1024 x 2048 | 1,735,071 | 0.0436 | a9de31b14f982be3b075fc0228dca940e7e2b8b7b3963a1ee67534dab9c7de15 |
1,735,071 bfloat16 entries differ from the starting checkpoint (Qwen/Qwen3.5-0.8B @ 2fc06364). edit/manifest.json and
edit/edit.npz hold the edit as an exact diff (indices and bfloat16 bits), with the sha256 of every tensor before and
after; rebuilding the tensors from the diff reproduces these hashes.
Quick start
from vllm import LLM, SamplingParamsfrom transformers import AutoTokenizer def main(): repo = "OpenMed/Qwen3.5-0.8B-WSP-Clinical" tok = AutoTokenizer.from_pretrained(repo) llm = LLM(model=repo, dtype="bfloat16", max_model_len=34816, language_model_only=True, generation_config="vllm") # a MedQA-USMLE practice question (train split, id medqa_train_4541; the key is B) question = ("A 23-year-old male with a homozygous CCR5 mutation is found to be immune to HIV infection. " "The patient's CCR5 mutation interferes with the function of which viral protein?") options = {"A": "Reverse transcriptase", "B": "gp120", "C": "gp41", "D": "pp17"} user = ("Which option is the best answer to this clinical question?\n\n" + question + "\n\n" + "\n".join(f"{k}. {v}" for k, v in options.items()) + "\n\nReason as much as you need, then finish with one last line exactly like: Answer: <letter>") prompt = tok.apply_chat_template([{"role": "user", "content": user}], tokenize=False, add_generation_prompt=True, enable_thinking=True) sp = SamplingParams(temperature=0.6, top_p=0.95, top_k=20, presence_penalty=1.5, max_tokens=32768, seed=0) text = llm.generate([prompt], sp)[0].outputs[0].text print(text.split("</think>")[-1].strip()) if __name__ == "__main__": # vLLM starts worker processes main()
How it was made
- The harness. We rebuilt the paper's setup, whose prompts and rules are published but whose code is not: a persistent CPU Python kernel over the weights (no GPU, no internet, no gradients;
save_edit refuses the final norm, the embeddings and whole-tensor rescaling) and a forward-pass tool (generations with the evaluation's sampling, paired original vs edited with fixed seeds, and teacher-forced reads of hidden states, MLP activations and attention). The task text is the paper's, with the target changed from math to clinical questions.
- The editor. Claude Opus 5.5 (reasoning effort high) had a budget of 12 forward passes, 40 Python runs and $4 of API. It could use only training-split practice questions; the MedQA, MedMCQA and MMLU test sets in the tables were never shown to it. It diagnosed the failures, localized them, tested strengths and confirmed its edit on fresh practice questions before submitting.
- Evaluation and control. Every checkpoint ran with the same vLLM 0.33.0 server and settings on one GPU. The random-patch control changes the same rows and columns of the same tensors by the same amount (the same singular values) in random directions; two seeds.
Files
- The weights, config, tokenizer and chat template: Qwen3.5-0.8B's release files with the edited tensors (every
other tensor is unchanged).
edit/: the clinical edit as an exact, hash-checked diff from the starting checkpoint.
eval/: per-question results of every checkpoint on every benchmark (id, finish reason, tokens, extracted answer,
grade) with no question text, the scores, the first 20 generated texts per benchmark for this model, and
receipt.json (editor, API cost, passes, wall time).
Limitations
- Small model, one sample per question (MedQA with three seeds). The gains are relative to the same model and sampling and say nothing about clinical safety.
- Most of the gain is the model now writing a letter where it used to copy the prompt's
<letter> placeholder; the format-agnostic table shows how much is format and how much is the choice itself.
- The fixed prompt literally says
Answer: <letter>; with a prompt that shows no placeholder the edit has less to fix.
- The edit lowers the probability of
< everywhere layer 23 writes, not only in the answer line.
- It does not fix the thinking loops: about a fifth of MedQA answers still hit the 32,768-token limit (OpenMed/Qwen3.5-0.8B-WSP-Math-Clinical also carries the paper's anti-loop edit).
- Research only. Not for clinical use, diagnosis or treatment.
Credits
- Method: "Sparks of Weight-Space Programming: LLMs can natively read & write neural network weights" by Rikiya Takehi, Jayden Teoh, Alex Zhang and Omar Khattab (MIT CSAIL, 2 Nov 2026), https://rikiyat.github.io/blog/weight-space-programming/; logs and diffs at https://github.com/RikiyaT/lm_understand-logs. OpenMed rebuilt their harness from the published prompts and rules and pointed it at clinical questions.
- Base model: Qwen/Qwen3.5-0.8B by the Qwen team, Apache-2.0.
- Editor: Claude Opus 5.5 by Anthropic.
- Data: MedQA-USMLE (GBaker/MedQA-USMLE-4-options, CC-BY-4.0), MedMCQA (openlifescienceai/medmcqa, Apache-2.0), MMLU (cais/mmlu, MIT), MATH-500 (HuggingFaceH4/MATH-500), IFEval (google/IFEval, Apache-2.0).
- Hugging Face's ML Intern reproduction of the paper's math edit showed the method reproduces; ML Intern did not take part in this model.
Citation
@misc{takehi2026weightspace, title = {Sparks of Weight-Space Programming: LLMs can natively read \& write neural network weights}, author = {Rikiya Takehi and Jayden Teoh and Alex Zhang and Omar Khattab}, year = {2026}, month = {nov}, url = {https://rikiyat.github.io/blog/weight-space-programming/}}