Text Generation
Transformers
Safetensors
English
qwen3
dna
genomics
biology
variant-effect-prediction
conversational
text-generation-inference
Instructions to use HuggingFaceBio/Carbon-X with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use HuggingFaceBio/Carbon-X with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="HuggingFaceBio/Carbon-X") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("HuggingFaceBio/Carbon-X") model = AutoModelForCausalLM.from_pretrained("HuggingFaceBio/Carbon-X", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.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(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use HuggingFaceBio/Carbon-X with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "HuggingFaceBio/Carbon-X" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "HuggingFaceBio/Carbon-X", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/HuggingFaceBio/Carbon-X
- SGLang
How to use HuggingFaceBio/Carbon-X 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 "HuggingFaceBio/Carbon-X" \ --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": "HuggingFaceBio/Carbon-X", "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 "HuggingFaceBio/Carbon-X" \ --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": "HuggingFaceBio/Carbon-X", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use HuggingFaceBio/Carbon-X with Docker Model Runner:
docker model run hf.co/HuggingFaceBio/Carbon-X
Move the agent-tool section to the end of the model card
Browse files
README.md
CHANGED
|
@@ -24,12 +24,12 @@ An open 14B language model for DNA understanding and generation, from the **Carb
|
|
| 24 |
|
| 25 |
1. [Model Summary](#model-summary)
|
| 26 |
2. [How to use](#how-to-use)
|
| 27 |
-
- [Using Carbon-X as a tool for an agent](#using-carbon-x-as-a-tool-for-an-agent)
|
| 28 |
3. [Evaluation](#evaluation)
|
| 29 |
4. [Training](#training)
|
| 30 |
5. [Limitations](#limitations)
|
| 31 |
6. [License](#license)
|
| 32 |
7. [Acknowledgements](#acknowledgements)
|
|
|
|
| 33 |
|
| 34 |
## Model Summary
|
| 35 |
|
|
@@ -132,92 +132,6 @@ The tokenizer switches between BPE for text and 6-mers for DNA. You can paste se
|
|
| 132 |
- Include any context you already have, such as the gene, strand, coordinates or annotations. Without it, the model may guess at a sequence's identity or function.
|
| 133 |
- For variant questions, give the reference and alternate sequences, or a reference sequence with the position and the base change.
|
| 134 |
|
| 135 |
-
### Using Carbon-X as a tool for an agent
|
| 136 |
-
|
| 137 |
-
A general-purpose assistant can call Carbon-X when a question involves DNA. Serve Carbon-X with vLLM as above, wrap it in a function, and give that function to any chat model that supports tool calling.
|
| 138 |
-
|
| 139 |
-
**1. Wrap Carbon-X in a function.** The function takes a question and named DNA sequences, and returns Carbon-X's answer.
|
| 140 |
-
|
| 141 |
-
```python
|
| 142 |
-
from openai import OpenAI
|
| 143 |
-
|
| 144 |
-
carbon = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
def ask_carbon(question: str, sequences: dict[str, str], context: str = "") -> str:
|
| 148 |
-
"""Ask Carbon-X a question about one or more named DNA sequences."""
|
| 149 |
-
parts = [context, question] if context else [question]
|
| 150 |
-
parts += [f"{name}: <dna>{seq}</dna>" for name, seq in sequences.items()]
|
| 151 |
-
response = carbon.chat.completions.create(
|
| 152 |
-
model="HuggingFaceBio/Carbon-X",
|
| 153 |
-
messages=[{"role": "user", "content": "\n\n".join(parts)}],
|
| 154 |
-
max_tokens=4096,
|
| 155 |
-
extra_body={"chat_template_kwargs": {"enable_thinking": False}},
|
| 156 |
-
)
|
| 157 |
-
return response.choices[0].message.content
|
| 158 |
-
```
|
| 159 |
-
|
| 160 |
-
**2. Describe it to the agent as a tool.** Let the agent refer to sequences by name, and have your code look up the DNA. Language models often miscopy long sequences, so the agent should never retype them.
|
| 161 |
-
|
| 162 |
-
```python
|
| 163 |
-
import json
|
| 164 |
-
|
| 165 |
-
sequences = {"reference.fa": "ATGGTGCATCTGACTCCTGAGGAGAAGTCTGCCGTTACTGCCCTGTGGGGCAAGG",
|
| 166 |
-
"variant.fa": "ATGGTGCATCTGACTCCTGTGGAGAAGTCTGCCGTTACTGCCCTGTGGGGCAAGG"}
|
| 167 |
-
|
| 168 |
-
carbon_tool = {
|
| 169 |
-
"type": "function",
|
| 170 |
-
"function": {
|
| 171 |
-
"name": "ask_carbon",
|
| 172 |
-
"description": (
|
| 173 |
-
"Ask Carbon-X, a DNA language model, a question about DNA sequences: variant effects, "
|
| 174 |
-
"regulatory elements, organism of origin, sequence features. Refer to sequences by name; "
|
| 175 |
-
"do not paste DNA. Its answers are model predictions, not verified facts."
|
| 176 |
-
),
|
| 177 |
-
"parameters": {
|
| 178 |
-
"type": "object",
|
| 179 |
-
"properties": {
|
| 180 |
-
"question": {"type": "string", "description": "One self-contained question."},
|
| 181 |
-
"sequences": {"type": "array", "items": {"type": "string", "enum": list(sequences)}},
|
| 182 |
-
"context": {"type": "string", "description": "Known gene, coordinates or annotations, if any."},
|
| 183 |
-
},
|
| 184 |
-
"required": ["question", "sequences"],
|
| 185 |
-
},
|
| 186 |
-
},
|
| 187 |
-
}
|
| 188 |
-
```
|
| 189 |
-
|
| 190 |
-
**3. Run the agent loop.** Any OpenAI-compatible chat model with tool calling works as the agent.
|
| 191 |
-
|
| 192 |
-
```python
|
| 193 |
-
agent = OpenAI() # the agent model's provider
|
| 194 |
-
messages = [
|
| 195 |
-
{"role": "system", "content": "For questions about DNA, consult Carbon-X with the ask_carbon tool before answering."},
|
| 196 |
-
{"role": "user", "content": "variant.fa differs from reference.fa by one base. Is the change likely benign or pathogenic?"},
|
| 197 |
-
]
|
| 198 |
-
while True:
|
| 199 |
-
reply = agent.chat.completions.create(model="<agent model>", messages=messages, tools=[carbon_tool])
|
| 200 |
-
message = reply.choices[0].message
|
| 201 |
-
messages.append(message)
|
| 202 |
-
if not message.tool_calls:
|
| 203 |
-
break
|
| 204 |
-
for call in message.tool_calls:
|
| 205 |
-
args = json.loads(call.function.arguments)
|
| 206 |
-
answer = ask_carbon(args["question"], {name: sequences[name] for name in args["sequences"]}, args.get("context", ""))
|
| 207 |
-
messages.append({"role": "tool", "tool_call_id": call.id, "content": answer})
|
| 208 |
-
print(message.content)
|
| 209 |
-
```
|
| 210 |
-
|
| 211 |
-
Coding agents such as Claude Code or Codex CLI can use the same function as a skill: a short `SKILL.md` that says when to consult Carbon-X, plus a script that calls `ask_carbon` on sequence files in the workspace.
|
| 212 |
-
|
| 213 |
-
Tips for agent use:
|
| 214 |
-
|
| 215 |
-
- **Pass DNA by reference.** Keep sequences in files or a lookup table and let the agent name them.
|
| 216 |
-
- **Ask for Carbon-X explicitly.** Agents often answer DNA questions on their own instead of calling a tool. If you want Carbon-X's view, say so in the system prompt.
|
| 217 |
-
- **Send only A, C, G and T.** Trim padding such as leading or trailing `N`s. Other characters become `<oov>` tokens.
|
| 218 |
-
- **Leave exact operations to code.** Counting, coordinates and edits are more reliable in Python than in either model. For variants, compute the position and the reference and alternate bases in code and pass them as `context`.
|
| 219 |
-
- **Cap generation length.** For next-base and continuation questions, set `max_tokens` to what you need and a client timeout, since long DNA generations are slow (see [Limitations](#limitations)).
|
| 220 |
-
|
| 221 |
## Evaluation
|
| 222 |
|
| 223 |
We evaluate Carbon-X on five benchmarks that test whether a model can use DNA knowledge to predict mutation effects, identify biological features and recover DNA bases. All results below are for the released checkpoint, with thinking disabled, the default sampling settings and one sample per problem.
|
|
@@ -333,3 +247,89 @@ Apache 2.0.
|
|
| 333 |
## Acknowledgements
|
| 334 |
|
| 335 |
Carbon is a joint collaboration between the research teams at Hugging Face, Zhongguancun Academy, and TIGEM/University of Naples “Federico II”.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
1. [Model Summary](#model-summary)
|
| 26 |
2. [How to use](#how-to-use)
|
|
|
|
| 27 |
3. [Evaluation](#evaluation)
|
| 28 |
4. [Training](#training)
|
| 29 |
5. [Limitations](#limitations)
|
| 30 |
6. [License](#license)
|
| 31 |
7. [Acknowledgements](#acknowledgements)
|
| 32 |
+
8. [Using Carbon-X as a tool for an agent](#using-carbon-x-as-a-tool-for-an-agent)
|
| 33 |
|
| 34 |
## Model Summary
|
| 35 |
|
|
|
|
| 132 |
- Include any context you already have, such as the gene, strand, coordinates or annotations. Without it, the model may guess at a sequence's identity or function.
|
| 133 |
- For variant questions, give the reference and alternate sequences, or a reference sequence with the position and the base change.
|
| 134 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
## Evaluation
|
| 136 |
|
| 137 |
We evaluate Carbon-X on five benchmarks that test whether a model can use DNA knowledge to predict mutation effects, identify biological features and recover DNA bases. All results below are for the released checkpoint, with thinking disabled, the default sampling settings and one sample per problem.
|
|
|
|
| 247 |
## Acknowledgements
|
| 248 |
|
| 249 |
Carbon is a joint collaboration between the research teams at Hugging Face, Zhongguancun Academy, and TIGEM/University of Naples “Federico II”.
|
| 250 |
+
|
| 251 |
+
## Using Carbon-X as a tool for an agent
|
| 252 |
+
|
| 253 |
+
A general-purpose assistant can call Carbon-X when a question involves DNA. Serve Carbon-X with vLLM as above, wrap it in a function, and give that function to any chat model that supports tool calling.
|
| 254 |
+
|
| 255 |
+
**1. Wrap Carbon-X in a function.** The function takes a question and named DNA sequences, and returns Carbon-X's answer.
|
| 256 |
+
|
| 257 |
+
```python
|
| 258 |
+
from openai import OpenAI
|
| 259 |
+
|
| 260 |
+
carbon = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
|
| 261 |
+
|
| 262 |
+
|
| 263 |
+
def ask_carbon(question: str, sequences: dict[str, str], context: str = "") -> str:
|
| 264 |
+
"""Ask Carbon-X a question about one or more named DNA sequences."""
|
| 265 |
+
parts = [context, question] if context else [question]
|
| 266 |
+
parts += [f"{name}: <dna>{seq}</dna>" for name, seq in sequences.items()]
|
| 267 |
+
response = carbon.chat.completions.create(
|
| 268 |
+
model="HuggingFaceBio/Carbon-X",
|
| 269 |
+
messages=[{"role": "user", "content": "\n\n".join(parts)}],
|
| 270 |
+
max_tokens=4096,
|
| 271 |
+
extra_body={"chat_template_kwargs": {"enable_thinking": False}},
|
| 272 |
+
)
|
| 273 |
+
return response.choices[0].message.content
|
| 274 |
+
```
|
| 275 |
+
|
| 276 |
+
**2. Describe it to the agent as a tool.** Let the agent refer to sequences by name, and have your code look up the DNA. Language models often miscopy long sequences, so the agent should never retype them.
|
| 277 |
+
|
| 278 |
+
```python
|
| 279 |
+
import json
|
| 280 |
+
|
| 281 |
+
sequences = {"reference.fa": "ATGGTGCATCTGACTCCTGAGGAGAAGTCTGCCGTTACTGCCCTGTGGGGCAAGG",
|
| 282 |
+
"variant.fa": "ATGGTGCATCTGACTCCTGTGGAGAAGTCTGCCGTTACTGCCCTGTGGGGCAAGG"}
|
| 283 |
+
|
| 284 |
+
carbon_tool = {
|
| 285 |
+
"type": "function",
|
| 286 |
+
"function": {
|
| 287 |
+
"name": "ask_carbon",
|
| 288 |
+
"description": (
|
| 289 |
+
"Ask Carbon-X, a DNA language model, a question about DNA sequences: variant effects, "
|
| 290 |
+
"regulatory elements, organism of origin, sequence features. Refer to sequences by name; "
|
| 291 |
+
"do not paste DNA. Its answers are model predictions, not verified facts."
|
| 292 |
+
),
|
| 293 |
+
"parameters": {
|
| 294 |
+
"type": "object",
|
| 295 |
+
"properties": {
|
| 296 |
+
"question": {"type": "string", "description": "One self-contained question."},
|
| 297 |
+
"sequences": {"type": "array", "items": {"type": "string", "enum": list(sequences)}},
|
| 298 |
+
"context": {"type": "string", "description": "Known gene, coordinates or annotations, if any."},
|
| 299 |
+
},
|
| 300 |
+
"required": ["question", "sequences"],
|
| 301 |
+
},
|
| 302 |
+
},
|
| 303 |
+
}
|
| 304 |
+
```
|
| 305 |
+
|
| 306 |
+
**3. Run the agent loop.** Any OpenAI-compatible chat model with tool calling works as the agent.
|
| 307 |
+
|
| 308 |
+
```python
|
| 309 |
+
agent = OpenAI() # the agent model's provider
|
| 310 |
+
messages = [
|
| 311 |
+
{"role": "system", "content": "For questions about DNA, consult Carbon-X with the ask_carbon tool before answering."},
|
| 312 |
+
{"role": "user", "content": "variant.fa differs from reference.fa by one base. Is the change likely benign or pathogenic?"},
|
| 313 |
+
]
|
| 314 |
+
while True:
|
| 315 |
+
reply = agent.chat.completions.create(model="<agent model>", messages=messages, tools=[carbon_tool])
|
| 316 |
+
message = reply.choices[0].message
|
| 317 |
+
messages.append(message)
|
| 318 |
+
if not message.tool_calls:
|
| 319 |
+
break
|
| 320 |
+
for call in message.tool_calls:
|
| 321 |
+
args = json.loads(call.function.arguments)
|
| 322 |
+
answer = ask_carbon(args["question"], {name: sequences[name] for name in args["sequences"]}, args.get("context", ""))
|
| 323 |
+
messages.append({"role": "tool", "tool_call_id": call.id, "content": answer})
|
| 324 |
+
print(message.content)
|
| 325 |
+
```
|
| 326 |
+
|
| 327 |
+
Coding agents such as Claude Code or Codex CLI can use the same function as a skill: a short `SKILL.md` that says when to consult Carbon-X, plus a script that calls `ask_carbon` on sequence files in the workspace.
|
| 328 |
+
|
| 329 |
+
Tips for agent use:
|
| 330 |
+
|
| 331 |
+
- **Pass DNA by reference.** Keep sequences in files or a lookup table and let the agent name them.
|
| 332 |
+
- **Ask for Carbon-X explicitly.** Agents often answer DNA questions on their own instead of calling a tool. If you want Carbon-X's view, say so in the system prompt.
|
| 333 |
+
- **Send only A, C, G and T.** Trim padding such as leading or trailing `N`s. Other characters become `<oov>` tokens.
|
| 334 |
+
- **Leave exact operations to code.** Counting, coordinates and edits are more reliable in Python than in either model. For variants, compute the position and the reference and alternate bases in code and pass them as `context`.
|
| 335 |
+
- **Cap generation length.** For next-base and continuation questions, set `max_tokens` to what you need and a client timeout, since long DNA generations are slow (see [Limitations](#limitations)).
|