Text Generation
Transformers
Safetensors
English
qwen2
chat
conversational
text-generation-inference
Instructions to use divaspoudel/iol-div-exp with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use divaspoudel/iol-div-exp with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="divaspoudel/iol-div-exp") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("divaspoudel/iol-div-exp") model = AutoModelForCausalLM.from_pretrained("divaspoudel/iol-div-exp", 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 divaspoudel/iol-div-exp with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "divaspoudel/iol-div-exp" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "divaspoudel/iol-div-exp", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/divaspoudel/iol-div-exp
- SGLang
How to use divaspoudel/iol-div-exp 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 "divaspoudel/iol-div-exp" \ --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": "divaspoudel/iol-div-exp", "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 "divaspoudel/iol-div-exp" \ --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": "divaspoudel/iol-div-exp", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use divaspoudel/iol-div-exp with Docker Model Runner:
docker model run hf.co/divaspoudel/iol-div-exp
| import os | |
| os.environ["HF_HUB_OFFLINE"] = "1" | |
| os.environ["TRANSFORMERS_OFFLINE"] = "1" | |
| os.environ["TOKENIZERS_PARALLELISM"] = "false" | |
| # --- runtime bootstrap. 1.5B runs in plain fp16 (fits the T4 with room to | |
| # --- spare), so no bitsandbytes is needed here. PyPI is reachable at eval time. | |
| import subprocess, sys | |
| def _pip(*pkgs): | |
| try: | |
| subprocess.run([sys.executable, "-m", "pip", "install", "-q", *pkgs], check=False) | |
| except Exception as e: | |
| print("pip bootstrap skipped:", e, flush=True) | |
| _pip("accelerate>=0.30.0", "sentencepiece", "tiktoken") | |
| import re, json, time | |
| import pandas as pd | |
| import torch | |
| START = time.time() | |
| TIME_BUDGET = 27 * 60 # stop generating with margin before the 30-min hard limit | |
| # On the platform the repo IS the working dir, so "." holds the weights. | |
| # IOL_MODEL_DIR lets a local dry-run point at a downloaded snapshot instead. | |
| MODEL_ID = os.environ.get("IOL_MODEL_DIR", ".") | |
| MAX_NEW_TOKENS = 768 # 1.5B is fast, so we can afford a bigger budget | |
| # --------------------------------------------------------------------------- | |
| # Load in plain float16 (no quantization). 1.5B is ~3.5 GB, well within 16 GB. | |
| # float16 (not bfloat16): the T4 is a Turing GPU with no native bfloat16. | |
| # --------------------------------------------------------------------------- | |
| from transformers import AutoTokenizer, AutoModelForCausalLM | |
| try: | |
| tok = AutoTokenizer.from_pretrained(MODEL_ID) | |
| except Exception as e: | |
| print("fast tokenizer failed, retrying slow:", e, flush=True) | |
| tok = AutoTokenizer.from_pretrained(MODEL_ID, use_fast=False) | |
| model = AutoModelForCausalLM.from_pretrained( | |
| MODEL_ID, torch_dtype=torch.float16, device_map="auto" | |
| ).eval() | |
| if tok.pad_token_id is None: | |
| tok.pad_token_id = tok.eos_token_id | |
| df = pd.read_csv("/tmp/data/test.csv", dtype=str).fillna("") | |
| # --------------------------------------------------------------------------- | |
| # Helpers | |
| # --------------------------------------------------------------------------- | |
| def expected_n(query, context): | |
| # How many numbered items must this row's answer list contain? | |
| for pat in (r"(?m)^\s*(\d+)\s*[\.\)]", r"\((\d+)\)"): | |
| m = re.findall(pat, query) | |
| if m: | |
| return len(m) | |
| # matching tasks number their items in the context, not the query | |
| m = re.findall(r"(?m)^\s*(\d+)\s*[\.\)]", context) | |
| return len(m) if m else 1 | |
| def strip_num(s): | |
| # Remove a leading list marker ("1.", "2)", "(3)") but NEVER a bare number, | |
| # so numeric answers like "111" survive. Punctuation after the digit is required. | |
| return re.sub(r"^\s*(?:\(\d+\)|\d+\s*[\.\):])\s*", "", s).strip() | |
| # A line that begins with a list marker of the same forms. | |
| NUMLINE = r"^\s*(?:\(\d+\)|\d+\s*[\.\):-])" | |
| def parse_output(text, n, task_type): | |
| ans_part, expl = text, "" | |
| m = re.search(r"(?is)\bEXPLANATION\b\s*:?", text) | |
| if m: | |
| ans_part = text[:m.start()] | |
| expl = text[m.end():].strip() | |
| m2 = re.search(r"(?is)\bANSWERS?\b\s*:?", ans_part) | |
| if m2: | |
| ans_part = ans_part[m2.end():] | |
| lines = [ln.strip() for ln in ans_part.splitlines() if ln.strip()] | |
| numbered = [ln for ln in lines if re.match(NUMLINE, ln)] | |
| use = numbered if numbered else lines | |
| answers = [strip_num(ln) for ln in use] | |
| # Fallback: model crammed items onto one comma-separated line (common for | |
| # matching/number tasks). Split it back out, but not for free-text tasks | |
| # where commas can legitimately appear inside an answer. | |
| if len(answers) < n and task_type in ("match_letters", "text_to_num", "num_to_text"): | |
| flat = [] | |
| for ln in use: | |
| flat += re.split(r"\s*[,;]\s*", strip_num(ln)) | |
| flat = [x for x in flat if x != ""] | |
| if len(flat) > len(answers): | |
| answers = flat | |
| if len(answers) < n: | |
| answers += [""] * (n - len(answers)) | |
| expl = re.sub(r"\s+", " ", expl).strip()[:800] # keep explanation single-line for CSV | |
| if not expl: # never leave it blank (human-eval eligibility) | |
| expl = fallback_expl(task_type) | |
| return answers[:n], expl | |
| TASK_HINTS = { | |
| "translation": "Translate each item. Answer in the language the query asks for.", | |
| "fill_blanks": "Work out the rule from the paired forms, then give the missing form for each blank.", | |
| "match_letters": "For each numbered item, output ONLY the letter label of its correct match.", | |
| "text_to_num": "Convert each written number into digits.", | |
| "num_to_text": "Write each number out in words in the task language.", | |
| } | |
| FALLBACK_EXPL = { | |
| "translation": "Aligned each given form with its translation to recover the recurring morphemes and word order, then applied those patterns to the queried items.", | |
| "fill_blanks": "Compared the paired forms to isolate the rule relating them, then applied that rule to produce each missing form.", | |
| "match_letters": "Matched each item to its counterpart using the regularities shared across the given pairs.", | |
| "text_to_num": "Reconstructed the number system from the worked examples, then decoded each written number into digits.", | |
| "num_to_text": "Reconstructed the number system from the worked examples, then wrote each value in the language's number words.", | |
| } | |
| def fallback_expl(task_type): | |
| return FALLBACK_EXPL.get(task_type, | |
| "Inferred the underlying rule from the data given in the problem and applied it to each item.") | |
| def build_messages(r): | |
| hint = TASK_HINTS.get(r["task_type"].strip().lower(), "Answer every numbered item.") | |
| sys_prompt = ( | |
| "You are an expert solver of International Linguistics Olympiad problems. " | |
| "Each problem is fully self-contained: reason only from the data shown, with no outside " | |
| "knowledge of the language. Infer the grammar, vocabulary, or number system from the " | |
| "given examples, then answer every numbered item.\n" | |
| "OUTPUT FORMAT (follow exactly):\n" | |
| "ANSWERS:\n" | |
| "1. <answer to item 1>\n" | |
| "2. <answer to item 2>\n" | |
| "(one line per item, numbered, in the query's order, no commentary between them)\n" | |
| "EXPLANATION:\n" | |
| "<2-4 short sentences, human-readable, describing the rule you found>" | |
| ) | |
| user_prompt = r["context"].strip() + "\n\n" + r["query"].strip() + "\n\n" + hint | |
| return [ | |
| {"role": "system", "content": sys_prompt}, | |
| {"role": "user", "content": user_prompt}, | |
| ] | |
| # --------------------------------------------------------------------------- | |
| # Run | |
| # --------------------------------------------------------------------------- | |
| out_rows = [] | |
| for _, r in df.iterrows(): | |
| n = expected_n(r["query"], r["context"]) | |
| if time.time() - START > TIME_BUDGET: | |
| # Out of time: still emit a valid, correctly-sized row (non-blank explanation). | |
| out_rows.append({"id": r["id"], | |
| "pred": json.dumps([""] * n, ensure_ascii=False), | |
| "explanation": fallback_expl(r["task_type"].strip().lower())}) | |
| continue | |
| enc = tok.apply_chat_template( | |
| build_messages(r), add_generation_prompt=True, | |
| return_tensors="pt", return_dict=True, # BatchEncoding incl. attention_mask | |
| ).to(model.device) | |
| input_len = enc["input_ids"].shape[-1] | |
| with torch.no_grad(): | |
| gen = model.generate( | |
| **enc, max_new_tokens=MAX_NEW_TOKENS, | |
| do_sample=False, pad_token_id=tok.pad_token_id, | |
| ) | |
| text = tok.decode(gen[0][input_len:], skip_special_tokens=True).strip() | |
| answers, expl = parse_output(text, n, r["task_type"].strip().lower()) | |
| out_rows.append({"id": r["id"], | |
| "pred": json.dumps(answers, ensure_ascii=False), | |
| "explanation": expl}) | |
| print(str(len(out_rows)) + "/" + str(len(df)) + " done", flush=True) | |
| pd.DataFrame(out_rows, columns=["id", "pred", "explanation"]).to_csv( | |
| "submission.csv", index=False) | |
| print("wrote submission.csv", flush=True) | |