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
| # Copyright 2024 Bytedance Ltd. and/or its affiliates | |
| # Copyright 2026 The OraRL Authors | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| """Pre-selection references and post-selection moment correction. | |
| The projection and RMS-downscale construction is derived from the Apache-2.0 | |
| EasyR1/verl implementation. | |
| """ | |
| from __future__ import annotations | |
| from typing import Any | |
| import torch | |
| from ._utils import ( | |
| batch_reward_tokens, | |
| boolean_mask, | |
| broadcast_sequence_values, | |
| group_rows, | |
| sample_std, | |
| sequence_advantages, | |
| sequence_rewards, | |
| validate_floating_tensor, | |
| ) | |
| from .config import CorrectionConfig, PostSelectionReference | |
| def _resolved_config( | |
| config: CorrectionConfig | None, | |
| rms_match: bool | None, | |
| rms_min_scale: float | None, | |
| sigma_policy_floor: float | None, | |
| eps: float | None, | |
| ) -> CorrectionConfig: | |
| base = CorrectionConfig() if config is None else config | |
| return CorrectionConfig( | |
| rms_match=base.rms_match if rms_match is None else rms_match, | |
| rms_min_scale=(base.rms_min_scale if rms_min_scale is None else rms_min_scale), | |
| sigma_policy_floor=( | |
| base.sigma_policy_floor if sigma_policy_floor is None else sigma_policy_floor | |
| ), | |
| eps=base.eps if eps is None else eps, | |
| ) | |
| def capture_pre_selection_references( | |
| data: Any, | |
| *, | |
| reward_key: str | None = None, | |
| group_key: str = "uid", | |
| oracle_key: str = "is_oracle_row", | |
| ) -> dict[Any, PostSelectionReference]: | |
| """Capture policy RMS and reward spread before rows are selected.""" | |
| required = ("advantages", "response_mask") | |
| missing = [key for key in required if key not in data.batch] | |
| if missing: | |
| raise ValueError(f"reference capture is missing batch keys: {missing}.") | |
| if group_key not in data.non_tensor_batch: | |
| raise ValueError(f"reference capture requires {group_key!r}.") | |
| if oracle_key not in data.non_tensor_batch: | |
| raise ValueError(f"reference capture requires {oracle_key!r}.") | |
| advantages = data.batch["advantages"] | |
| response_mask = data.batch["response_mask"] | |
| sequence_values = sequence_advantages(advantages, response_mask).float() | |
| reward_tokens = batch_reward_tokens(data, reward_key) | |
| reward_values, _ = sequence_rewards(reward_tokens, response_mask) | |
| reward_values = reward_values.to( | |
| device=sequence_values.device, | |
| dtype=torch.float32, | |
| ) | |
| grouped = group_rows( | |
| data.non_tensor_batch[group_key], | |
| sequence_values.numel(), | |
| ) | |
| oracle = boolean_mask( | |
| data.non_tensor_batch[oracle_key], | |
| sequence_values.numel(), | |
| device=sequence_values.device, | |
| name=oracle_key, | |
| ) | |
| references: dict[Any, PostSelectionReference] = {} | |
| for group_id, rows in grouped.items(): | |
| row_index = torch.tensor( | |
| rows, | |
| dtype=torch.long, | |
| device=sequence_values.device, | |
| ) | |
| group_oracle = oracle.index_select(0, row_index) | |
| if int(group_oracle.sum().item()) != 1: | |
| raise ValueError(f"group {group_id!r} requires exactly one oracle row.") | |
| policy = ~group_oracle | |
| policy_advantages = sequence_values.index_select(0, row_index)[policy] | |
| policy_rewards = reward_values.index_select(0, row_index)[policy] | |
| references[group_id] = PostSelectionReference( | |
| policy_rms=float(torch.sqrt(torch.mean(policy_advantages.square())).item()), | |
| sigma_policy=float(sample_std(policy_rewards).item()), | |
| policy_rows=int(policy.sum().item()), | |
| ) | |
| return references | |
| build_pre_selection_references = capture_pre_selection_references | |
| def correct_post_selection_group( | |
| active_advantages: torch.Tensor, | |
| is_oracle_row: torch.Tensor, | |
| *, | |
| reference: PostSelectionReference, | |
| config: CorrectionConfig | None = None, | |
| rms_match: bool | None = None, | |
| rms_min_scale: float | None = None, | |
| sigma_policy_floor: float | None = None, | |
| eps: float | None = None, | |
| ) -> tuple[torch.Tensor, dict[str, float]]: | |
| """Zero-center one selected group and optionally downscale its RMS.""" | |
| cfg = _resolved_config( | |
| config, | |
| rms_match, | |
| rms_min_scale, | |
| sigma_policy_floor, | |
| eps, | |
| ) | |
| validate_floating_tensor("active_advantages", active_advantages) | |
| if active_advantages.ndim != 1 or active_advantages.numel() == 0: | |
| raise ValueError("active_advantages must be a non-empty vector.") | |
| oracle = boolean_mask( | |
| is_oracle_row, | |
| active_advantages.numel(), | |
| device=active_advantages.device, | |
| name="is_oracle_row", | |
| ) | |
| oracle_rows = int(oracle.sum().item()) | |
| if oracle_rows != 1: | |
| raise ValueError(f"post-selection correction requires one oracle row, got {oracle_rows}.") | |
| policy = ~oracle | |
| policy_rows = int(policy.sum().item()) | |
| if policy_rows < 1: | |
| raise ValueError("post-selection correction requires a policy row.") | |
| before = active_advantages.detach() | |
| mean_before = before.mean() | |
| rms_before = torch.sqrt(torch.mean(before.square())) | |
| corrected = before - mean_before | |
| projected = False | |
| if float(corrected[oracle].item()) < 0.0: | |
| correction = -corrected[oracle].squeeze(0) | |
| corrected[oracle] = 0.0 | |
| corrected[policy] -= correction / policy_rows | |
| projected = True | |
| small_sigma_fallback = reference.sigma_policy < cfg.sigma_policy_floor | |
| rms_scale = corrected.new_ones(()) | |
| if cfg.rms_match and not small_sigma_fallback: | |
| active_rms = torch.sqrt(torch.mean(corrected.square())) | |
| if float(active_rms.item()) > cfg.eps: | |
| target = corrected.new_tensor(reference.policy_rms) | |
| rms_scale = torch.clamp( | |
| target / (active_rms + cfg.eps), | |
| min=cfg.rms_min_scale, | |
| max=1.0, | |
| ) | |
| corrected = corrected * rms_scale | |
| mean_after = corrected.mean() | |
| rms_after = torch.sqrt(torch.mean(corrected.square())) | |
| metrics = { | |
| "active_mean_before": float(mean_before.item()), | |
| "active_rms_before": float(rms_before.item()), | |
| "policy_rms_reference": reference.policy_rms, | |
| "rms_scale": float(rms_scale.item()), | |
| "oracle_sign_projection": float(projected), | |
| "small_sigma_fallback": float(small_sigma_fallback), | |
| "active_mean_after": float(mean_after.item()), | |
| "active_rms_after": float(rms_after.item()), | |
| "oracle_advantage_after": float(corrected[oracle].item()), | |
| "active_rows": float(corrected.numel()), | |
| "active_policy_rows": float(policy_rows), | |
| } | |
| return corrected, metrics | |
| balance_post_selection_group = correct_post_selection_group | |
| def apply_post_selection_correction( | |
| data: Any, | |
| references: dict[Any, PostSelectionReference], | |
| *, | |
| config: CorrectionConfig | None = None, | |
| rms_match: bool | None = None, | |
| rms_min_scale: float | None = None, | |
| sigma_policy_floor: float | None = None, | |
| eps: float | None = None, | |
| group_key: str = "uid", | |
| oracle_key: str = "is_oracle_row", | |
| ) -> dict[str, float]: | |
| """Apply post-selection correction to every DataProto-like group.""" | |
| cfg = _resolved_config( | |
| config, | |
| rms_match, | |
| rms_min_scale, | |
| sigma_policy_floor, | |
| eps, | |
| ) | |
| if "advantages" not in data.batch or "response_mask" not in data.batch: | |
| raise ValueError("correction requires advantages and response_mask.") | |
| advantages = data.batch["advantages"] | |
| response_mask = data.batch["response_mask"] | |
| sequence_values = sequence_advantages(advantages, response_mask).float() | |
| grouped = group_rows( | |
| data.non_tensor_batch[group_key], | |
| sequence_values.numel(), | |
| ) | |
| oracle = boolean_mask( | |
| data.non_tensor_batch[oracle_key], | |
| sequence_values.numel(), | |
| device=sequence_values.device, | |
| name=oracle_key, | |
| ) | |
| updated = advantages.detach().clone() | |
| collected: dict[str, list[float]] = {} | |
| for group_id, rows in grouped.items(): | |
| if group_id not in references: | |
| raise ValueError(f"missing pre-selection reference for {group_id!r}.") | |
| row_index = torch.tensor( | |
| rows, | |
| dtype=torch.long, | |
| device=sequence_values.device, | |
| ) | |
| corrected, group_metrics = correct_post_selection_group( | |
| sequence_values.index_select(0, row_index), | |
| oracle.index_select(0, row_index), | |
| reference=references[group_id], | |
| config=cfg, | |
| ) | |
| updated.index_copy_( | |
| 0, | |
| row_index.to(device=updated.device), | |
| broadcast_sequence_values( | |
| corrected.to(device=updated.device), | |
| response_mask.index_select( | |
| 0, | |
| row_index.to(device=response_mask.device), | |
| ), | |
| dtype=advantages.dtype, | |
| ), | |
| ) | |
| for key, value in group_metrics.items(): | |
| collected.setdefault(key, []).append(value) | |
| data.batch["advantages"] = updated | |
| metrics: dict[str, float] = { | |
| "orarl/post_selection_groups": float(len(grouped)), | |
| "orarl/post_selection_rms_match": float(cfg.rms_match), | |
| } | |
| for key, values in collected.items(): | |
| metrics[f"orarl/post_selection_{key}"] = sum(values) / len(values) | |
| return metrics | |
| apply_post_selection_advantage_correction = apply_post_selection_correction | |