# Using Numo-1-E2B
[Overview](README.md) · [Tasks](#choose-a-task) · [Output](#read-the-result)
For literature organization, evidence screening and research-assistant workflows,
see [why Numo](WHY_NUMO.md). Named tasks return defined answers; your workflow
retains responsibility for human review and domain validation.
## Setup
The model folder contains all inference weights and the tokenizer.
It does not need a separate Gemma download, private Numo code or PEFT for inference.
Table as text
| Tested software | Version |
| --- | --- |
| Python | 3.12 |
| PyTorch | 2.14.0 |
| Transformers | 5.17.0 |
In a Linux Python environment, install the versions in
[requirements.txt](requirements.txt). Choose the appropriate PyTorch CUDA
wheel for your hardware. The tested GPU is an **RTX 3060 with 12 GB VRAM**, on a 64 GB RAM host.
Other versions and hardware have not been verified against this release.
A minimum system-RAM configuration has not been measured.
**Prerequisite: a C compiler and Python development headers.** On the first
GPU decision, PyTorch 2.14 compiles a small Triton helper, and that needs
`gcc` and `Python.h`. Without them, loading works but the first prediction
fails with `fatal error: Python.h: No such file or directory`. Either install
them (Ubuntu: `sudo apt install build-essential python3-dev`) or create your
environment from a Python build that ships its headers, such as one installed
by `uv` or conda.
Allow CPU memory for the full 9.27 GB of inference tensors and loading overhead.
During GPU inference, a large lookup table stays on CPU; that table alone uses
about 4.7 GB. Load the model on CPU first, then call `prepare_for_inference("cuda")`.
The standalone reload used 4.31 GiB peak PyTorch CUDA allocation for nine synthetic
requests; this is not total-device VRAM or a maximum-length guarantee.
See the [README example](README.md#quickstart).
From the model folder:
```sh
python example.py
python example.py --device cpu
```
The second command uses CPU placement. Full-model CPU speed has not been measured.
Automatic device maps, FP16, quantization, arbitrary batching and alternative
attention backends are not validated release settings.
## Choose a task
Call `model.predict(tokenizer, task=..., text=...)`. The model supplies the
declared question and answer choices for that task.
Table as text
| Task ID | Answers | Recommended text |
| --- | --- | --- |
| `scientific_field` | 2–8 selected broad arXiv fields | Title and abstract |
| `research_area` | Medicine, biology, physics, computing or another area | Title and abstract |
| `study_approach` | Six declared study approaches | Title and abstract |
| `biomedical_relevance` | Irrelevant, partially relevant or relevant | Seed and candidate paper |
| `support_boolean` | False or true: evidence fully supports the hypothesis | Evidence and hypothesis |
| `support_grade3` | None, partial or full support | Evidence and hypothesis |
| `consensus4` | Four coded vote-consensus bands | Evidence and hypothesis |
| `consensus5` | Five coded vote-consensus bands | Evidence and hypothesis |
Use these text formats:
```python
paper = "Title: ...\nAbstract: ..."
evidence = "Evidence:\n...\nHypothesis:\n..."
pair = "Seed paper:\n
\n\nCandidate paper:\n\n"
result = model.predict(tokenizer, task="research_area", text=paper)
```
The exact descriptions, IDs and meanings are in
[task-contracts.json](task-contracts.json) and `model.config.task_contracts`.
For `scientific_field`, pass `candidate_ids=[...]` to choose or reorder a
declared subset. Other calibrated tasks require their fixed answer order.
## Read the result
Table as text
| Field | Meaning |
| --- | --- |
| `answer` | Description of the selected answer |
| `answer_id` | Stable answer ID for a named task |
| `semantic_answer` | Its declared meaning, such as a Boolean value |
| `probabilities_by_id` | Probability scores keyed by answer ID |
| `calibrated` | Whether the exact request matches a calibrated task |
| `review_required` | Always true: a person or your workflow decides what to accept |
| `complete_input_tokens` | Length of the full rendered request |
| `backbone_calls` | One model pass per decision |
Probability scores are adjusted using the release's existing calibration.
They are not a guarantee of correctness. See [evaluation](EVALUATION.md).
## Input rules
The full request must fit **1,024 tokens**, including instructions and choices.
Text, question and choices must be nonempty. There must be 2–8 distinct choices.
Oversized input and reserved control tokens are rejected without truncation.
Boolean answers use false/true order; ordinal levels use ascending order.
## Custom questions
For a question outside the named tasks, supply a typed request:
```python
result = model.predict(tokenizer, request={
"text": "A synthetic example describes two proposed methods.",
"question": "Which method is described?",
"choices": ["Method A", "Method B"],
"kind": "choice"
})
```
For a yes/no question use `"kind": "noul"`; for ordered levels use `"kind": "score"`.
Custom requests outside the exact declared definitions return **uncalibrated**
research output. Similar wording alone does not make a request calibrated.
More synthetic requests are in [examples.json](examples.json).