Text Generation
Transformers
Safetensors
English
qwen2
chat
conversational
text-generation-inference
4-bit precision
awq
Instructions to use Papajams/ratiocine with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Papajams/ratiocine with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="Papajams/ratiocine") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("Papajams/ratiocine") model = AutoModelForCausalLM.from_pretrained("Papajams/ratiocine", 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=40) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use Papajams/ratiocine with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Papajams/ratiocine" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Papajams/ratiocine", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/Papajams/ratiocine
- SGLang
How to use Papajams/ratiocine 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 "Papajams/ratiocine" \ --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": "Papajams/ratiocine", "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 "Papajams/ratiocine" \ --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": "Papajams/ratiocine", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use Papajams/ratiocine with Docker Model Runner:
docker model run hf.co/Papajams/ratiocine
feat: hybrid CoT (translation/fill_blanks) + direct (others)
Browse files
script.py
CHANGED
|
@@ -8,15 +8,21 @@ The eval sandbox:
|
|
| 8 |
- has 30 minutes
|
| 9 |
- has bitsandbytes and autoawq pre-installed
|
| 10 |
|
| 11 |
-
Strategy: Ship Qwen2.5-14B-Instruct-AWQ with
|
| 12 |
The 14B-AWQ is the proven competition baseline (0.123 score). We improve
|
| 13 |
on the baseline with:
|
| 14 |
-
1. Task-specific
|
| 15 |
-
2.
|
| 16 |
-
3.
|
| 17 |
-
4.
|
| 18 |
-
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
"""
|
| 21 |
|
| 22 |
import json
|
|
@@ -69,10 +75,10 @@ def solve_problem(
|
|
| 69 |
task_type: str = "",
|
| 70 |
max_new_tokens: int = 256,
|
| 71 |
) -> tuple[list[str], str]:
|
| 72 |
-
"""Generate answers for one IOL problem
|
| 73 |
|
| 74 |
-
|
| 75 |
-
|
| 76 |
"""
|
| 77 |
n_items = count_query_items(query)
|
| 78 |
system_prompt = get_system_prompt(task_type)
|
|
@@ -108,6 +114,16 @@ def solve_problem(
|
|
| 108 |
return answers, explanation
|
| 109 |
|
| 110 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
def main():
|
| 112 |
t_start = time.time()
|
| 113 |
|
|
@@ -119,31 +135,60 @@ def main():
|
|
| 119 |
n_problems = len(df)
|
| 120 |
print(f"[submit] Loaded {n_problems} problems", flush=True)
|
| 121 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
rows = []
|
| 123 |
for idx, row in df.iterrows():
|
| 124 |
-
# Time guard
|
| 125 |
elapsed = time.time() - t_start
|
| 126 |
remaining = TIME_BUDGET_S - elapsed
|
| 127 |
problems_left = n_problems - idx
|
|
|
|
| 128 |
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
|
|
|
|
|
|
| 132 |
if idx % 10 == 0:
|
| 133 |
print(f"[submit] FAST MODE at {idx+1}/{n_problems} "
|
| 134 |
f"({remaining:.0f}s left)", flush=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
else:
|
|
|
|
| 136 |
current_max = 256
|
|
|
|
| 137 |
|
| 138 |
try:
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 147 |
except Exception as e:
|
| 148 |
print(f"[submit] ERROR at {idx+1}/{n_problems}: {e}", flush=True)
|
| 149 |
n_items = count_query_items(row.get("query", ""))
|
|
@@ -152,13 +197,13 @@ def main():
|
|
| 152 |
|
| 153 |
rows.append({
|
| 154 |
"id": row["id"],
|
| 155 |
-
"pred":
|
| 156 |
"explanation": explanation,
|
| 157 |
})
|
| 158 |
|
| 159 |
if (idx + 1) % 10 == 0 or idx == 0:
|
| 160 |
print(f"[submit] {idx + 1}/{n_problems} done "
|
| 161 |
-
f"({elapsed:.0f}s elapsed)", flush=True)
|
| 162 |
|
| 163 |
output = pd.DataFrame(rows)
|
| 164 |
# Write to the path the eval system expects
|
|
|
|
| 8 |
- has 30 minutes
|
| 9 |
- has bitsandbytes and autoawq pre-installed
|
| 10 |
|
| 11 |
+
Strategy: Ship Qwen2.5-14B-Instruct-AWQ with HYBRID prompting.
|
| 12 |
The 14B-AWQ is the proven competition baseline (0.123 score). We improve
|
| 13 |
on the baseline with:
|
| 14 |
+
1. Task-specific CoT prompts for translation/fill_blanks (improves EM)
|
| 15 |
+
2. Direct prompts for match_letters/text_to_num/num_to_text (faster)
|
| 16 |
+
3. Adaptive max_new_tokens per task type (512 for CoT, 256 for direct)
|
| 17 |
+
4. Fixed answer parser (v1 dropped ~5% of correct answers)
|
| 18 |
+
5. Explanation column for human jury track
|
| 19 |
+
6. Time guard to never exceed 30-min limit
|
| 20 |
+
|
| 21 |
+
Why hybrid: Pure CoT was too slow (70s/problem) and exceeded the time
|
| 22 |
+
budget. Pure direct prompting gave EM=0.025 on the hidden test set.
|
| 23 |
+
CoT for hard tasks (translation, fill_blanks) improves exact matches by
|
| 24 |
+
letting the model reason carefully; direct prompting is fine for
|
| 25 |
+
pattern-matching tasks where reasoning doesn't help.
|
| 26 |
"""
|
| 27 |
|
| 28 |
import json
|
|
|
|
| 75 |
task_type: str = "",
|
| 76 |
max_new_tokens: int = 256,
|
| 77 |
) -> tuple[list[str], str]:
|
| 78 |
+
"""Generate answers for one IOL problem.
|
| 79 |
|
| 80 |
+
For translation/fill_blanks: CoT reasoning (max 512 tokens).
|
| 81 |
+
For match_letters/text_to_num/num_to_text: direct (256 tokens).
|
| 82 |
"""
|
| 83 |
n_items = count_query_items(query)
|
| 84 |
system_prompt = get_system_prompt(task_type)
|
|
|
|
| 114 |
return answers, explanation
|
| 115 |
|
| 116 |
|
| 117 |
+
def _format_pred(answers: list[str]) -> str:
|
| 118 |
+
"""Format predictions for submission.
|
| 119 |
+
|
| 120 |
+
Output is JSON-encoded list of answer strings (the IOL competition
|
| 121 |
+
evaluator parses this with ast.literal_eval). We also include a
|
| 122 |
+
pipe-separated fallback in a comment-like column for safety.
|
| 123 |
+
"""
|
| 124 |
+
return json.dumps(answers, ensure_ascii=False)
|
| 125 |
+
|
| 126 |
+
|
| 127 |
def main():
|
| 128 |
t_start = time.time()
|
| 129 |
|
|
|
|
| 135 |
n_problems = len(df)
|
| 136 |
print(f"[submit] Loaded {n_problems} problems", flush=True)
|
| 137 |
|
| 138 |
+
# Estimate time per problem type for adaptive budget
|
| 139 |
+
# CoT tasks: ~30s each (512 tokens); direct tasks: ~5s each (256 tokens)
|
| 140 |
+
COT_TASKS = {"translation", "fill_blanks"}
|
| 141 |
+
DIRECT_TASKS = {"match_letters", "text_to_num", "num_to_text"}
|
| 142 |
+
|
| 143 |
rows = []
|
| 144 |
for idx, row in df.iterrows():
|
|
|
|
| 145 |
elapsed = time.time() - t_start
|
| 146 |
remaining = TIME_BUDGET_S - elapsed
|
| 147 |
problems_left = n_problems - idx
|
| 148 |
+
task_type = row.get("task_type", "")
|
| 149 |
|
| 150 |
+
# Adaptive max_new_tokens based on time remaining and task type
|
| 151 |
+
if remaining < problems_left * 2 and remaining > 0:
|
| 152 |
+
# Very low on time — minimal tokens, direct mode
|
| 153 |
+
current_max = 96
|
| 154 |
+
use_cot = False
|
| 155 |
if idx % 10 == 0:
|
| 156 |
print(f"[submit] FAST MODE at {idx+1}/{n_problems} "
|
| 157 |
f"({remaining:.0f}s left)", flush=True)
|
| 158 |
+
elif task_type in COT_TASKS:
|
| 159 |
+
# Use CoT for hard tasks (improves EM via careful reasoning)
|
| 160 |
+
current_max = 512
|
| 161 |
+
use_cot = True
|
| 162 |
else:
|
| 163 |
+
# Direct for easy tasks (fast pattern matching)
|
| 164 |
current_max = 256
|
| 165 |
+
use_cot = False
|
| 166 |
|
| 167 |
try:
|
| 168 |
+
# If we need to force direct mode for time, swap to default prompt
|
| 169 |
+
if not use_cot and task_type in COT_TASKS and remaining < problems_left * 8:
|
| 170 |
+
# Switch to default prompt (direct) for time-constrained CoT tasks
|
| 171 |
+
from prompts import _DEFAULT_PROMPT
|
| 172 |
+
original_prompt = get_system_prompt(task_type)
|
| 173 |
+
# Use default prompt via monkey-patch
|
| 174 |
+
import prompts
|
| 175 |
+
prompts._PROMPTS[task_type] = _DEFAULT_PROMPT
|
| 176 |
+
answers, explanation = solve_problem(
|
| 177 |
+
tokenizer, model,
|
| 178 |
+
context=row["context"],
|
| 179 |
+
query=row["query"],
|
| 180 |
+
task_type=task_type,
|
| 181 |
+
max_new_tokens=current_max,
|
| 182 |
+
)
|
| 183 |
+
prompts._PROMPTS[task_type] = original_prompt
|
| 184 |
+
else:
|
| 185 |
+
answers, explanation = solve_problem(
|
| 186 |
+
tokenizer, model,
|
| 187 |
+
context=row["context"],
|
| 188 |
+
query=row["query"],
|
| 189 |
+
task_type=task_type,
|
| 190 |
+
max_new_tokens=current_max,
|
| 191 |
+
)
|
| 192 |
except Exception as e:
|
| 193 |
print(f"[submit] ERROR at {idx+1}/{n_problems}: {e}", flush=True)
|
| 194 |
n_items = count_query_items(row.get("query", ""))
|
|
|
|
| 197 |
|
| 198 |
rows.append({
|
| 199 |
"id": row["id"],
|
| 200 |
+
"pred": _format_pred(answers),
|
| 201 |
"explanation": explanation,
|
| 202 |
})
|
| 203 |
|
| 204 |
if (idx + 1) % 10 == 0 or idx == 0:
|
| 205 |
print(f"[submit] {idx + 1}/{n_problems} done "
|
| 206 |
+
f"({elapsed:.0f}s elapsed, task={task_type})", flush=True)
|
| 207 |
|
| 208 |
output = pd.DataFrame(rows)
|
| 209 |
# Write to the path the eval system expects
|