Instructions to use acram/iol-qwen3-1_7b-plain with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use acram/iol-qwen3-1_7b-plain with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="acram/iol-qwen3-1_7b-plain") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("acram/iol-qwen3-1_7b-plain") model = AutoModelForCausalLM.from_pretrained("acram/iol-qwen3-1_7b-plain", 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 acram/iol-qwen3-1_7b-plain with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "acram/iol-qwen3-1_7b-plain" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "acram/iol-qwen3-1_7b-plain", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/acram/iol-qwen3-1_7b-plain
- SGLang
How to use acram/iol-qwen3-1_7b-plain 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 "acram/iol-qwen3-1_7b-plain" \ --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": "acram/iol-qwen3-1_7b-plain", "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 "acram/iol-qwen3-1_7b-plain" \ --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": "acram/iol-qwen3-1_7b-plain", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use acram/iol-qwen3-1_7b-plain with Docker Model Runner:
docker model run hf.co/acram/iol-qwen3-1_7b-plain
| import os | |
| # The evaluation sandbox has NO internet. The model's weights are shipped inside | |
| # this repo and loaded from the local folder ".", with offline mode forced. We do | |
| # NOT pip install anything: transformers, torch and pandas are already in the | |
| # sandbox, and autoawq (needed for AWQ models) is preinstalled too. | |
| os.environ["HF_HUB_OFFLINE"] = "1" | |
| os.environ["TRANSFORMERS_OFFLINE"] = "1" | |
| import json, re, shutil, tempfile | |
| import pandas as pd | |
| import torch | |
| from transformers import AutoTokenizer, AutoModelForCausalLM | |
| MODEL_ID = "." # the model's weights ship inside this repo | |
| MAX_NEW_TOKENS = 2048 # this is a 1.7B model, cheap to run -- room for a longer answer block | |
| def load_tokenizer(model_id: str = "."): | |
| """Load the tokenizer, patching tokenizer.json if it uses a merges format | |
| the sandbox's (older) tokenizers build can't parse. Newer exports sometimes | |
| store BPE merges as [["a","b"], ...] (list-of-lists) instead of the older | |
| ["a b", ...] (space-joined strings), which raises: | |
| 'data did not match any variant of untagged enum ModelWrapper'.""" | |
| tokenizer_path = os.path.join(model_id, "tokenizer.json") | |
| with open(tokenizer_path, encoding="utf-8") as handle: | |
| data = json.load(handle) | |
| merges = data.get("model", {}).get("merges", []) | |
| if not merges or not isinstance(merges[0], list): | |
| return AutoTokenizer.from_pretrained(model_id) | |
| data["model"]["merges"] = [" ".join(piece) for piece in merges] | |
| tmpdir = tempfile.mkdtemp() | |
| for name in ("tokenizer_config.json", "special_tokens_map.json"): | |
| src = os.path.join(model_id, name) | |
| if os.path.isfile(src): | |
| shutil.copy(src, tmpdir) | |
| with open(os.path.join(tmpdir, "tokenizer.json"), "w", encoding="utf-8") as handle: | |
| json.dump(data, handle) | |
| return AutoTokenizer.from_pretrained(tmpdir) | |
| # 1) Load the model shipped in this repo (float16 = the T4's native precision). | |
| tok = load_tokenizer(MODEL_ID) | |
| model = AutoModelForCausalLM.from_pretrained( | |
| MODEL_ID, torch_dtype=torch.float16, device_map="auto" | |
| ).eval() | |
| # 2) Read the hidden test set the platform mounts for us (one row per problem). | |
| df = pd.read_csv("/tmp/data/test.csv", dtype=str).fillna("") | |
| # 3) How we ask: let the model reason, then write its answers after a marker. | |
| SYSTEM = ( | |
| "You solve International Linguistics Olympiad problems by reasoning from the " | |
| "data in CONTEXT you are given to solve the problems in QUERY.\n" | |
| "There are common TASK TYPES that we specify below, but you may meet a TASK " | |
| "TYPE you have never seen: read the instruction and the examples, and answer " | |
| "the QUERY in the same form they use.\n\n" | |
| "Common TASK TYPES and what to return:\n" | |
| "`translation`: return the translated form only, in the language the task asks for;\n" | |
| "`fill_blanks`: return only the missing form for each indicated blank " | |
| "(this could be a word, part of a word, or a phonetic transcription -- pay close " | |
| "attention to what part of the CONTEXT is missing in QUERY);\n" | |
| "`match_letters`: return only the option letter (for example A, B, C);\n" | |
| "`text_to_num`: return the number in digits;\n" | |
| "`num_to_text`: return the number written out in words, in the language asked;\n" | |
| "any other type: return exactly what the instruction asks for, nothing else.\n\n" | |
| "First, reason step by step about (1) the linguistic rules that can be deduced " | |
| "from the examples in CONTEXT, and (2) how to apply them to the items in QUERY. " | |
| "Then write a draft answer, check it against the format requirements and the " | |
| "deduced rules, and make sure it has one answer for every item in QUERY. Correct " | |
| "it if needed.\n" | |
| "Finally, write a line that says exactly FINAL ANSWERS: and, below it, the " | |
| "answers to the items in QUERY (not those already given in CONTEXT), one " | |
| "answer per line, in the order the items are asked for -- the bare answer " | |
| "only, no numbering, no quotes, no extra text." | |
| ) | |
| def expected_answer_count(query: str, task_type: str) -> int: | |
| if task_type == "match_letters": | |
| numbered = re.findall(r"^\s*\d+\.", query, re.MULTILINE) | |
| return len(numbered) or 1 | |
| if "blanks" in query.lower(): | |
| range_match = re.search(r"\((\d+)-(\d+)\)", query) | |
| if range_match: | |
| return int(range_match.group(2)) - int(range_match.group(1)) + 1 | |
| return len(re.findall(r"\(\d+\)", query)) or 1 | |
| numbered = re.findall(r"^\s*\d+[.)]", query, re.MULTILINE) | |
| return len(numbered) or 1 | |
| def split_single_line_answer(text, expected, task_type): | |
| text = text.strip() | |
| if expected <= 1: | |
| return [text] | |
| def try_split(pattern): | |
| parts = [p.strip() for p in re.split(pattern, text) if p.strip()] | |
| return parts if len(parts) == expected else None | |
| if task_type == "match_letters": | |
| for pattern in (r"\s+", r",\s*", r";\s*"): | |
| if result := try_split(pattern): | |
| return result | |
| letters = re.findall(r"[A-Za-z]", text) | |
| if len(letters) == expected: | |
| return [letter.upper() for letter in letters] | |
| return [text] | |
| for pattern in (r";\s*", r",\s*", r"\s+"): | |
| if result := try_split(pattern): | |
| return result | |
| return [text] | |
| def parse_answers(text, query, task_type): | |
| """Keep only the lines after the last 'FINAL ANSWERS:' marker, one per line. | |
| We drop the reasoning above it and return the answers in order; the scorer | |
| lines our list up against the reference by position.""" | |
| marker = list(re.finditer(r"(?im)^[^\w\n]*final answers?[^\w\n]*:?\s*$", text)) | |
| if not marker: | |
| return [] | |
| text = text[marker[-1].end():] | |
| answers = [] | |
| for line in text.splitlines(): | |
| line = line.strip("`").strip() | |
| if not line: | |
| continue | |
| numbered = re.match(r"^\s*\d+[.)]\s+(.*)", line) | |
| line = numbered.group(1).strip() if numbered else line | |
| line = re.sub(r"\*\*", "", line).strip() | |
| if task_type == "match_letters": | |
| parts = [p.strip("().[]") for p in re.split(r"[\s,;]+", line) if p.strip()] | |
| if not (len(parts) > 1 and all(re.fullmatch(r"[A-Za-z]", p) for p in parts)): | |
| m = re.match(r"^\s*(?:\(([A-Za-z])\)|\[([A-Za-z])\]|([A-Za-z]))\.?:?\s*(.*)$", line) | |
| if m: | |
| line = (m.group(1) or m.group(2) or m.group(3)).upper() | |
| if line: | |
| answers.append(line) | |
| expected = expected_answer_count(query, task_type) | |
| if len(answers) == 1 and expected > 1: | |
| answers = split_single_line_answer(answers[0], expected, task_type) | |
| return answers | |
| # 4) Answer every problem, in order, and write the submission file. | |
| rows = [] | |
| for i, r in df.iterrows(): | |
| messages = [ | |
| {"role": "system", "content": SYSTEM}, | |
| {"role": "user", "content": ( | |
| f"CONTEXT:\n{r['context'].strip()}\n\n" | |
| f"TASK TYPE: `{r['task_type']}`\n\n" | |
| f"QUERY:\n{r['query'].strip()}" | |
| )}, | |
| ] | |
| ids = tok.apply_chat_template( | |
| messages, add_generation_prompt=True, return_tensors="pt", | |
| enable_thinking=False, # Qwen3 supports a <think> mode; off keeps output short and predictable | |
| ).to(model.device) | |
| with torch.no_grad(): | |
| out = model.generate(ids, max_new_tokens=MAX_NEW_TOKENS, do_sample=False) | |
| text = tok.decode(out[0][ids.shape[-1]:], skip_special_tokens=True).strip() | |
| answers = parse_answers(text, r["query"], r["task_type"]) | |
| rows.append({"id": r["id"], "pred": json.dumps(answers, ensure_ascii=False)}) | |
| print(f"[{i + 1}/{len(df)}] {len(answers)} answers", flush=True) | |
| pd.DataFrame(rows).to_csv("submission.csv", index=False) | |