Image-Text-to-Text
Transformers
English
vision-language-model
vlm
surveillance
iot
gemma
vl-jepa
multimodal
object-detection
video-analytics
Instructions to use hardiksa/arcisvlm with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use hardiksa/arcisvlm with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="hardiksa/arcisvlm")# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("hardiksa/arcisvlm", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use hardiksa/arcisvlm with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "hardiksa/arcisvlm" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "hardiksa/arcisvlm", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/hardiksa/arcisvlm
- SGLang
How to use hardiksa/arcisvlm 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 "hardiksa/arcisvlm" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "hardiksa/arcisvlm", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'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 "hardiksa/arcisvlm" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "hardiksa/arcisvlm", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use hardiksa/arcisvlm with Docker Model Runner:
docker model run hf.co/hardiksa/arcisvlm
| #!/usr/bin/env python3 | |
| """ | |
| Benchmark ArcisVLM vs Qwen3-VL on real camera frames. | |
| Captures frames from live cameras, runs the SAME questions through both models, | |
| and produces a side-by-side comparison report. | |
| Qwen3-VL-8B is loaded via transformers (HuggingFace). | |
| ArcisVLM uses the local API. | |
| Usage: | |
| # Run on GPU instance with both models | |
| python3 scripts/benchmark_vs_qwen.py \ | |
| --arcisvlm-api http://localhost:8000 \ | |
| --qwen-model Qwen/Qwen3-VL-8B-Instruct \ | |
| --camera-frames data/test_frames/ \ | |
| --output benchmark_results.json | |
| # Or capture frames from live cameras first | |
| python3 scripts/benchmark_vs_qwen.py \ | |
| --arcisvlm-api http://localhost:8000 \ | |
| --capture-from "rtsp://admin:@ATPL-900064-AIPTZ.torqueverse.dev:64/ch0_0.264" \ | |
| --qwen-model Qwen/Qwen3-VL-8B-Instruct | |
| """ | |
| import argparse | |
| import base64 | |
| import json | |
| import os | |
| import sys | |
| import time | |
| from pathlib import Path | |
| # Test questions covering all 8 agent types | |
| BENCHMARK_QUESTIONS = [ | |
| # VQA | |
| {"question": "What is happening in this image?", "agent": "vqa", "category": "general"}, | |
| {"question": "Is there a person in this image?", "agent": "vqa", "category": "yes_no"}, | |
| {"question": "What color is the main vehicle?", "agent": "vqa", "category": "attribute"}, | |
| # Detect | |
| {"question": "List all objects visible in this scene.", "agent": "detect", "category": "detection"}, | |
| {"question": "What types of vehicles are present?", "agent": "detect", "category": "vehicle_detect"}, | |
| # Caption | |
| {"question": "Describe this image in detail.", "agent": "caption", "category": "description"}, | |
| {"question": "Write a detailed caption for this surveillance camera image.", "agent": "caption", "category": "surveillance_caption"}, | |
| # Count | |
| {"question": "How many people are in this image?", "agent": "count", "category": "count_people"}, | |
| {"question": "How many vehicles can you see?", "agent": "count", "category": "count_vehicles"}, | |
| # OCR | |
| {"question": "What text or signs are visible in this image?", "agent": "ocr", "category": "text_reading"}, | |
| # Alert | |
| {"question": "Is there any suspicious or unusual activity in this scene?", "agent": "alert", "category": "anomaly"}, | |
| {"question": "Are there any security concerns visible?", "agent": "alert", "category": "security"}, | |
| # Reason | |
| {"question": "Analyze this scene and describe what is happening, including any potential concerns.", "agent": "reason", "category": "analysis"}, | |
| # Track (single frame — limited, but tests spatial understanding) | |
| {"question": "Describe the positions and movements of people in this scene.", "agent": "track", "category": "spatial"}, | |
| ] | |
| def capture_frames(camera_urls: list[str], output_dir: str, n_frames: int = 3): | |
| """Capture frames from live cameras.""" | |
| import cv2 | |
| os.makedirs(output_dir, exist_ok=True) | |
| frames = [] | |
| for url in camera_urls: | |
| cam_id = url.split("/")[-1].split(".")[0][:20] | |
| print(f" Capturing from {cam_id}...") | |
| cap = cv2.VideoCapture(url, cv2.CAP_FFMPEG) | |
| if not cap.isOpened(): | |
| print(f" FAILED to open {url}") | |
| continue | |
| for i in range(n_frames): | |
| ret, frame = cap.read() | |
| if ret: | |
| path = os.path.join(output_dir, f"{cam_id}_frame{i}.jpg") | |
| cv2.imwrite(path, frame) | |
| frames.append(path) | |
| print(f" Saved: {path}") | |
| time.sleep(1) | |
| cap.release() | |
| return frames | |
| def query_arcisvlm(api_url: str, image_path: str, question: str, task_type: str) -> dict: | |
| """Query ArcisVLM API with an image.""" | |
| import requests | |
| with open(image_path, "rb") as f: | |
| img_b64 = base64.b64encode(f.read()).decode() | |
| try: | |
| resp = requests.post( | |
| f"{api_url}/api/v1/query", | |
| json={ | |
| "question": question, | |
| "task_type": task_type, | |
| "image_base64": img_b64, | |
| }, | |
| timeout=120, | |
| ) | |
| if resp.ok: | |
| data = resp.json() | |
| return { | |
| "answer": data.get("answer", ""), | |
| "time_ms": data.get("processing_time_ms", 0), | |
| "expert": data.get("expert_used", ""), | |
| "output_type": data.get("output_type", "text"), | |
| } | |
| except Exception as e: | |
| return {"answer": f"ERROR: {e}", "time_ms": 0, "expert": "", "output_type": "error"} | |
| return {"answer": "API error", "time_ms": 0} | |
| def query_qwen(model, processor, image_path: str, question: str, device: str = "cuda") -> dict: | |
| """Query Qwen3-VL with an image.""" | |
| from PIL import Image | |
| import torch | |
| start = time.time() | |
| try: | |
| image = Image.open(image_path).convert("RGB") | |
| messages = [ | |
| {"role": "user", "content": [ | |
| {"type": "image", "image": image}, | |
| {"type": "text", "text": question}, | |
| ]} | |
| ] | |
| text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True) | |
| inputs = processor(text=[text], images=[image], return_tensors="pt", padding=True).to(device) | |
| with torch.no_grad(): | |
| generated = model.generate(**inputs, max_new_tokens=256) | |
| output = processor.batch_decode(generated[:, inputs.input_ids.shape[1]:], skip_special_tokens=True)[0] | |
| elapsed = (time.time() - start) * 1000 | |
| return {"answer": output.strip(), "time_ms": elapsed} | |
| except Exception as e: | |
| return {"answer": f"ERROR: {e}", "time_ms": (time.time() - start) * 1000} | |
| def run_benchmark(arcisvlm_api: str, qwen_model_name: str, frame_paths: list[str], | |
| device: str = "cuda", output_path: str = "benchmark_results.json"): | |
| """Run side-by-side benchmark.""" | |
| print("=" * 80) | |
| print(" ArcisVLM vs Qwen3-VL Benchmark") | |
| print("=" * 80) | |
| # Load Qwen model | |
| print(f"\nLoading Qwen model: {qwen_model_name}...") | |
| from transformers import Qwen2VLForConditionalGeneration, AutoProcessor | |
| import torch | |
| qwen_processor = AutoProcessor.from_pretrained(qwen_model_name) | |
| qwen_model = Qwen2VLForConditionalGeneration.from_pretrained( | |
| qwen_model_name, | |
| torch_dtype=torch.bfloat16, | |
| device_map="auto", | |
| ) | |
| print(f" Qwen loaded: {sum(p.numel() for p in qwen_model.parameters()):,} params") | |
| results = [] | |
| for frame_idx, frame_path in enumerate(frame_paths[:5]): # Max 5 frames | |
| print(f"\n{'='*60}") | |
| print(f" Frame {frame_idx + 1}: {os.path.basename(frame_path)}") | |
| print(f"{'='*60}") | |
| for q in BENCHMARK_QUESTIONS: | |
| question = q["question"] | |
| agent = q["agent"] | |
| category = q["category"] | |
| print(f"\n Q [{agent}]: {question[:60]}...") | |
| # ArcisVLM | |
| arc_result = query_arcisvlm(arcisvlm_api, frame_path, question, agent) | |
| print(f" ArcisVLM: {arc_result['answer'][:100]} [{arc_result['time_ms']:.0f}ms]") | |
| # Qwen | |
| qwen_result = query_qwen(qwen_model, qwen_processor, frame_path, question, device) | |
| print(f" Qwen3-VL: {qwen_result['answer'][:100]} [{qwen_result['time_ms']:.0f}ms]") | |
| results.append({ | |
| "frame": os.path.basename(frame_path), | |
| "question": question, | |
| "agent": agent, | |
| "category": category, | |
| "arcisvlm_answer": arc_result["answer"], | |
| "arcisvlm_time_ms": arc_result["time_ms"], | |
| "qwen_answer": qwen_result["answer"], | |
| "qwen_time_ms": qwen_result["time_ms"], | |
| }) | |
| # Summary | |
| print(f"\n{'='*80}") | |
| print(" SUMMARY") | |
| print(f"{'='*80}") | |
| arc_avg_time = sum(r["arcisvlm_time_ms"] for r in results) / max(len(results), 1) | |
| qwen_avg_time = sum(r["qwen_time_ms"] for r in results) / max(len(results), 1) | |
| print(f" Total questions: {len(results)}") | |
| print(f" ArcisVLM avg time: {arc_avg_time:.0f}ms") | |
| print(f" Qwen3-VL avg time: {qwen_avg_time:.0f}ms") | |
| # Save | |
| with open(output_path, "w") as f: | |
| json.dump({ | |
| "timestamp": time.strftime("%Y-%m-%d %H:%M:%S UTC", time.gmtime()), | |
| "arcisvlm_api": arcisvlm_api, | |
| "qwen_model": qwen_model_name, | |
| "total_questions": len(results), | |
| "arcisvlm_avg_time_ms": arc_avg_time, | |
| "qwen_avg_time_ms": qwen_avg_time, | |
| "results": results, | |
| }, f, indent=2) | |
| print(f"\n Results saved to: {output_path}") | |
| if __name__ == "__main__": | |
| parser = argparse.ArgumentParser(description="ArcisVLM vs Qwen3-VL Benchmark") | |
| parser.add_argument("--arcisvlm-api", default="http://localhost:8000") | |
| parser.add_argument("--qwen-model", default="Qwen/Qwen3-VL-8B-Instruct") | |
| parser.add_argument("--camera-frames", default="data/test_frames", | |
| help="Directory with test frame images") | |
| parser.add_argument("--capture-from", nargs="*", default=None, | |
| help="Camera URLs to capture frames from") | |
| parser.add_argument("--device", default="cuda") | |
| parser.add_argument("--output", default="benchmark_results.json") | |
| args = parser.parse_args() | |
| # Capture frames if requested | |
| if args.capture_from: | |
| print("Capturing frames from cameras...") | |
| frames = capture_frames(args.capture_from, args.camera_frames) | |
| else: | |
| frames = sorted(Path(args.camera_frames).glob("*.jpg")) | |
| if not frames: | |
| print(f"No frames found in {args.camera_frames}. Use --capture-from to capture.") | |
| sys.exit(1) | |
| frames = [str(f) for f in frames] | |
| print(f"Using {len(frames)} test frames") | |
| run_benchmark(args.arcisvlm_api, args.qwen_model, frames, args.device, args.output) | |