Image-Text-to-Text
Transformers
Safetensors
qwen3_5
vllm
video
multimodal
reinforcement-learning
temporal-grounding
object-tracking
video-segmentation
visual-question-answering
spatial-reasoning
qwen3.5
conversational
Instructions to use OraRL/Video-ORA-9B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use OraRL/Video-ORA-9B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="OraRL/Video-ORA-9B") 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)# Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("OraRL/Video-ORA-9B") model = AutoModelForMultimodalLM.from_pretrained("OraRL/Video-ORA-9B", 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=40) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use OraRL/Video-ORA-9B with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "OraRL/Video-ORA-9B" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "OraRL/Video-ORA-9B", "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/OraRL/Video-ORA-9B
- SGLang
How to use OraRL/Video-ORA-9B 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 "OraRL/Video-ORA-9B" \ --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": "OraRL/Video-ORA-9B", "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 "OraRL/Video-ORA-9B" \ --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": "OraRL/Video-ORA-9B", "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 OraRL/Video-ORA-9B with Docker Model Runner:
docker model run hf.co/OraRL/Video-ORA-9B
| """Dependency-light compatibility adapter for canonical OraRL evaluation rows.""" | |
| from __future__ import annotations | |
| import copy | |
| import json | |
| import os | |
| import re | |
| from collections.abc import Mapping, Sequence | |
| from pathlib import Path | |
| from typing import Any | |
| _CANONICAL_FIELDS = { | |
| "schema_version", | |
| "eval_task", | |
| "sample_id", | |
| "benchmark", | |
| "split", | |
| "problem", | |
| "answer", | |
| "images", | |
| "videos", | |
| "problem_type", | |
| "source", | |
| } | |
| _MEDIA_PATH_KEYS = ( | |
| "path", | |
| "video", | |
| "image", | |
| "video_path", | |
| "image_path", | |
| "file_name", | |
| ) | |
| _PATH_KEY_RE = re.compile( | |
| r"(?:^|_)(?:artifact|artifacts|cfg|checkpoint|ckpt|dir|directory|file|" | |
| r"files|image|images|media|path|paths|prefix|root|subtitle|" | |
| r"subtitles|tensor|tensors|video|videos)$" | |
| ) | |
| _GROUND_TRUTH_KEYS = ( | |
| "bbox", | |
| "bboxes", | |
| "boxes", | |
| "coordinates", | |
| "duration", | |
| "end", | |
| "frame", | |
| "frame_id", | |
| "frame_ids", | |
| "gt_bbox", | |
| "mask", | |
| "masks", | |
| "negative_points", | |
| "normalized_solution", | |
| "object", | |
| "positive_points", | |
| "query", | |
| "segment", | |
| "segmentation", | |
| "span", | |
| "spans", | |
| "start", | |
| "target", | |
| "time", | |
| "timestamp", | |
| "timestamps", | |
| "trajectory", | |
| ) | |
| _ASSET_DIRECTORIES = frozenset({"artifacts", "media"}) | |
| class CanonicalDataError(ValueError): | |
| """Raised when a canonical row cannot be safely adapted.""" | |
| def is_canonical_row(record: Any) -> bool: | |
| """Return whether a mapping uses the canonical evaluation-row contract.""" | |
| return ( | |
| isinstance(record, Mapping) | |
| and record.get("schema_version") == 1 | |
| and _CANONICAL_FIELDS.issubset(record) | |
| ) | |
| def _configured_root() -> Path | None: | |
| value = os.environ.get("ORARL_EVAL_DATA_ROOT", "").strip() | |
| if value: | |
| return Path(value).expanduser().resolve() | |
| manifest = os.environ.get("ORARL_EVAL_DATASETS_JSONL", "").strip() | |
| if manifest: | |
| return Path(manifest).expanduser().resolve().parent | |
| return None | |
| def _configured_asset_root() -> Path | None: | |
| value = os.environ.get("ORARL_EVAL_ASSET_ROOT", "").strip() | |
| return Path(value).expanduser().resolve() if value else None | |
| def _infer_root(input_path: Path) -> Path | None: | |
| configured = _configured_root() | |
| if configured is not None: | |
| return configured | |
| for candidate in (input_path.parent, *input_path.parents): | |
| if (candidate / "datasets.jsonl").is_file(): | |
| return candidate.resolve() | |
| return None | |
| def canonical_dataset_record( | |
| eval_task: str, | |
| split: str, | |
| root: str | os.PathLike[str] | None = None, | |
| ) -> dict[str, Any] | None: | |
| """Return one canonical ``datasets.jsonl`` record for a task split.""" | |
| repository_root = ( | |
| Path(root).expanduser().resolve() if root is not None else _configured_root() | |
| ) | |
| if repository_root is None: | |
| return None | |
| manifest = repository_root / "datasets.jsonl" | |
| if not manifest.is_file(): | |
| return None | |
| normalized_split = str(split).strip().casefold().replace("-", "_") | |
| matches: list[dict[str, Any]] = [] | |
| try: | |
| with manifest.open("r", encoding="utf-8") as handle: | |
| for line_number, line in enumerate(handle, start=1): | |
| if not line.strip(): | |
| continue | |
| try: | |
| record = json.loads(line) | |
| except json.JSONDecodeError as error: | |
| raise CanonicalDataError( | |
| f"{manifest}:{line_number}: invalid JSON: {error}" | |
| ) from error | |
| if not isinstance(record, Mapping): | |
| raise CanonicalDataError( | |
| f"{manifest}:{line_number}: dataset record must be an object" | |
| ) | |
| record_task = str(record.get("task") or "").casefold() | |
| record_split = str(record.get("split") or "").casefold() | |
| if record_task == str(eval_task).casefold() and record_split == normalized_split: | |
| matches.append(copy.deepcopy(dict(record))) | |
| except OSError as error: | |
| raise CanonicalDataError(f"cannot read canonical dataset manifest: {error}") from error | |
| if len(matches) > 1: | |
| raise CanonicalDataError( | |
| f"duplicate canonical dataset profile for {eval_task}/{normalized_split}" | |
| ) | |
| return matches[0] if matches else None | |
| def resolve_repository_path( | |
| value: str, | |
| root: str | os.PathLike[str], | |
| asset_root: str | os.PathLike[str] | None = None, | |
| ) -> str: | |
| """Resolve one repository-relative canonical path without allowing escape.""" | |
| raw = str(value).strip() | |
| if not raw: | |
| raise CanonicalDataError("canonical repository path must be nonempty") | |
| repository_root = Path(root).expanduser().resolve() | |
| configured_asset_root = ( | |
| Path(asset_root).expanduser().resolve() | |
| if asset_root is not None | |
| else _configured_asset_root() | |
| ) | |
| candidate = Path(raw).expanduser() | |
| selected_root = repository_root | |
| if ( | |
| not candidate.is_absolute() | |
| and candidate.parts | |
| and candidate.parts[0].casefold() in _ASSET_DIRECTORIES | |
| and configured_asset_root is not None | |
| ): | |
| selected_root = configured_asset_root | |
| resolved = ( | |
| candidate.resolve() | |
| if candidate.is_absolute() | |
| else (selected_root / candidate).resolve() | |
| ) | |
| allowed_roots = [repository_root] | |
| if configured_asset_root is not None: | |
| allowed_roots.append(configured_asset_root) | |
| try: | |
| next(root for root in allowed_roots if resolved.is_relative_to(root)) | |
| except StopIteration as error: | |
| raise CanonicalDataError( | |
| f"canonical path resolves outside configured evaluation roots: {raw}" | |
| ) from error | |
| return os.path.normpath(str(resolved)) | |
| def repository_relative_output_path( | |
| value: str, | |
| root: str | os.PathLike[str], | |
| ) -> str: | |
| """Return a ``./``-prefixed path when an asset is contained by ``root``.""" | |
| raw = str(value).strip() | |
| if not raw or not str(root).strip(): | |
| return raw | |
| candidate = Path(raw).expanduser() | |
| if not candidate.is_absolute(): | |
| return raw | |
| repository_root = Path(root).expanduser().resolve() | |
| resolved = candidate.resolve() | |
| try: | |
| relative = resolved.relative_to(repository_root) | |
| except ValueError: | |
| return raw | |
| return f"./{relative.as_posix()}" | |
| def _is_path_key(value: object) -> bool: | |
| return isinstance(value, str) and bool(_PATH_KEY_RE.search(value.casefold())) | |
| def _resolve_media_entry(value: Any, root: Path, asset_root: Path | None) -> Any: | |
| if isinstance(value, str): | |
| return resolve_repository_path(value, root, asset_root) | |
| if not isinstance(value, Mapping): | |
| return copy.deepcopy(value) | |
| resolved = copy.deepcopy(dict(value)) | |
| for key in _MEDIA_PATH_KEYS: | |
| path = resolved.get(key) | |
| if isinstance(path, str) and path.strip(): | |
| resolved[key] = resolve_repository_path(path, root, asset_root) | |
| return resolved | |
| def _resolve_declared_paths( | |
| value: Any, | |
| root: Path, | |
| asset_root: Path | None, | |
| path_context: bool = False, | |
| ) -> Any: | |
| if isinstance(value, str): | |
| return ( | |
| resolve_repository_path(value, root, asset_root) | |
| if path_context | |
| else value | |
| ) | |
| if isinstance(value, Mapping): | |
| return { | |
| key: _resolve_declared_paths( | |
| item, | |
| root, | |
| asset_root, | |
| path_context=path_context or _is_path_key(key), | |
| ) | |
| for key, item in value.items() | |
| } | |
| if isinstance(value, Sequence) and not isinstance(value, (str, bytes, bytearray)): | |
| return [ | |
| _resolve_declared_paths( | |
| item, | |
| root, | |
| asset_root, | |
| path_context=path_context, | |
| ) | |
| for item in value | |
| ] | |
| return copy.deepcopy(value) | |
| def _media_path(value: Any) -> str: | |
| if isinstance(value, str): | |
| return value | |
| if isinstance(value, Mapping): | |
| for key in _MEDIA_PATH_KEYS: | |
| candidate = value.get(key) | |
| if isinstance(candidate, str) and candidate: | |
| return candidate | |
| return "" | |
| def _declared_path_values(value: Any, path_context: bool = False) -> list[str]: | |
| if isinstance(value, str): | |
| return [value] if path_context else [] | |
| if isinstance(value, Mapping): | |
| paths: list[str] = [] | |
| for key, item in value.items(): | |
| paths.extend( | |
| _declared_path_values( | |
| item, | |
| path_context=path_context or _is_path_key(key), | |
| ) | |
| ) | |
| return paths | |
| if isinstance(value, Sequence) and not isinstance(value, (str, bytes, bytearray)): | |
| paths = [] | |
| for item in value: | |
| paths.extend(_declared_path_values(item, path_context=path_context)) | |
| return paths | |
| return [] | |
| def adapt_canonical_row( | |
| record: Mapping[str, Any], | |
| root: str | os.PathLike[str] | None = None, | |
| asset_root: str | os.PathLike[str] | None = None, | |
| ) -> dict[str, Any]: | |
| """Resolve canonical paths and add non-destructive legacy aliases.""" | |
| if not is_canonical_row(record): | |
| return copy.deepcopy(dict(record)) | |
| repository_root = ( | |
| Path(root).expanduser().resolve() if root is not None else _configured_root() | |
| ) | |
| if repository_root is None: | |
| raise CanonicalDataError( | |
| "canonical rows require ORARL_EVAL_DATA_ROOT or an explicit root" | |
| ) | |
| resolved_asset_root = ( | |
| Path(asset_root).expanduser().resolve() | |
| if asset_root is not None | |
| else _configured_asset_root() | |
| ) | |
| adapted = copy.deepcopy(dict(record)) | |
| for field in ("images", "videos", "subtitles"): | |
| values = adapted.get(field) | |
| if isinstance(values, list): | |
| adapted[field] = [ | |
| _resolve_media_entry(value, repository_root, resolved_asset_root) | |
| for value in values | |
| ] | |
| for field in ("preprocessed", "task_payload", "metadata", "evaluation"): | |
| value = adapted.get(field) | |
| if isinstance(value, Mapping): | |
| adapted[field] = _resolve_declared_paths( | |
| value, | |
| repository_root, | |
| resolved_asset_root, | |
| ) | |
| image_paths = [ | |
| path for value in adapted.get("images", []) if (path := _media_path(value)) | |
| ] | |
| video_paths = [ | |
| path for value in adapted.get("videos", []) if (path := _media_path(value)) | |
| ] | |
| subtitle_paths = [ | |
| path | |
| for value in adapted.get("subtitles", []) | |
| if (path := _media_path(value)) | |
| ] | |
| adapted.setdefault("id", adapted["sample_id"]) | |
| adapted.setdefault("problem_id", adapted["sample_id"]) | |
| adapted.setdefault("question_id", adapted["sample_id"]) | |
| adapted.setdefault("question", adapted["problem"]) | |
| adapted.setdefault("prompt", adapted["problem"]) | |
| adapted.setdefault("ground_truth", adapted["answer"]) | |
| adapted.setdefault("solution", adapted["answer"]) | |
| adapted.setdefault("dataset", adapted["benchmark"]) | |
| adapted.setdefault("options", copy.deepcopy(adapted.get("choices", []))) | |
| adapted.setdefault("image_list", image_paths) | |
| if image_paths: | |
| adapted.setdefault("image", image_paths[0]) | |
| adapted.setdefault("image_path", image_paths[0]) | |
| if video_paths: | |
| adapted.setdefault("video", video_paths[0]) | |
| adapted.setdefault("video_path", video_paths[0]) | |
| if video_paths or image_paths: | |
| adapted.setdefault("path", (video_paths or image_paths)[0]) | |
| if subtitle_paths: | |
| adapted.setdefault("subtitle", subtitle_paths[0]) | |
| adapted.setdefault("subtitle_path", subtitle_paths[0]) | |
| metadata = adapted.get("metadata") | |
| if isinstance(metadata, Mapping): | |
| for key, value in metadata.items(): | |
| adapted.setdefault(str(key), copy.deepcopy(value)) | |
| payload = adapted.get("task_payload") | |
| if isinstance(payload, Mapping): | |
| for key, value in payload.items(): | |
| adapted.setdefault(str(key), copy.deepcopy(value)) | |
| if isinstance(adapted.get("answer"), Mapping): | |
| for key in _GROUND_TRUTH_KEYS: | |
| if key in adapted["answer"]: | |
| adapted.setdefault(key, copy.deepcopy(adapted["answer"][key])) | |
| preprocessed = adapted.get("preprocessed") | |
| if isinstance(preprocessed, Mapping): | |
| for key, value in preprocessed.items(): | |
| adapted.setdefault(str(key), copy.deepcopy(value)) | |
| paths = _declared_path_values(preprocessed) | |
| if paths: | |
| adapted.setdefault("preprocessed_video", paths[0]) | |
| adapted.setdefault("preprocessed_video_path", paths[0]) | |
| if video_paths: | |
| adapted.setdefault("data_type", "video") | |
| elif image_paths: | |
| adapted.setdefault("data_type", "image") | |
| adapted.setdefault("question_type", adapted["problem_type"]) | |
| adapted.setdefault("task_type", adapted["problem_type"]) | |
| return adapted | |
| def load_json_records( | |
| path: str | os.PathLike[str], | |
| *, | |
| root: str | os.PathLike[str] | None = None, | |
| asset_root: str | os.PathLike[str] | None = None, | |
| ) -> list[dict[str, Any]]: | |
| """Read JSON/JSONL and adapt only rows that use the canonical contract.""" | |
| input_path = Path(path) | |
| text = input_path.read_text(encoding="utf-8") | |
| if not text.strip(): | |
| records: list[Any] = [] | |
| else: | |
| try: | |
| payload = json.loads(text) | |
| except json.JSONDecodeError: | |
| records = [json.loads(line) for line in text.splitlines() if line.strip()] | |
| else: | |
| records = payload if isinstance(payload, list) else [payload] | |
| if not all(isinstance(record, Mapping) for record in records): | |
| raise CanonicalDataError(f"{input_path}: every record must be a JSON object") | |
| repository_root = ( | |
| Path(root).expanduser().resolve() | |
| if root is not None | |
| else _infer_root(input_path) | |
| ) | |
| return [ | |
| adapt_canonical_row(record, repository_root, asset_root) | |
| if is_canonical_row(record) | |
| else copy.deepcopy(dict(record)) | |
| for record in records | |
| ] | |
| __all__ = [ | |
| "CanonicalDataError", | |
| "adapt_canonical_row", | |
| "canonical_dataset_record", | |
| "is_canonical_row", | |
| "load_json_records", | |
| "resolve_repository_path", | |
| ] | |