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-4B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use OraRL/Video-ORA-4B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="OraRL/Video-ORA-4B") 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-4B") model = AutoModelForMultimodalLM.from_pretrained("OraRL/Video-ORA-4B", 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-4B with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "OraRL/Video-ORA-4B" # 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-4B", "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-4B
- SGLang
How to use OraRL/Video-ORA-4B 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-4B" \ --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-4B", "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-4B" \ --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-4B", "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-4B with Docker Model Runner:
docker model run hf.co/OraRL/Video-ORA-4B
| # Copyright 2024 Bytedance Ltd. and/or its affiliates | |
| # | |
| # 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. | |
| """ | |
| the class of WorkerGroup | |
| """ | |
| import logging | |
| import signal | |
| import threading | |
| import time | |
| from typing import Any, Callable, Optional | |
| from .decorator import MAGIC_ATTR, Dispatch, get_predefined_dispatch_fn, get_predefined_execute_fn | |
| class ResourcePool: | |
| """The resource pool with meta info such as world size.""" | |
| def __init__( | |
| self, process_on_nodes: Optional[Any] = None, max_colocate_count: int = 10, n_gpus_per_node: int = 8 | |
| ) -> None: | |
| if process_on_nodes is None: | |
| process_on_nodes = [] | |
| self._store = process_on_nodes | |
| self.max_colocate_count = max_colocate_count | |
| self.n_gpus_per_node = n_gpus_per_node # this is left for future huawei GPU that contains 16 GPUs per node | |
| def add_node(self, process_count): | |
| self._store.append(process_count) | |
| def world_size(self): | |
| return sum(self._store) | |
| def __call__(self) -> Any: | |
| return self._store | |
| def store(self): | |
| return self._store | |
| def local_world_size_list(self) -> list[int]: | |
| nested_local_world_size_list = [ | |
| [local_world_size for _ in range(local_world_size)] for local_world_size in self._store | |
| ] | |
| return [item for row in nested_local_world_size_list for item in row] | |
| def local_rank_list(self) -> list[int]: | |
| nested_local_rank_list = [[i for i in range(local_world_size)] for local_world_size in self._store] # noqa: C416 | |
| return [item for row in nested_local_rank_list for item in row] | |
| class ClassWithInitArgs: | |
| """ | |
| This class stores a class constructor and the args/kwargs to construct the class. | |
| It is used to instantiate the remote class. | |
| """ | |
| def __init__(self, cls, *args, **kwargs) -> None: | |
| self.cls = cls | |
| self.args = args | |
| self.kwargs = kwargs | |
| def __call__(self) -> Any: | |
| return self.cls(*self.args, **self.kwargs) | |
| def check_workers_alive(workers: list, is_alive: Callable, gap_time: float = 1) -> None: | |
| while True: | |
| for worker in workers: | |
| if not is_alive(worker): | |
| logging.warning(f"Worker {worker} is not alive, sending signal to main thread") | |
| signal.raise_signal(signal.SIGABRT) | |
| time.sleep(gap_time) | |
| class WorkerGroup: | |
| """A group of workers""" | |
| def __init__(self, resource_pool: ResourcePool, **kwargs) -> None: | |
| self._is_init_with_detached_workers = True if resource_pool is None else False | |
| if resource_pool is not None: | |
| # handle the case when WorkGroup is attached to an existing one | |
| self._procecss_dispatch_config = resource_pool() | |
| else: | |
| self._procecss_dispatch_config = None | |
| self._workers = [] | |
| self._worker_names = [] | |
| self._master_addr = None | |
| self._master_port = None | |
| self._checker_thread: threading.Thread = None | |
| def _is_worker_alive(self, worker): | |
| raise NotImplementedError("WorkerGroup._is_worker_alive called, should be implemented in derived class.") | |
| def _block_until_all_workers_alive(self) -> None: | |
| while True: | |
| all_state = [self._is_worker_alive(worker) for worker in self._workers] | |
| if False in all_state: | |
| time.sleep(1) | |
| else: | |
| break | |
| def start_worker_aliveness_check(self, every_n_seconds=1) -> None: | |
| # before starting checking worker aliveness, make sure all workers are already alive | |
| self._block_until_all_workers_alive() | |
| self._checker_thread = threading.Thread( | |
| target=check_workers_alive, args=(self._workers, self._is_worker_alive, every_n_seconds) | |
| ) | |
| self._checker_thread.start() | |
| def world_size(self): | |
| return len(self._workers) | |
| def _bind_worker_method(self, user_defined_cls, func_generator): | |
| """ | |
| Bind the worker method to the WorkerGroup | |
| """ | |
| for method_name in dir(user_defined_cls): | |
| try: | |
| method = getattr(user_defined_cls, method_name) | |
| assert callable(method), f"{method_name} in {user_defined_cls} is not callable" | |
| except Exception: | |
| # if it is a property, it will fail because Class doesn't have instance property | |
| continue | |
| if hasattr(method, MAGIC_ATTR): | |
| # this method is decorated by register | |
| attribute = getattr(method, MAGIC_ATTR) | |
| assert isinstance(attribute, dict), f"attribute must be a dictionary. Got {type(attribute)}" | |
| assert "dispatch_mode" in attribute, "attribute must contain dispatch_mode in its key" | |
| dispatch_mode = attribute["dispatch_mode"] | |
| execute_mode = attribute["execute_mode"] | |
| blocking = attribute["blocking"] | |
| # get dispatch fn | |
| if isinstance(dispatch_mode, Dispatch): | |
| # get default dispatch fn | |
| fn = get_predefined_dispatch_fn(dispatch_mode=dispatch_mode) | |
| dispatch_fn = fn["dispatch_fn"] | |
| collect_fn = fn["collect_fn"] | |
| else: | |
| assert isinstance(dispatch_mode, dict) | |
| assert "dispatch_fn" in dispatch_mode | |
| assert "collect_fn" in dispatch_mode | |
| dispatch_fn = dispatch_mode["dispatch_fn"] | |
| collect_fn = dispatch_mode["collect_fn"] | |
| # get execute_fn_name | |
| execute_mode = get_predefined_execute_fn(execute_mode=execute_mode) | |
| wg_execute_fn_name = execute_mode["execute_fn_name"] | |
| # get execute_fn from string | |
| try: | |
| execute_fn = getattr(self, wg_execute_fn_name) | |
| assert callable(execute_fn), "execute_fn must be callable" | |
| except Exception: | |
| print(f"execute_fn {wg_execute_fn_name} is invalid") | |
| raise | |
| # bind a new method to the RayWorkerGroup | |
| func = func_generator( | |
| self, | |
| method_name, | |
| dispatch_fn=dispatch_fn, | |
| collect_fn=collect_fn, | |
| execute_fn=execute_fn, | |
| blocking=blocking, | |
| ) | |
| try: | |
| setattr(self, method_name, func) | |
| except Exception: | |
| raise ValueError(f"Fail to set method_name {method_name}") | |