Image-Text-to-Text
Transformers
Safetensors
English
Chinese
sensenova_loop
text-generation
nvfp4
modelopt
quantized
multimodal
looped-transformer
mhc
mtp
custom_code
conversational
8-bit precision
Instructions to use gitcommit90/SenseNova-Loop-9B-Preview-NVFP4 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use gitcommit90/SenseNova-Loop-9B-Preview-NVFP4 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="gitcommit90/SenseNova-Loop-9B-Preview-NVFP4", trust_remote_code=True) messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("gitcommit90/SenseNova-Loop-9B-Preview-NVFP4", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use gitcommit90/SenseNova-Loop-9B-Preview-NVFP4 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "gitcommit90/SenseNova-Loop-9B-Preview-NVFP4" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "gitcommit90/SenseNova-Loop-9B-Preview-NVFP4", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/gitcommit90/SenseNova-Loop-9B-Preview-NVFP4
- SGLang
How to use gitcommit90/SenseNova-Loop-9B-Preview-NVFP4 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 "gitcommit90/SenseNova-Loop-9B-Preview-NVFP4" \ --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": "gitcommit90/SenseNova-Loop-9B-Preview-NVFP4", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'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 "gitcommit90/SenseNova-Loop-9B-Preview-NVFP4" \ --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": "gitcommit90/SenseNova-Loop-9B-Preview-NVFP4", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Docker Model Runner
How to use gitcommit90/SenseNova-Loop-9B-Preview-NVFP4 with Docker Model Runner:
docker model run hf.co/gitcommit90/SenseNova-Loop-9B-Preview-NVFP4
NVFP4 (ModelOpt) quantization of sensenova/SenseNova-Loop-9B-Preview @27abea77 with BF16 MTP head
a57aa9f verified Download evaluation/harness/tasks.py from gitcommit90/SenseNova-Loop-9B-Preview-NVFP4: direct link, hf CLI and curl.
- Browser
- Download file 10.9 kB
-
https://huggingface.co/gitcommit90/SenseNova-Loop-9B-Preview-NVFP4/resolve/main/evaluation/harness/tasks.py
- Command line
-
hf download hf://gitcommit90/SenseNova-Loop-9B-Preview-NVFP4/evaluation/harness/tasks.py
-
curl -L -o tasks.py https://huggingface.co/gitcommit90/SenseNova-Loop-9B-Preview-NVFP4/resolve/main/evaluation/harness/tasks.py
10.9 kB
| """Task definitions: prompt construction, max_tokens, answer extraction and scoring. | |
| Every task exposes: | |
| build_messages(item, data_dir) -> (messages, tools|None) | |
| score(item, resp) -> dict(pred=..., correct=bool, **details) (resp = common.chat() result) | |
| """ | |
| from __future__ import annotations | |
| import base64 | |
| import json | |
| import os | |
| import re | |
| import subprocess | |
| import sys | |
| import tempfile | |
| from pathlib import Path | |
| import ifeval_lite | |
| from common import calls_from_message, strip_think | |
| # Fixed per-task generation budgets (thinking OFF). Changing these => bump EVAL_VERSION. | |
| MAX_TOKENS = {"ifeval": 1024, "gsm8k": 1024, "mmlu_pro": 1024, "humaneval": 1024, | |
| "tools": 512, "vqa": 64} | |
| # ============================================================================ IFEval | |
| def ifeval_messages(item, data_dir): | |
| return [{"role": "user", "content": item["prompt"]}], None | |
| def ifeval_score(item, resp): | |
| text = strip_think(resp["content"]) | |
| per = ifeval_lite.check(text, item["instruction_id_list"], item["kwargs"]) | |
| return {"pred": None, "correct": all(per), "per_instruction": per} | |
| # ============================================================================ GSM8K | |
| GSM_TMPL = ("Solve the following math problem step by step. At the end, write the final " | |
| "answer on its own line in the form \"The final answer is <number>\".\n\n{q}") | |
| NUM_RE = r"-?\$?\s?\d[\d,]*(?:\.\d+)?" | |
| def _norm_num(s): | |
| if s is None: | |
| return None | |
| s = s.replace(",", "").replace("$", "").replace(" ", "").rstrip(".") | |
| try: | |
| x = float(s) | |
| except ValueError: | |
| return None | |
| return str(int(x)) if x == int(x) else repr(round(x, 6)) | |
| def gsm_extract(text): | |
| text = strip_think(text) | |
| m = re.findall(r"final answer is[:\s]*\**\s*\\?\(?\\?(?:boxed\{)?\s*(" + NUM_RE + ")", text, re.I) | |
| if m: | |
| return _norm_num(m[-1]) | |
| m = re.findall(r"\\boxed\{\s*(" + NUM_RE + ")", text) | |
| if m: | |
| return _norm_num(m[-1]) | |
| m = re.findall(NUM_RE, text) | |
| return _norm_num(m[-1]) if m else None | |
| def gsm8k_messages(item, data_dir): | |
| return [{"role": "user", "content": GSM_TMPL.format(q=item["question"])}], None | |
| def gsm8k_score(item, resp): | |
| pred = gsm_extract(resp["content"]) | |
| return {"pred": pred, "correct": pred is not None and pred == _norm_num(item["answer"])} | |
| # ============================================================================ MMLU-Pro | |
| LETTERS = "ABCDEFGHIJ" | |
| MC_TMPL = ("The following is a multiple choice question about {cat}. Think step by step briefly, " | |
| "then finish with \"The answer is (X)\" where X is the letter of the correct option.\n\n" | |
| "Question: {q}\n{opts}") | |
| def mmlu_pro_messages(item, data_dir): | |
| opts = "\n".join(f"({LETTERS[i]}) {o}" for i, o in enumerate(item["options"])) | |
| return [{"role": "user", "content": MC_TMPL.format(cat=item["category"], q=item["question"], opts=opts)}], None | |
| def mc_extract(text, n_opts): | |
| text = strip_think(text) | |
| valid = LETTERS[:n_opts] | |
| m = re.findall(r"answer is:?\s*\**\(?([A-J])\)?", text, re.I) | |
| m = [x.upper() for x in m if x.upper() in valid] | |
| if m: | |
| return m[-1] | |
| m = re.findall(r"(?:^|\s)\(?([A-J])\)?[\.\s]*$", text.strip()) | |
| if m and m[-1] in valid: | |
| return m[-1] | |
| m = re.findall(r"\(([A-J])\)", text) | |
| m = [x for x in m if x in valid] | |
| return m[-1] if m else None | |
| def mmlu_pro_score(item, resp): | |
| pred = mc_extract(resp["content"], len(item["options"])) | |
| return {"pred": pred, "correct": pred == item["answer"]} | |
| # ============================================================================ HumanEval | |
| HE_TMPL = ("Complete the following Python function. Return the complete function definition " | |
| "(including the signature and any needed imports) in a single ```python code block.\n\n" | |
| "```python\n{p}```") | |
| def humaneval_messages(item, data_dir): | |
| return [{"role": "user", "content": HE_TMPL.format(p=item["prompt"])}], None | |
| def extract_code(text, item): | |
| text = strip_think(text) | |
| blocks = re.findall(r"```(?:python|py|Python)?\s*\n(.*?)```", text, re.S) | |
| code = None | |
| for b in blocks: | |
| if f"def {item['entry_point']}" in b: | |
| code = b | |
| break | |
| if code is None and blocks: | |
| code = blocks[0] | |
| if code is None: | |
| code = text | |
| if f"def {item['entry_point']}" not in code: # body-only completion | |
| code = item["prompt"] + code | |
| else: # keep the prompt's imports/helper defs available | |
| code = item["prompt"].split(f"def {item['entry_point']}")[0] + "\n" + code | |
| return code | |
| def run_python_sandboxed(program: str, timeout: float = 10.0) -> tuple[bool, str]: | |
| """Execute untrusted code in a fresh isolated interpreter in a temp dir with rlimits.""" | |
| with tempfile.TemporaryDirectory(prefix="he_") as td: | |
| path = os.path.join(td, "prog.py") | |
| with open(path, "w") as f: | |
| f.write(program) | |
| def limits(): | |
| import resource | |
| resource.setrlimit(resource.RLIMIT_AS, (2 << 30, 2 << 30)) | |
| resource.setrlimit(resource.RLIMIT_CPU, (int(timeout) + 1, int(timeout) + 1)) | |
| resource.setrlimit(resource.RLIMIT_FSIZE, (10 << 20, 10 << 20)) | |
| os.setsid() | |
| env = {"PATH": "/usr/bin:/bin", "HOME": td, "PYTHONHASHSEED": "0"} | |
| try: | |
| p = subprocess.run([sys.executable, "-I", "-B", path], cwd=td, env=env, capture_output=True, | |
| timeout=timeout, preexec_fn=limits, text=True) | |
| return p.returncode == 0, (p.stderr or "")[-400:] | |
| except subprocess.TimeoutExpired: | |
| return False, "timeout" | |
| def humaneval_score(item, resp): | |
| code = extract_code(resp["content"], item) | |
| prog = code + "\n\n" + item["test"] + f"\n\ncheck({item['entry_point']})\n" | |
| ok, err = run_python_sandboxed(prog) | |
| return {"pred": code, "correct": ok, "exec_error": None if ok else err} | |
| # ============================================================================ Tool calling | |
| def tools_messages(item, data_dir): | |
| msgs = [] | |
| if item.get("system"): | |
| msgs.append({"role": "system", "content": item["system"]}) | |
| msgs.append({"role": "user", "content": item["user"]}) | |
| return msgs, item["tools"] | |
| def _val_match(got, allowed): | |
| for a in allowed: | |
| if isinstance(a, (int, float)) and not isinstance(a, bool): | |
| try: | |
| if abs(float(got) - float(a)) < 1e-6: | |
| return True | |
| except (TypeError, ValueError): | |
| pass | |
| elif isinstance(a, str) and isinstance(got, str): | |
| if got.strip().lower() == a.strip().lower(): | |
| return True | |
| elif got == a: | |
| return True | |
| return False | |
| def _call_match(call, gold): | |
| if call.get("name") != gold["name"]: | |
| return False | |
| args = call.get("arguments") or {} | |
| if not isinstance(args, dict): | |
| return False | |
| spec = gold["arguments"] # name -> list of allowed values; [] or containing "__optional__" | |
| for k, allowed in spec.items(): | |
| optional = "__optional__" in allowed | |
| allowed = [a for a in allowed if a != "__optional__"] | |
| if k not in args: | |
| if not optional: | |
| return False | |
| continue | |
| if allowed and not _val_match(args[k], allowed): | |
| return False | |
| return all(k in spec for k in args) # no hallucinated params | |
| def tools_score(item, resp): | |
| calls, source, fmt = calls_from_message(resp["message"] or {"content": resp["content"]}, item["tools"]) | |
| gold = item["gold_calls"] | |
| if not gold: # irrelevance: must NOT call any tool | |
| correct = len(calls) == 0 | |
| else: | |
| remaining = list(calls) | |
| correct = len(calls) == len(gold) | |
| for g in gold: # order-insensitive matching for parallel calls | |
| hit = next((c for c in remaining if _call_match(c, g)), None) | |
| if hit is None: | |
| correct = False | |
| break | |
| remaining.remove(hit) | |
| names_ok = sorted(c.get("name") or "" for c in calls) == sorted(g["name"] for g in gold) | |
| return {"pred": calls, "correct": correct, "names_correct": names_ok, "parse_source": source, | |
| "format": fmt} | |
| # ============================================================================ VQA (TextVQA) | |
| VQA_SUFFIX = "\nAnswer the question using a single word or phrase." | |
| _CONTRACT = {"dont": "don't", "doesnt": "doesn't", "isnt": "isn't", "cant": "can't", "wont": "won't", | |
| "im": "i'm", "ive": "i've", "youre": "you're", "thats": "that's"} | |
| _NUMW = {"none": "0", "zero": "0", "one": "1", "two": "2", "three": "3", "four": "4", "five": "5", | |
| "six": "6", "seven": "7", "eight": "8", "nine": "9", "ten": "10"} | |
| _ART = {"a", "an", "the"} | |
| def vqa_norm(s: str) -> str: | |
| s = (s or "").strip().lower().replace("\n", " ").replace("\t", " ") | |
| s = s.rstrip(".") | |
| s = re.sub(r"(?<=\d),(?=\d)", "", s) | |
| s = re.sub(r"[;/\[\]\"{}()=+\\_\-><@`,?!*#%^&$:~|]", " ", s) | |
| s = re.sub(r"(?<!\d)\.(?!\d)", "", s) | |
| words = [_NUMW.get(w, _CONTRACT.get(w, w)) for w in s.split()] | |
| return " ".join(w for w in words if w not in _ART) | |
| def vqa_messages(item, data_dir): | |
| img_path = Path(data_dir) / item["image"] | |
| b64 = base64.b64encode(img_path.read_bytes()).decode() | |
| return [{"role": "user", "content": [ | |
| {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{b64}"}}, | |
| {"type": "text", "text": item["question"] + VQA_SUFFIX}, | |
| ]}], None | |
| def vqa_score(item, resp): | |
| pred = vqa_norm(strip_think(resp["content"]).split("\n")[0]) | |
| golds = [vqa_norm(a) for a in item["answers"]] | |
| matches = sum(1 for g in golds if g == pred) | |
| soft = min(1.0, matches / 3.0) | |
| # primary binary metric (relaxed): normalized exact match with >=2 of the 10 annotator answers | |
| # (robust to a single noisy annotation); standard VQA soft accuracy min(1, m/3) also recorded. | |
| return {"pred": pred, "correct": matches >= 2 and bool(pred), "vqa_soft_acc": soft, | |
| "any_annotator_match": matches >= 1} | |
| TASKS = { | |
| "ifeval": (ifeval_messages, ifeval_score), | |
| "gsm8k": (gsm8k_messages, gsm8k_score), | |
| "mmlu_pro": (mmlu_pro_messages, mmlu_pro_score), | |
| "humaneval": (humaneval_messages, humaneval_score), | |
| "tools": (tools_messages, tools_score), | |
| "vqa": (vqa_messages, vqa_score), | |
| } | |
| def agreement_key(task: str, scored: dict, resp: dict): | |
| """Label-free comparable answer used for reference agreement.""" | |
| if task == "ifeval": | |
| return strip_think(resp.get("content", "")).strip() | |
| if task == "humaneval": | |
| return (scored.get("pred") or "").strip() | |
| if task == "tools": | |
| return json.dumps(scored.get("pred"), sort_keys=True, default=str) | |
| return scored.get("pred") | |