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 | |
| """Collect machine-readable facts about the Piko-9b checkpoint. | |
| Everything reported here is read from files. Nothing is inferred, and nothing | |
| is filled in from the model card. | |
| Usage | |
| ----- | |
| python scripts/audit_repository.py --model <path> --output reports/repository_audit.json | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import hashlib | |
| import json | |
| import re | |
| from pathlib import Path | |
| from typing import Any | |
| from safetensors import safe_open | |
| # Patterns that must never appear in a published repository. | |
| SECRET_PATTERNS = { | |
| "hf_token": re.compile(r"\bhf_[A-Za-z0-9]{34,}\b"), | |
| "openai_key": re.compile(r"\bsk-[A-Za-z0-9]{20,}\b"), | |
| "aws_access_key": re.compile(r"\bAKIA[0-9A-Z]{16}\b"), | |
| "private_key_block": re.compile(r"-----BEGIN (?:RSA |OPENSSH |EC )?PRIVATE KEY-----"), | |
| "generic_bearer": re.compile(r"\bBearer\s+[A-Za-z0-9\-._~+/]{24,}"), | |
| } | |
| # Absolute paths that leak the author's machine layout. | |
| PATH_PATTERNS = { | |
| "wsl_mount": re.compile(r"/mnt/[a-z]/"), | |
| "windows_drive": re.compile(r"\b[A-Z]:\\\\?"), | |
| "unix_home": re.compile(r"/home/[A-Za-z0-9_.-]+/"), | |
| "windows_users": re.compile(r"[Cc]:[\\/]+Users[\\/]+"), | |
| } | |
| TEXT_SUFFIXES = {".json", ".md", ".txt", ".jinja", ".yaml", ".yml", ".py", ".cfg", ".toml"} | |
| def sha256_file(path: Path, limit: int | None = None) -> str: | |
| digest = hashlib.sha256() | |
| with path.open("rb") as handle: | |
| read = 0 | |
| while chunk := handle.read(1 << 20): | |
| digest.update(chunk) | |
| read += len(chunk) | |
| if limit is not None and read >= limit: | |
| break | |
| return digest.hexdigest() | |
| def safetensors_header(path: Path) -> dict[str, Any]: | |
| """Read the JSON header of a safetensors file without loading tensors.""" | |
| with path.open("rb") as handle: | |
| length = int.from_bytes(handle.read(8), "little") | |
| header = json.loads(handle.read(length)) | |
| metadata = header.pop("__metadata__", {}) | |
| dtypes: dict[str, int] = {} | |
| parameters = 0 | |
| for entry in header.values(): | |
| dtypes[entry["dtype"]] = dtypes.get(entry["dtype"], 0) + 1 | |
| count = 1 | |
| for dimension in entry["shape"]: | |
| count *= dimension | |
| parameters += count | |
| return { | |
| "file": path.name, | |
| "bytes": path.stat().st_size, | |
| "tensor_count": len(header), | |
| "dtypes": dtypes, | |
| "parameters": parameters, | |
| "metadata": metadata, | |
| } | |
| def scan_text_files(root: Path) -> dict[str, Any]: | |
| secrets: list[dict[str, Any]] = [] | |
| paths: list[dict[str, Any]] = [] | |
| for file in sorted(root.rglob("*")): | |
| if not file.is_file() or file.suffix not in TEXT_SUFFIXES: | |
| continue | |
| if file.stat().st_size > 8 * 1024 * 1024: | |
| continue # tokenizer.json and friends: no secrets, huge cost | |
| try: | |
| text = file.read_text(encoding="utf-8", errors="replace") | |
| except OSError: | |
| continue | |
| relative = str(file.relative_to(root)) | |
| for name, pattern in SECRET_PATTERNS.items(): | |
| if pattern.search(text): | |
| secrets.append({"file": relative, "pattern": name}) | |
| for name, pattern in PATH_PATTERNS.items(): | |
| for match in set(pattern.findall(text)): | |
| # Record the surrounding line so a human can judge it. | |
| for line in text.splitlines(): | |
| if match in line: | |
| paths.append( | |
| {"file": relative, "pattern": name, "line": line.strip()[:200]} | |
| ) | |
| break | |
| return {"secrets": secrets, "absolute_paths": paths} | |
| def audit(model_root: Path) -> dict[str, Any]: | |
| report: dict[str, Any] = {"model_root": str(model_root)} | |
| config = json.loads((model_root / "config.json").read_text(encoding="utf-8")) | |
| text_config = config.get("text_config", {}) | |
| vision_config = config.get("vision_config", {}) | |
| rope = text_config.get("rope_parameters", {}) | |
| layer_types = text_config.get("layer_types", []) | |
| report["architecture"] = { | |
| "architectures": config.get("architectures"), | |
| "model_type": config.get("model_type"), | |
| "declared_transformers_version": config.get("transformers_version"), | |
| "tie_word_embeddings": config.get("tie_word_embeddings"), | |
| "text": { | |
| "hidden_size": text_config.get("hidden_size"), | |
| "intermediate_size": text_config.get("intermediate_size"), | |
| "num_hidden_layers": text_config.get("num_hidden_layers"), | |
| "num_attention_heads": text_config.get("num_attention_heads"), | |
| "num_key_value_heads": text_config.get("num_key_value_heads"), | |
| "head_dim": text_config.get("head_dim"), | |
| "vocab_size": text_config.get("vocab_size"), | |
| "max_position_embeddings": text_config.get("max_position_embeddings"), | |
| "layer_type_counts": { | |
| kind: layer_types.count(kind) for kind in sorted(set(layer_types)) | |
| }, | |
| "full_attention_interval": text_config.get("full_attention_interval"), | |
| "linear_attention": { | |
| "conv_kernel_dim": text_config.get("linear_conv_kernel_dim"), | |
| "key_head_dim": text_config.get("linear_key_head_dim"), | |
| "num_key_heads": text_config.get("linear_num_key_heads"), | |
| "num_value_heads": text_config.get("linear_num_value_heads"), | |
| "value_head_dim": text_config.get("linear_value_head_dim"), | |
| }, | |
| "dtype": text_config.get("dtype"), | |
| }, | |
| "vision": { | |
| "depth": vision_config.get("depth"), | |
| "hidden_size": vision_config.get("hidden_size"), | |
| "num_heads": vision_config.get("num_heads"), | |
| "patch_size": vision_config.get("patch_size"), | |
| "spatial_merge_size": vision_config.get("spatial_merge_size"), | |
| "temporal_patch_size": vision_config.get("temporal_patch_size"), | |
| "out_hidden_size": vision_config.get("out_hidden_size"), | |
| "num_position_embeddings": vision_config.get("num_position_embeddings"), | |
| "deepstack_visual_indexes": vision_config.get("deepstack_visual_indexes"), | |
| }, | |
| "rope": rope, | |
| "special_token_ids": { | |
| "image_token_id": config.get("image_token_id"), | |
| "video_token_id": config.get("video_token_id"), | |
| "vision_start_token_id": config.get("vision_start_token_id"), | |
| "vision_end_token_id": config.get("vision_end_token_id"), | |
| "eos_token_id": text_config.get("eos_token_id"), | |
| }, | |
| } | |
| # Non-standard keys are exactly where provenance leaks tend to hide. | |
| known_top_level = { | |
| "architectures", | |
| "image_token_id", | |
| "model_type", | |
| "text_config", | |
| "tie_word_embeddings", | |
| "transformers_version", | |
| "video_token_id", | |
| "vision_config", | |
| "vision_end_token_id", | |
| "vision_start_token_id", | |
| "dtype", | |
| "eos_token_id", | |
| "pad_token_id", | |
| "hidden_size", | |
| "use_cache", | |
| } | |
| report["nonstandard_config_keys"] = { | |
| key: config[key] for key in config if key not in known_top_level | |
| } | |
| shards = sorted(model_root.glob("model-*.safetensors")) | |
| headers = [safetensors_header(shard) for shard in shards] | |
| total_parameters = sum(h["parameters"] for h in headers) | |
| dtypes: dict[str, int] = {} | |
| for header in headers: | |
| for dtype, count in header["dtypes"].items(): | |
| dtypes[dtype] = dtypes.get(dtype, 0) + count | |
| index_path = model_root / "model.safetensors.index.json" | |
| weight_map = ( | |
| json.loads(index_path.read_text(encoding="utf-8"))["weight_map"] | |
| if index_path.is_file() | |
| else {} | |
| ) | |
| vision_keys = [k for k in weight_map if ".visual." in k] | |
| language_keys = [k for k in weight_map if ".visual." not in k] | |
| vision_parameters = 0 | |
| language_parameters = 0 | |
| for shard in shards: | |
| with safe_open(shard, framework="pt", device="cpu") as handle: | |
| for key in handle.keys(): | |
| view = handle.get_slice(key) | |
| count = 1 | |
| for dimension in view.get_shape(): | |
| count *= int(dimension) | |
| if ".visual." in key: | |
| vision_parameters += count | |
| else: | |
| language_parameters += count | |
| report["weights"] = { | |
| "shard_count": len(shards), | |
| "total_bytes": sum(h["bytes"] for h in headers), | |
| "tensor_count": sum(h["tensor_count"] for h in headers), | |
| "total_parameters": total_parameters, | |
| "language_parameters": language_parameters, | |
| "vision_parameters": vision_parameters, | |
| "language_tensor_count": len(language_keys), | |
| "vision_tensor_count": len(vision_keys), | |
| "dtype_histogram": dtypes, | |
| "safetensors_metadata": {h["file"]: h["metadata"] for h in headers}, | |
| "shards": headers, | |
| } | |
| generation_path = model_root / "generation_config.json" | |
| report["generation_config"] = ( | |
| json.loads(generation_path.read_text(encoding="utf-8")) | |
| if generation_path.is_file() | |
| else None | |
| ) | |
| tokenizer_config = json.loads( | |
| (model_root / "tokenizer_config.json").read_text(encoding="utf-8") | |
| ) | |
| added = tokenizer_config.get("added_tokens_decoder", {}) | |
| report["tokenizer"] = { | |
| "tokenizer_class": tokenizer_config.get("tokenizer_class"), | |
| "processor_class": tokenizer_config.get("processor_class"), | |
| "model_max_length": tokenizer_config.get("model_max_length"), | |
| "eos_token": tokenizer_config.get("eos_token"), | |
| "pad_token": tokenizer_config.get("pad_token"), | |
| "bos_token": tokenizer_config.get("bos_token"), | |
| "padding_side": tokenizer_config.get("padding_side"), | |
| "added_token_count": len(added), | |
| "special_tokens": tokenizer_config.get("model_specific_special_tokens"), | |
| "has_chat_template_file": (model_root / "chat_template.jinja").is_file(), | |
| } | |
| for name in ("preprocessor_config.json", "video_preprocessor_config.json"): | |
| path = model_root / name | |
| report[name.replace(".json", "")] = ( | |
| json.loads(path.read_text(encoding="utf-8")) if path.is_file() else None | |
| ) | |
| report["files"] = ( | |
| sorted( | |
| { | |
| "name": str(p.relative_to(model_root)), | |
| "bytes": p.stat().st_size, | |
| } | |
| for p in model_root.rglob("*") | |
| if p.is_file() and ".cache" not in p.parts | |
| ) | |
| if False | |
| else [ | |
| {"name": str(p.relative_to(model_root)), "bytes": p.stat().st_size} | |
| for p in sorted(model_root.rglob("*")) | |
| if p.is_file() and ".cache" not in p.parts | |
| ] | |
| ) | |
| report["remote_code"] = { | |
| "auto_map_present": "auto_map" in config, | |
| "python_files_in_repo": [f["name"] for f in report["files"] if f["name"].endswith(".py")], | |
| "trust_remote_code_required": "auto_map" in config, | |
| } | |
| report["hygiene"] = scan_text_files(model_root) | |
| small_hashes = {} | |
| for entry in report["files"]: | |
| path = model_root / entry["name"] | |
| if entry["bytes"] <= 4 * 1024 * 1024: | |
| small_hashes[entry["name"]] = sha256_file(path) | |
| report["file_sha256_small"] = small_hashes | |
| return report | |
| def main() -> None: | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument("--model", required=True, type=Path) | |
| parser.add_argument("--output", type=Path, default=Path("reports/repository_audit.json")) | |
| args = parser.parse_args() | |
| report = audit(args.model) | |
| args.output.parent.mkdir(parents=True, exist_ok=True) | |
| args.output.write_text(json.dumps(report, indent=2) + "\n", encoding="utf-8") | |
| weights = report["weights"] | |
| print(f"Wrote {args.output}") | |
| print(f" parameters : {weights['total_parameters']:,}") | |
| print(f" language : {weights['language_parameters']:,}") | |
| print(f" vision : {weights['vision_parameters']:,}") | |
| print(f" shards : {weights['shard_count']}") | |
| print(f" dtypes : {weights['dtype_histogram']}") | |
| print(f" secrets found : {len(report['hygiene']['secrets'])}") | |
| print(f" absolute paths : {len(report['hygiene']['absolute_paths'])}") | |
| for entry in report["hygiene"]["absolute_paths"]: | |
| print(f" {entry['file']}: {entry['line'][:120]}") | |
| if __name__ == "__main__": | |
| main() | |