Text Generation
Transformers
Safetensors
qwen3_5
biology
crispr
genomics
active-learning
reinforcement-learning
assayloop
assaybench
conversational
Instructions to use Genentech/assayllm-handoff-grpo with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Genentech/assayllm-handoff-grpo with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="Genentech/assayllm-handoff-grpo") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoProcessor, AutoModelForCausalLM processor = AutoProcessor.from_pretrained("Genentech/assayllm-handoff-grpo") model = AutoModelForCausalLM.from_pretrained("Genentech/assayllm-handoff-grpo", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use Genentech/assayllm-handoff-grpo with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Genentech/assayllm-handoff-grpo" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Genentech/assayllm-handoff-grpo", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/Genentech/assayllm-handoff-grpo
- SGLang
How to use Genentech/assayllm-handoff-grpo with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "Genentech/assayllm-handoff-grpo" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Genentech/assayllm-handoff-grpo", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "Genentech/assayllm-handoff-grpo" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Genentech/assayllm-handoff-grpo", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use Genentech/assayllm-handoff-grpo with Docker Model Runner:
docker model run hf.co/Genentech/assayllm-handoff-grpo
Update README.md
Browse files
README.md
CHANGED
|
@@ -99,77 +99,23 @@ table above.
|
|
| 99 |
|
| 100 |
## Loading
|
| 101 |
|
| 102 |
-
The weights are stored under the multimodal key layout Qwen3.6-27B inherits from its
|
| 103 |
-
vision-capable base: the language model lives under `model.language_model.*` and the unused
|
| 104 |
-
vision tower under `model.visual.*`, 1,199 tensors in all. `config.json` declares
|
| 105 |
-
`architectures: ["Qwen3_5ForCausalLM"]`, as the base model does. Both load paths work, and
|
| 106 |
-
they give you different things:
|
| 107 |
-
|
| 108 |
```python
|
| 109 |
# text-only -- what you want. Builds 851 tensors, skips the vision tower.
|
| 110 |
from transformers import AutoModelForCausalLM
|
| 111 |
model = AutoModelForCausalLM.from_pretrained(REPO, dtype="bfloat16", device_map="auto")
|
| 112 |
-
|
| 113 |
-
# full multimodal graph, vision tower included. Builds 1,184 tensors.
|
| 114 |
-
from transformers import AutoModelForImageTextToText
|
| 115 |
-
model = AutoModelForImageTextToText.from_pretrained(REPO, dtype="bfloat16", device_map="auto")
|
| 116 |
```
|
| 117 |
|
| 118 |
-
`AutoModelForCausalLM` names its tensors `model.layers.*`, not
|
| 119 |
-
`model.language_model.layers.*`; transformers reconciles the two on load, so the trained
|
| 120 |
-
weights do arrive despite the apparent name mismatch. Nothing here uses the vision tower, so
|
| 121 |
-
the first form is the one to use.
|
| 122 |
-
|
| 123 |
-
The 15 tensors neither class builds are the base model's multi-token-prediction head, which
|
| 124 |
-
vLLM uses for speculative decoding; they are ignored on load.
|
| 125 |
-
|
| 126 |
## Results
|
| 127 |
|
| 128 |
-
Results are evaluated on AssayBench-Loop
|
| 129 |
-
and the full-genome candidate pool. EF is hits found divided by hits a uniform-random policy
|
| 130 |
-
would find, so 1.0 is chance. Rows naming two models are pipelines, and their metrics belong
|
| 131 |
-
to the complete pipeline rather than this checkpoint alone.
|
| 132 |
|
| 133 |
| Method | EF | nAUC | FH | SF |
|
| 134 |
|---|---|---|---|---|
|
| 135 |
| AssayLLM alone (SFT + GRPO) | 3.70 | 0.156 | 0.193 | 0.173 |
|
| 136 |
| AssayFormer alone (BPMF + GRPO) | 4.83 | 0.172 | 0.232 | 0.100 |
|
| 137 |
-
| AssayLLM → AssayFormer, handoff
|
| 138 |
-
| **
|
| 139 |
-
|
| 140 |
-
Joint training improves on combining two separately trained components because the opener
|
| 141 |
-
is optimized against the objective used to score the complete pipeline.
|
| 142 |
-
|
| 143 |
-
## Training
|
| 144 |
-
|
| 145 |
-
The model was SFT-trained on GLM-5.1 rollouts, then GRPO-trained with reward computed on the
|
| 146 |
-
full ten-round campaign. This model writes only the first two rounds; AssayFormer
|
| 147 |
-
(`gf-bpmf-train-hits-rl`) plays out the remaining eight during training. The LLM is therefore
|
| 148 |
-
credited for openings that set the ranker up well rather than only for its own two-round hit
|
| 149 |
-
count.
|
| 150 |
-
|
| 151 |
-
The prompt is built by `LLMSingleAcquisition` in
|
| 152 |
-
[`src/assayloop/acquisitions/llm_single_acq.py`](https://github.com/Genentech/AssayLoop/blob/main/src/assayloop/acquisitions/llm_single_acq.py):
|
| 153 |
-
an AssayBench screen-description block, a running table of what has already been assayed and
|
| 154 |
-
which observations were hits, and an instruction to return exactly 100 symbols, strongest
|
| 155 |
-
first and comma-separated.
|
| 156 |
-
|
| 157 |
-
## Notes
|
| 158 |
-
|
| 159 |
-
- **Bookkeeping.** The harness assays the first 100 genes of each response that are in the
|
| 160 |
-
screen's library and not already acquired, and drops the rest. SF is the share of all
|
| 161 |
-
picks that fell outside the library: it counts those dropped names, not repeats.
|
| 162 |
-
- **Files.** 12 safetensors shards of ~5 GB, 55.6 GB total, bf16. The handover export put
|
| 163 |
-
49.8 GB of that in a single file; it was re-sharded for upload, and every tensor was hashed
|
| 164 |
-
before and after to confirm the weights are unchanged.
|
| 165 |
-
- **Architecture.** `config.json` reports `model_type: qwen3_5`. That is the transformers
|
| 166 |
-
implementation Qwen3.6-27B uses; it is not a different base model.
|
| 167 |
-
- **Used alone it is not the best opener.** It was trained to be handed off from at round
|
| 168 |
-
three, and is credited for openings that set the ranker up well rather than for its own
|
| 169 |
-
two-round hit count. The standalone `SFT + GRPO` policy the paper calls AssayLLM is a
|
| 170 |
-
separate checkpoint that was not preserved and is not published; if you want a
|
| 171 |
-
general-purpose LLM policy from this work, start from `Genentech/assayllm-sft`.
|
| 172 |
-
- **Not a general assistant.** Fine-tuned on one task in one output format.
|
| 173 |
|
| 174 |
## Citation
|
| 175 |
|
|
|
|
| 99 |
|
| 100 |
## Loading
|
| 101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
```python
|
| 103 |
# text-only -- what you want. Builds 851 tensors, skips the vision tower.
|
| 104 |
from transformers import AutoModelForCausalLM
|
| 105 |
model = AutoModelForCausalLM.from_pretrained(REPO, dtype="bfloat16", device_map="auto")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
```
|
| 107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
## Results
|
| 109 |
|
| 110 |
+
Results are evaluated on AssayBench-Loop.
|
|
|
|
|
|
|
|
|
|
| 111 |
|
| 112 |
| Method | EF | nAUC | FH | SF |
|
| 113 |
|---|---|---|---|---|
|
| 114 |
| AssayLLM alone (SFT + GRPO) | 3.70 | 0.156 | 0.193 | 0.173 |
|
| 115 |
| AssayFormer alone (BPMF + GRPO) | 4.83 | 0.172 | 0.232 | 0.100 |
|
| 116 |
+
| AssayLLM → AssayFormer, handoff | 5.05 | 0.186 | 0.247 | 0.077 |
|
| 117 |
+
| **Handoff-trained AssayLLM →AssayFormer** | **5.23** | **0.187** | **0.251** | **0.091** |
|
| 118 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
|
| 120 |
## Citation
|
| 121 |
|