Image-Text-to-Text
Transformers
Safetensors
English
qwen3_5
piko
piko-9b
multimodal
vision-language
hybrid-attention
linear-attention
ocr
document-understanding
conversational
Instructions to use Dexy2/Piko-9b with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Dexy2/Piko-9b with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="Dexy2/Piko-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("Dexy2/Piko-9b") model = AutoModelForMultimodalLM.from_pretrained("Dexy2/Piko-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 Dexy2/Piko-9b with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Dexy2/Piko-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": "Dexy2/Piko-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/Dexy2/Piko-9b
- SGLang
How to use Dexy2/Piko-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 "Dexy2/Piko-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": "Dexy2/Piko-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 "Dexy2/Piko-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": "Dexy2/Piko-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 Dexy2/Piko-9b with Docker Model Runner:
docker model run hf.co/Dexy2/Piko-9b
| #!/usr/bin/env python3 | |
| """Validate the model card before publishing. | |
| Checks the YAML front matter, verifies that every number in a results table is | |
| backed by a file under evaluation/results or benchmarks/results, and refuses | |
| placeholder values. The point is to make it hard to reintroduce the original | |
| release's defect: benchmark numbers measured on a different checkpoint. | |
| python scripts/validate_model_card.py --readme README.md | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import json | |
| import re | |
| import sys | |
| from pathlib import Path | |
| from typing import Any | |
| REQUIRED_METADATA = ["license", "language", "library_name", "pipeline_tag", "base_model", "tags"] | |
| REQUIRED_SECTIONS = [ | |
| "Model summary", | |
| "Relationship to the base model", | |
| "Intended uses", | |
| "Out-of-scope uses", | |
| "Architecture", | |
| "Training", | |
| "Evaluation", | |
| "Benchmark results", | |
| "Hardware requirements", | |
| "Quantization", | |
| "Limitations", | |
| "Reproducibility", | |
| "Citation", | |
| "License", | |
| ] | |
| PLACEHOLDERS = [ | |
| "TODO", | |
| "FIXME", | |
| "XXX", | |
| "[More Information Needed]", | |
| "lorem ipsum", | |
| "TBD", | |
| ] | |
| # Anything that looks like a leaked local path. | |
| PATH_PATTERNS = [ | |
| re.compile(r"/mnt/[a-z]/"), | |
| re.compile(r"/home/[A-Za-z0-9_.-]+/"), | |
| re.compile(r"[Cc]:[\\/]+Users[\\/]+"), | |
| ] | |
| SECRET_PATTERNS = [ | |
| re.compile(r"\bhf_[A-Za-z0-9]{34,}\b"), | |
| re.compile(r"\bsk-[A-Za-z0-9]{20,}\b"), | |
| re.compile(r"\bAKIA[0-9A-Z]{16}\b"), | |
| ] | |
| ALLOWED_STATUSES = { | |
| "not run", | |
| "unavailable", | |
| "could not verify", | |
| "not tested", | |
| "n/a", | |
| "—", | |
| "-", | |
| } | |
| def parse_front_matter(text: str) -> tuple[dict[str, Any] | None, str]: | |
| if not text.startswith("---"): | |
| return None, text | |
| end = text.find("\n---", 3) | |
| if end == -1: | |
| return None, text | |
| block = text[3:end] | |
| body = text[end + 4 :] | |
| try: | |
| import yaml | |
| return yaml.safe_load(block), body | |
| except ImportError: | |
| # Fall back to a shallow key scan so the check still works without pyyaml. | |
| keys = dict(re.findall(r"^([a-z_]+):", block, re.MULTILINE)) | |
| return {k: True for k in keys}, body | |
| def collect_measured_numbers(results_dirs: list[Path]) -> set[str]: | |
| """Every percentage and ratio that appears in a committed result file.""" | |
| found: set[str] = set() | |
| for directory in results_dirs: | |
| for path in directory.rglob("*.json"): | |
| try: | |
| data = json.loads(path.read_text(encoding="utf-8")) | |
| except (json.JSONDecodeError, OSError): | |
| continue | |
| _walk(data, found) | |
| return found | |
| def _walk(node: Any, found: set[str]) -> None: | |
| if isinstance(node, dict): | |
| for key, value in node.items(): | |
| if key in ("accuracy", "score") and isinstance(value, (int, float)): | |
| found.add(f"{value * 100:.1f}") | |
| found.add(f"{value * 100:.0f}") | |
| if key in ("passed", "total") and isinstance(value, int): | |
| found.add(str(value)) | |
| _walk(value, found) | |
| elif isinstance(node, list): | |
| for item in node: | |
| _walk(item, found) | |
| def check_tables(body: str, measured: set[str]) -> list[str]: | |
| """Every percentage in a results table must be measured or an allowed status.""" | |
| problems: list[str] = [] | |
| in_results = False | |
| for line in body.splitlines(): | |
| lowered = line.lower() | |
| if lowered.startswith("#"): | |
| in_results = "benchmark" in lowered or "result" in lowered | |
| continue | |
| if not in_results or not line.strip().startswith("|"): | |
| continue | |
| cells = [c.strip() for c in line.strip().strip("|").split("|")] | |
| for cell in cells: | |
| stripped = cell.replace("**", "").strip() | |
| if stripped.lower() in ALLOWED_STATUSES or not stripped: | |
| continue | |
| match = re.fullmatch(r"([+-]?\d+(?:\.\d+)?)\s*%", stripped) | |
| if not match: | |
| continue | |
| value = match.group(1).lstrip("+-") | |
| if value.startswith("0.") or value in ("0",): | |
| continue | |
| normalised = {f"{float(value):.1f}", f"{float(value):.0f}"} | |
| if not (normalised & measured): | |
| problems.append( | |
| f" {stripped} appears in a results table but is not in any " | |
| f"committed result file" | |
| ) | |
| return problems | |
| def main() -> None: | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument("--readme", type=Path, default=Path("README.md")) | |
| parser.add_argument( | |
| "--results", | |
| type=Path, | |
| nargs="*", | |
| default=[Path("evaluation/results"), Path("benchmarks/results")], | |
| ) | |
| parser.add_argument( | |
| "--strict-numbers", | |
| action="store_true", | |
| help="Fail on unbacked table numbers instead of warning.", | |
| ) | |
| args = parser.parse_args() | |
| if not args.readme.is_file(): | |
| sys.exit(f"Model card not found: {args.readme}") | |
| text = args.readme.read_text(encoding="utf-8") | |
| metadata, body = parse_front_matter(text) | |
| errors: list[str] = [] | |
| warnings: list[str] = [] | |
| if metadata is None: | |
| errors.append("No YAML front matter found.") | |
| else: | |
| for key in REQUIRED_METADATA: | |
| if key not in metadata: | |
| errors.append(f"Front matter is missing required key: {key}") | |
| license_is_apache = str(metadata.get("license", "")).lower() == "apache-2.0" | |
| if license_is_apache and not Path("NOTICE").is_file(): | |
| errors.append( | |
| "License is apache-2.0 but no NOTICE file exists. Upstream MIT " | |
| "attribution must be preserved." | |
| ) | |
| for section in REQUIRED_SECTIONS: | |
| if section.lower() not in body.lower(): | |
| warnings.append(f"No section mentioning: {section}") | |
| for placeholder in PLACEHOLDERS: | |
| if placeholder.lower() in body.lower(): | |
| errors.append(f"Placeholder text present: {placeholder!r}") | |
| for pattern in PATH_PATTERNS: | |
| for hit in set(pattern.findall(text)): | |
| errors.append(f"Local path leaked in model card: {hit!r}") | |
| for pattern in SECRET_PATTERNS: | |
| if pattern.search(text): | |
| errors.append("Possible secret detected in model card.") | |
| existing = [d for d in args.results if d.is_dir()] | |
| if existing: | |
| measured = collect_measured_numbers(existing) | |
| table_problems = check_tables(body, measured) | |
| (errors if args.strict_numbers else warnings).extend(table_problems) | |
| else: | |
| warnings.append("No result directories found; skipped number verification.") | |
| for link in re.findall(r"\]\((?!https?://|#)([^)]+)\)", body): | |
| target = (args.readme.parent / link.split("#")[0]).resolve() | |
| if not target.exists(): | |
| errors.append(f"Broken relative link: {link}") | |
| for warning in warnings: | |
| print(f"WARN {warning}") | |
| for error in errors: | |
| print(f"ERROR {error}") | |
| print(f"\n{len(errors)} error(s), {len(warnings)} warning(s) in {args.readme}") | |
| sys.exit(1 if errors else 0) | |
| if __name__ == "__main__": | |
| main() | |