Image-Text-to-Text
Transformers
Safetensors
qwen3_vl
qwen3-vl
viss
streaming-video
visual-question-answering
causal-video
conversational
Instructions to use mis2/ViSS-8B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use mis2/ViSS-8B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="mis2/ViSS-8B") 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 AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("mis2/ViSS-8B") model = AutoModelForMultimodalLM.from_pretrained("mis2/ViSS-8B", device_map="auto") 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?"} ] }, ] inputs = processor.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=256) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use mis2/ViSS-8B with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "mis2/ViSS-8B" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "mis2/ViSS-8B", "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/mis2/ViSS-8B
- SGLang
How to use mis2/ViSS-8B 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 "mis2/ViSS-8B" \ --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": "mis2/ViSS-8B", "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 "mis2/ViSS-8B" \ --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": "mis2/ViSS-8B", "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 mis2/ViSS-8B with Docker Model Runner:
docker model run hf.co/mis2/ViSS-8B
Download code/scripts/score_official_benchmark_predictions.py from mis2/ViSS-8B: direct link, hf CLI and curl.
- Browser
- Download file 13.9 kB
-
https://huggingface.co/mis2/ViSS-8B/resolve/main/code/scripts/score_official_benchmark_predictions.py
- Command line
-
hf download hf://mis2/ViSS-8B/code/scripts/score_official_benchmark_predictions.py
-
curl -L -o score_official_benchmark_predictions.py https://huggingface.co/mis2/ViSS-8B/resolve/main/code/scripts/score_official_benchmark_predictions.py
13.9 kB
| #!/usr/bin/env python3 | |
| from __future__ import annotations | |
| import argparse | |
| import copy | |
| import hashlib | |
| import importlib.util | |
| import io | |
| import json | |
| import re | |
| import subprocess | |
| import sys | |
| import tempfile | |
| from contextlib import redirect_stdout | |
| from pathlib import Path | |
| from statistics import mean | |
| from types import SimpleNamespace | |
| from typing import Any | |
| PROJECT_ROOT = Path(__file__).resolve().parents[1] | |
| from viss_core.benchmarks import load_prediction_file | |
| OVO_GROUP_TASKS = { | |
| "backward": ("EPM", "ASI", "HLD"), | |
| "realtime": ("OCR", "ACR", "ATR", "STU", "FPD", "OJR"), | |
| "forward": ("REC", "SSR", "CRR"), | |
| } | |
| INVALID_EMPTY_MODEL_RESPONSE = "__INVALID_EMPTY_MODEL_RESPONSE__" | |
| def main() -> None: | |
| parser = argparse.ArgumentParser( | |
| description="Adapt agent predictions to the original benchmark formats and invoke their scorers." | |
| ) | |
| parser.add_argument("--benchmark", required=True, choices=("streamingbench", "ovo")) | |
| parser.add_argument("--official-root", type=Path, required=True) | |
| parser.add_argument("--annotation", type=Path, required=True) | |
| parser.add_argument("--predictions", type=Path, required=True) | |
| parser.add_argument("--output-json", type=Path, required=True) | |
| parser.add_argument("--official-input-json", type=Path, default=None) | |
| args = parser.parse_args() | |
| if args.benchmark == "streamingbench": | |
| report, official_input = score_streamingbench( | |
| args.official_root, args.annotation, args.predictions | |
| ) | |
| else: | |
| report, official_input = score_ovo(args.official_root, args.annotation, args.predictions) | |
| args.output_json.parent.mkdir(parents=True, exist_ok=True) | |
| args.output_json.write_text( | |
| json.dumps(report, indent=2, ensure_ascii=False, sort_keys=True) + "\n", | |
| encoding="utf-8", | |
| ) | |
| if args.official_input_json: | |
| args.official_input_json.parent.mkdir(parents=True, exist_ok=True) | |
| args.official_input_json.write_text( | |
| json.dumps(official_input, indent=2, ensure_ascii=False, sort_keys=True) + "\n", | |
| encoding="utf-8", | |
| ) | |
| print(json.dumps(report, indent=2, ensure_ascii=False, sort_keys=True)) | |
| def score_streamingbench( | |
| official_root: Path, annotation: Path, predictions_path: Path | |
| ) -> tuple[dict[str, Any], Any]: | |
| predictions = load_prediction_file(predictions_path) | |
| data = json.loads(annotation.read_text(encoding="utf-8")) | |
| model_key = "AgenticSFT" | |
| expected_ids: list[str] = [] | |
| empty_model_response_ids: list[str] = [] | |
| for video_index, entry in enumerate(data): | |
| for question_index, question in enumerate(entry.get("questions") or []): | |
| query_id = f"streaming_{video_index}_{question_index}" | |
| expected_ids.append(query_id) | |
| raw = predictions.get(query_id) | |
| letter = _mcq_letter(raw, question.get("options") or []) | |
| response = letter if letter is not None else str(raw or "") | |
| if not response: | |
| # The original scorer skips false-y responses instead of counting | |
| # them as incorrect. Preserve the model failure without imputing an | |
| # answer by passing an explicit invalid value through the scorer. | |
| empty_model_response_ids.append(query_id) | |
| response = INVALID_EMPTY_MODEL_RESPONSE | |
| question[model_key] = [response] | |
| _require_exact_coverage(predictions, expected_ids, "StreamingBench") | |
| count_script = official_root / "src" / "data" / "count.py" | |
| if not count_script.is_file(): | |
| raise FileNotFoundError(count_script) | |
| with tempfile.TemporaryDirectory(prefix="streamingbench_official_score_") as tmp: | |
| tmp_path = Path(tmp) | |
| official_input = tmp_path / "predictions.json" | |
| official_input.write_text(json.dumps(data, ensure_ascii=False), encoding="utf-8") | |
| completed = subprocess.run( | |
| [ | |
| sys.executable, | |
| str(count_script), | |
| "--model", | |
| model_key, | |
| "--task", | |
| "real", | |
| "--src", | |
| str(official_input), | |
| ], | |
| cwd=tmp_path, | |
| check=True, | |
| text=True, | |
| capture_output=True, | |
| ) | |
| stats = json.loads((tmp_path / f"{model_key}_stats.json").read_text(encoding="utf-8")) | |
| total = stats.get("total") or {} | |
| by_task = { | |
| task: { | |
| "accuracy": float(values["accuracy"]), | |
| "correct": float(values["correct"]), | |
| "total": int(values["total"]), | |
| } | |
| for task, values in stats.items() | |
| if task != "total" | |
| } | |
| if int(total.get("total", 0)) != len(expected_ids): | |
| raise RuntimeError( | |
| f"official StreamingBench scorer counted {total.get('total')} of {len(expected_ids)} queries" | |
| ) | |
| report = { | |
| "benchmark": "streamingbench", | |
| "official_scorer": str(count_script), | |
| "official_scorer_sha256": _sha256(count_script), | |
| "official_repository_commit": _git_commit(official_root), | |
| "official_stdout": completed.stdout.strip(), | |
| "num_queries": len(expected_ids), | |
| "num_predictions": len(expected_ids), | |
| "coverage": 1.0, | |
| "num_empty_model_responses": len(empty_model_response_ids), | |
| "empty_model_response_ids": empty_model_response_ids, | |
| "empty_response_scoring": "counted_as_incorrect_without_answer_imputation", | |
| "accuracy": float(total["accuracy"]), | |
| "correct": float(total["correct"]), | |
| "total": int(total["total"]), | |
| "by_task": by_task, | |
| } | |
| return report, data | |
| def score_ovo( | |
| official_root: Path, annotation: Path, predictions_path: Path | |
| ) -> tuple[dict[str, Any], Any]: | |
| predictions = load_prediction_file(predictions_path) | |
| annotations = json.loads(annotation.read_text(encoding="utf-8")) | |
| results: dict[str, list[dict[str, Any]]] = {key: [] for key in OVO_GROUP_TASKS} | |
| expected_ids: list[str] = [] | |
| empty_model_response_ids: list[str] = [] | |
| for source in annotations: | |
| item = copy.deepcopy(source) | |
| task = str(item.get("task") or "").upper() | |
| group = next((name for name, tasks in OVO_GROUP_TASKS.items() if task in tasks), None) | |
| if group is None: | |
| raise ValueError(f"unknown OVO task: {task}") | |
| if group == "forward": | |
| for index, test_info in enumerate(item.get("test_info") or []): | |
| query_id = f"ovo_{item['id']}_{index}" | |
| expected_ids.append(query_id) | |
| response = str(predictions.get(query_id) or "") | |
| if not response: | |
| empty_model_response_ids.append(query_id) | |
| test_info["response"] = response | |
| else: | |
| query_id = f"ovo_{item['id']}" | |
| expected_ids.append(query_id) | |
| letter = _mcq_letter(predictions.get(query_id), item.get("options") or []) | |
| response = letter if letter is not None else str(predictions.get(query_id) or "") | |
| if not response: | |
| empty_model_response_ids.append(query_id) | |
| item["response"] = response | |
| item["ground_truth"] = chr(ord("A") + int(item["gt"])) | |
| results[group].append(item) | |
| _require_exact_coverage(predictions, expected_ids, "OVO-Bench") | |
| score_module_path = official_root / "utils" / "OVOBenchScore.py" | |
| if not score_module_path.is_file(): | |
| raise FileNotFoundError(score_module_path) | |
| spec = importlib.util.spec_from_file_location("official_ovo_score", score_module_path) | |
| if spec is None or spec.loader is None: | |
| raise ImportError(score_module_path) | |
| module = importlib.util.module_from_spec(spec) | |
| spec.loader.exec_module(module) | |
| scorer = module.OVOBenchOfflineScore(SimpleNamespace(model="AgenticSFT"), copy.deepcopy(results)) | |
| _, backward_scores = scorer.calculate_score_backward_realtime(copy.deepcopy(results["backward"])) | |
| _, realtime_scores = scorer.calculate_score_backward_realtime(copy.deepcopy(results["realtime"])) | |
| _, forward_scores = scorer.calculate_score_forward(copy.deepcopy(results["forward"])) | |
| score_maps = { | |
| "backward": backward_scores, | |
| "realtime": realtime_scores, | |
| "forward": forward_scores, | |
| } | |
| by_task: dict[str, dict[str, Any]] = {} | |
| official_by_group: dict[str, dict[str, Any]] = {} | |
| for group, expected_tasks in OVO_GROUP_TASKS.items(): | |
| scores = score_maps[group] | |
| if set(scores) != set(expected_tasks): | |
| raise RuntimeError(f"official OVO scorer tasks for {group}: {sorted(scores)}") | |
| task_accuracies = [] | |
| for task in expected_tasks: | |
| values = scores[task] | |
| accuracy = sum(values) / len(values) | |
| by_task[task] = { | |
| "accuracy": accuracy, | |
| "correct": float(sum(values)), | |
| "total": len(values), | |
| } | |
| task_accuracies.append(accuracy) | |
| official_by_group[group] = { | |
| "accuracy": mean(task_accuracies), | |
| "num_tasks": len(task_accuracies), | |
| } | |
| official_overall = mean(value["accuracy"] for value in official_by_group.values()) | |
| derived_metrics = _ovo_derived_metrics(by_task, official_by_group) | |
| stdout_buffer = io.StringIO() | |
| with redirect_stdout(stdout_buffer): | |
| module.OVOBenchOfflineScore( | |
| SimpleNamespace(model="AgenticSFT"), copy.deepcopy(results) | |
| ).score() | |
| official_stdout = stdout_buffer.getvalue().strip() | |
| _verify_ovo_stdout(official_stdout, by_task, official_by_group, official_overall) | |
| report = { | |
| "benchmark": "ovo", | |
| "official_scorer": str(score_module_path), | |
| "official_scorer_sha256": _sha256(score_module_path), | |
| "official_repository_commit": _git_commit(official_root), | |
| "official_stdout": official_stdout, | |
| "num_queries": len(expected_ids), | |
| "num_predictions": len(expected_ids), | |
| "coverage": 1.0, | |
| "num_empty_model_responses": len(empty_model_response_ids), | |
| "empty_model_response_ids": empty_model_response_ids, | |
| "empty_response_scoring": "passed_unchanged_to_original_scorer_without_answer_imputation", | |
| "by_task": by_task, | |
| "ovo_official": { | |
| "name": "Total Avg", | |
| "aggregation": "mean of Real-Time, Backward, and Forward task-macro averages", | |
| "accuracy": official_overall, | |
| "by_group": official_by_group, | |
| }, | |
| **derived_metrics, | |
| } | |
| return report, results | |
| def _ovo_derived_metrics( | |
| by_task: dict[str, dict[str, Any]], | |
| by_group: dict[str, dict[str, Any]], | |
| ) -> dict[str, dict[str, Any]]: | |
| micro_correct = sum(float(value["correct"]) for value in by_task.values()) | |
| micro_total = sum(int(value["total"]) for value in by_task.values()) | |
| if micro_total <= 0: | |
| raise RuntimeError("OVO-Bench has no scored predictions") | |
| rt_bt_accuracy = mean( | |
| float(by_group[group]["accuracy"]) for group in ("realtime", "backward") | |
| ) | |
| return { | |
| "ovo_micro_overall": { | |
| "name": "Overall", | |
| "aggregation": "micro average over all expanded OVO queries", | |
| "accuracy": micro_correct / micro_total, | |
| "correct": micro_correct, | |
| "total": micro_total, | |
| }, | |
| "ovo_rt_bt_avg": { | |
| "name": "RT/BT Avg", | |
| "aggregation": "mean of Real-Time and Backward task-macro averages", | |
| "accuracy": rt_bt_accuracy, | |
| }, | |
| } | |
| def _require_exact_coverage( | |
| predictions: dict[str, Any], expected_ids: list[str], benchmark: str | |
| ) -> None: | |
| expected = set(expected_ids) | |
| missing = sorted(expected - set(predictions)) | |
| if missing: | |
| raise RuntimeError(f"{benchmark} missing {len(missing)} predictions: {missing[:10]}") | |
| if len(expected_ids) != len(expected): | |
| raise RuntimeError(f"{benchmark} contains duplicate query IDs") | |
| def _mcq_letter(prediction: Any, _options: list[Any]) -> str | None: | |
| text = str(prediction or "").strip() | |
| match = re.match(r"^[\(\[]?([A-D])(?:[\)\].:\s-]|$)", text, flags=re.IGNORECASE) | |
| if match: | |
| return match.group(1).upper() | |
| return None | |
| def _verify_ovo_stdout( | |
| stdout: str, | |
| by_task: dict[str, dict[str, Any]], | |
| by_group: dict[str, dict[str, Any]], | |
| overall: float, | |
| ) -> None: | |
| printed_tasks = { | |
| task: float(value) | |
| for task, value in re.findall(r"Task:\s*(\w+),\s*Acc:\s*([0-9.]+)", stdout) | |
| } | |
| for task, values in by_task.items(): | |
| if printed_tasks.get(task) != round(values["accuracy"] * 100, 2): | |
| raise RuntimeError(f"official OVO stdout mismatch for {task}") | |
| labels = {"backward": "Backward", "realtime": "Realtime", "forward": "Forward"} | |
| for group, label in labels.items(): | |
| match = re.search(rf"{label} Avg\.:\s*([0-9.]+)", stdout) | |
| if match is None or float(match.group(1)) != round(by_group[group]["accuracy"] * 100, 2): | |
| raise RuntimeError(f"official OVO stdout mismatch for {group} Avg") | |
| match = re.search(r"Total Avg\.:\s*([0-9.]+)", stdout) | |
| if match is None or float(match.group(1)) != round(overall * 100, 2): | |
| raise RuntimeError("official OVO stdout mismatch for Total Avg") | |
| def _sha256(path: Path) -> str: | |
| digest = hashlib.sha256() | |
| with path.open("rb") as handle: | |
| for block in iter(lambda: handle.read(8 << 20), b""): | |
| digest.update(block) | |
| return digest.hexdigest() | |
| def _git_commit(root: Path) -> str | None: | |
| completed = subprocess.run( | |
| ["git", "-C", str(root), "rev-parse", "HEAD"], | |
| text=True, | |
| capture_output=True, | |
| check=False, | |
| ) | |
| if completed.returncode != 0: | |
| return None | |
| commit = completed.stdout.strip() | |
| return commit or None | |
| if __name__ == "__main__": | |
| main() | |