#!/usr/bin/env python3 """ ๐Ÿดโ€โ˜ ๏ธ PaddleOCR-VL CryptDeck โšก v2 โ€” ZeroGPU edition Cyber-occult hacker pirate deck for testing PaddlePaddle/PaddleOCR-VL-1.6-GGUF locally with llama.cpp on ZeroGPU. Do what thou wilt shall be the whole of the Law. """ import base64 import glob import io import json import os import shutil import subprocess import tarfile import threading import time import urllib.request import spaces # ZeroGPU SDK โ€” must be imported before CUDA-touching code import gradio as gr import requests from huggingface_hub import hf_hub_download from PIL import Image # ---------------------------------------------------------------- constants REPO_ID = "PaddlePaddle/PaddleOCR-VL-1.6-GGUF" MODEL_FILE = "PaddleOCR-VL-1.6-GGUF.gguf" MMPROJ_FILE = "PaddleOCR-VL-1.6-GGUF-mmproj.gguf" LLAMA_TAG = "b11555" LLAMA_URL = ( f"https://github.com/ggml-org/llama.cpp/releases/download/{LLAMA_TAG}/" f"llama-{LLAMA_TAG}-bin-ubuntu-cuda-12.8-x64.tar.gz" ) CUDART_URL = ( f"https://github.com/ggml-org/llama.cpp/releases/download/{LLAMA_TAG}/" f"cudart-llama-{LLAMA_TAG}-bin-ubuntu-cuda-12.8-x64.tar.gz" ) BIN_DIR = "/tmp/llama-bin" SERVER_PORT = 8081 SERVER_URL = f"http://127.0.0.1:{SERVER_PORT}" RITES = { "๐Ÿ”ค OCR โ€” full document parse": "OCR:", "๐Ÿงฎ Formula Recognition": "Formula Recognition:", "๐Ÿ“Š Table Recognition": "Table Recognition:", "๐Ÿ“ˆ Chart Recognition": "Chart Recognition:", "๐Ÿชช Seal Recognition": "Seal Recognition:", "๐Ÿ” Spotting (bounding boxes)": "Spotting:", } # ---------------------------------------------------------------- ritual log _log_lines: list[str] = ["๐Ÿดโ€โ˜ ๏ธ CryptDeck v2 โ€” ZeroGPU rig. Wake the oracle."] _log_lock = threading.Lock() def ritual_log(msg: str) -> str: with _log_lock: _log_lines.append(msg) return "\n".join(_log_lines[-60:]) def get_log() -> str: with _log_lock: return "\n".join(_log_lines[-60:]) # ---------------------------------------------------------------- engine _engine_lock = threading.Lock() _busy = threading.Lock() def _fetch_engine() -> str: """Download the prebuilt CUDA llama.cpp + cudart; return llama-server path.""" candidates = glob.glob(os.path.join(BIN_DIR, "llama-*", "llama-server")) server = candidates[0] if candidates else None if server and os.path.exists(server): return server os.makedirs(BIN_DIR, exist_ok=True) ritual_log(f"โš™๏ธ Downloading llama.cpp {LLAMA_TAG} (CUDA 12.8) + cudart โ€ฆ") for url in (LLAMA_URL, CUDART_URL): tgz = os.path.join(BIN_DIR, os.path.basename(url)) urllib.request.urlretrieve(url, tgz) with tarfile.open(tgz) as tf: tf.extractall(BIN_DIR) candidates = glob.glob(os.path.join(BIN_DIR, "llama-*", "llama-server")) if not candidates: raise RuntimeError("llama-server binary not found after extraction") server = candidates[0] os.chmod(server, 0o755) ritual_log("โš™๏ธ llama-server (CUDA) consecrated.") return server def _fetch_models() -> tuple[str, str]: ritual_log("๐Ÿ“ฆ Summoning the grimoire (1.9 GB, cached after first boot) โ€ฆ") main_gguf = hf_hub_download(REPO_ID, MODEL_FILE) mmproj = hf_hub_download(REPO_ID, MMPROJ_FILE) ritual_log("๐Ÿ“ฆ Grimoire secured: " + os.path.basename(main_gguf)) return main_gguf, mmproj # ---------------------------------------------------------------- GPU rite @spaces.GPU(duration=180) def gpu_rite(b64_png: str, prompt: str) -> tuple[str, float]: """Runs entirely inside a ZeroGPU window: boot llama-server, divine, scuttle it.""" server = _fetch_engine() model, mmproj = _fetch_models() # cudart libs sit in their own extracted dir โ€” expose them to the linker lib_dirs = glob.glob(os.path.join(BIN_DIR, "cudart-*")) server_dir = os.path.dirname(server) env = dict(os.environ) env["LD_LIBRARY_PATH"] = os.pathsep.join( lib_dirs + [server_dir, env.get("LD_LIBRARY_PATH", "")] ) ritual_log("๐Ÿ”ฅ Kindling llama-server on the GPU (-ngl 999) โ€ฆ") proc = subprocess.Popen( [ server, "-m", model, "--mmproj", mmproj, "--host", "127.0.0.1", "--port", str(SERVER_PORT), "-ngl", "999", "-c", "16384", "--temp", "0", "--no-webui", ], stdout=open("/tmp/llama-server.log", "ab"), stderr=subprocess.STDOUT, env=env, ) try: for _ in range(150): # up to 150 s for load onto GPU if proc.poll() is not None: raise RuntimeError( "llama-server died at boot. Log tail:\n" + open("/tmp/llama-server.log", "rb").read()[-1500:].decode(errors="replace") ) try: if requests.get(SERVER_URL + "/health", timeout=2).status_code == 200: ritual_log("๐ŸŸข Oracle online on GPU. The Signal is strong.") break except requests.RequestException: pass time.sleep(1) else: raise RuntimeError("llama-server never reported healthy.") payload = { "model": "paddleocr-vl", "temperature": 0, "messages": [ { "role": "user", "content": [ {"type": "image_url", "image_url": {"url": "data:image/png;base64," + b64_png}}, {"type": "text", "text": prompt}, ], } ], } t0 = time.time() resp = requests.post( SERVER_URL + "/v1/chat/completions", json=payload, timeout=120 ) dt = time.time() - t0 resp.raise_for_status() return resp.json()["choices"][0]["message"]["content"], dt finally: # scuttle the server before the GPU window closes ritual_log("๐Ÿช“ Scuttling llama-server. GPU returns to the void.") proc.terminate() try: proc.wait(timeout=10) except subprocess.TimeoutExpired: proc.kill() # ---------------------------------------------------------------- inference def divine(image, rite: str, custom: str, progress=gr.Progress()): if image is None: raise gr.Error("โš“ Bring the oracle an image โ€” no offering, no prophecy.") if not _busy.acquire(blocking=False): raise gr.Error("๐Ÿ”ฅ The oracle is already mid-rite. One soul at a time.") try: prompt = custom.strip() if custom.strip() else RITES[rite] ritual_log(f"๐Ÿœ‚ Casting rite โ†’ {prompt!r}") progress(0.2, desc="Opening the GPU window โ€ฆ") buf = io.BytesIO() Image.fromarray(image).save(buf, format="PNG") b64 = base64.b64encode(buf.getvalue()).decode() progress(0.4, desc="Summoning on GPU (first boot hauls ~3 GB) โ€ฆ") prophecy, dt = gpu_rite(b64, prompt) ritual_log(f"๐Ÿœƒ Rite complete in {dt:.1f}s on GPU.") progress(1.0, desc="Done.") meta = json.dumps( {"rite": prompt, "gpu_seconds": round(dt, 1)}, indent=2 ) return prophecy, meta, get_log() except requests.Timeout: raise gr.Error("โณ The oracle dawdled. Try a smaller image.") finally: _busy.release() # ---------------------------------------------------------------- UI HEADER = """
                                 .-
                        __    _-'-------------------------------.__
                       |  |  /        P A D D L E O C R - V L          \\
                   _-  |  | |        C  R  Y  P  T  D  E  C  K         |
                  |    |  | |  1.6 GGUF โ–ธ llama.cpp โ–ธ ZERO-GPU RITES   |
                  |    |  | |_________________________________________|
              ____|____|-|_'---------____________________---.___________
             (o  o  o  o  o  o  o  o  o  o  o  o  o  o  o  o  o  o  o  o)

โšก SKULL & SIGNAL โš“ โ€” feed the oracle a page, choose your rite, claim the text.

""" CSS = """ .gradio-container {background: #05060a !important;} body {background: #05060a !important; background-image: repeating-linear-gradient(0deg, rgba(57,255,136,0.03) 0 1px, transparent 1px 3px);} footer {display: none !important;} #header {border: 1px solid #1e2a1e; border-radius: 10px; background: radial-gradient(ellipse at top, #0b1a10, #05060a); padding: 12px;} textarea, .output-html, .prose {font-family: 'Fira Mono', ui-monospace, monospace !important;} .rune-btn {font-family: monospace !important; text-transform: uppercase; letter-spacing: 2px; background: linear-gradient(90deg, #0f2b18, #14203a) !important; border: 1px solid #39ff88 !important; color: #39ff88 !important;} .rune-btn:hover {box-shadow: 0 0 12px #39ff8866 !important;} #prophecy, #meta, #log textarea {color: #b8ffd9 !important; caret-color: #ff00cc;} #log textarea {color: #39ff88 !important; font-size: 12px;} h1, h2, h3, .label, .info {font-family: ui-monospace, monospace !important;} """ with gr.Blocks(title="๐Ÿดโ€โ˜ ๏ธ PaddleOCR-VL CryptDeck") as demo: gr.HTML(f'') with gr.Row(): with gr.Column(scale=1): gr.HTML('
โš“ THE OFFERING
') image_in = gr.Image(label="Target document", type="numpy", height=380) rite = gr.Radio( list(RITES.keys()), value=list(RITES.keys())[0], label="Choose your rite", ) custom = gr.Textbox( label="โ€ฆor whisper your own prompt (overrides the rite)", placeholder="OCR:", ) summon = gr.Button("๐Ÿœ‚ SUMMON THE PROPHECY", elem_classes=["rune-btn"]) gr.HTML( '
ZeroGPU rites: first cast hauls ' "~3 GB (engine + grimoire), then it's cached. Each rite boots the " "oracle fresh onto the GPU (~10โ€“20 s) before divining in seconds. " "One rite at a time, matey.
" ) with gr.Column(scale=1): gr.HTML('
๐Ÿ“œ THE PROPHECY
') prophecy = gr.Markdown(label="Prophecy") with gr.Accordion("Rite metadata", open=False): meta = gr.JSON(label="Metadata") with gr.Accordion("๐Ÿฉธ Ritual log", open=True): log = gr.Textbox(label="", lines=12, interactive=False) summon.click( divine, inputs=[image_in, rite, custom], outputs=[prophecy, meta, log], show_progress="full", ) demo.load(lambda: get_log(), outputs=[log]) if __name__ == "__main__": demo.queue(max_size=8).launch(server_name="0.0.0.0", show_error=True)