--- license: apache-2.0 base_model: - opendatalab/MinerU2.5-Pro-2605-1.2B pipeline_tag: image-text-to-text --- The `MinerU2.5-Pro` is now supported in `llama-cpp-python`. This project provides a test GGUF file. `llama-cpp-python`: https://github.com/JamePeng/llama-cpp-python Code example: ```python from llama_cpp import Llama from llama_cpp.llama_chat_format import Qwen25VLChatHandler import base64 import os # Model and multimodal projection paths MODEL_PATH = r".\MinerU2.5-Pro-2605-1.2b-BF16.gguf" MMPROJ_PATH = r".\mmproj-MinerU2.5-Pro-2605-BF16.gguf" # Initialize the Llama model with vision support llm = Llama( model_path=MODEL_PATH, chat_handler=Qwen25VLChatHandler( clip_model_path=MMPROJ_PATH, verbose=True ), n_gpu_layers=-1, # Use all available GPU layers n_ctx = 20480, # Context window size n_batch=2048, verbose=False ) # Comprehensive MIME type mapping (updated as of 2025) # Based on Pillow 10.x+ "Fully Supported" (Read & Write) formats # Reference: IANA official media types + common real-world usage # See: https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html _IMAGE_MIME_TYPES = { # Most common formats '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.gif': 'image/gif', '.webp': 'image/webp', # Next-generation formats '.avif': 'image/avif', '.jp2': 'image/jp2', '.j2k': 'image/jp2', '.jpx': 'image/jp2', # Legacy / Windows formats '.bmp': 'image/bmp', '.ico': 'image/x-icon', '.pcx': 'image/x-pcx', '.tga': 'image/x-tga', '.icns': 'image/icns', # Professional / Scientific imaging '.tif': 'image/tiff', '.tiff': 'image/tiff', '.eps': 'application/postscript', '.dds': 'image/vnd-ms.dds', '.dib': 'image/dib', '.sgi': 'image/sgi', # Portable Map formats (PPM/PGM/PBM) '.pbm': 'image/x-portable-bitmap', '.pgm': 'image/x-portable-graymap', '.ppm': 'image/x-portable-pixmap', # Miscellaneous / Older formats '.xbm': 'image/x-xbitmap', '.mpo': 'image/mpo', '.msp': 'image/msp', '.im': 'image/x-pillow-im', '.qoi': 'image/qoi', } def image_to_base64_data_uri( file_path: str, *, fallback_mime: str = "application/octet-stream" ) -> str: """ Convert a local image file to a base64-encoded data URI with the correct MIME type. Supports 20+ image formats (PNG, JPEG, WebP, AVIF, HEIC, SVG, BMP, ICO, TIFF, etc.). Args: file_path: Path to the image file on disk. fallback_mime: MIME type used when the file extension is unknown. Returns: A valid data URI string (e.g., data:image/webp;base64,...). Raises: FileNotFoundError: If the file does not exist. OSError: If reading the file fails. """ if not os.path.isfile(file_path): raise FileNotFoundError(f"Image file not found: {file_path}") extension = os.path.splitext(file_path)[1].lower() mime_type = _IMAGE_MIME_TYPES.get(extension, fallback_mime) if mime_type == fallback_mime: print(f"Warning: Unknown extension '{extension}' for '{file_path}'. " f"Using fallback MIME type: {fallback_mime}") try: with open(file_path, "rb") as img_file: encoded_data = base64.b64encode(img_file.read()).decode("utf-8") except OSError as e: raise OSError(f"Failed to read image file '{file_path}': {e}") from e return f"data:{mime_type};base64,{encoded_data}" # ======================== # Main image processing & inference section # ======================== # 1. List of image paths you want to analyze (supports mixed formats) image_paths = [ r'./book.jpg', ] # 2. Container for message content (each image + final text prompt) user_content = [] # 3. Convert every image to a properly formatted data URI message for path in image_paths: data_uri = image_to_base64_data_uri(path) user_content.append({ "type": "image_url", "image_url": {"url": data_uri} }) DEFAULT_PROMPTS: dict[str, str] = { "table": "\nTable Recognition:", "equation": "\nFormula Recognition:", "image": "\nImage Analysis:", "chart": "\nImage Analysis:", "[default]": "\nText Recognition:", "[layout]": "\nLayout Detection:", "[cross_page_table_merge]": "", # prompt is dynamic, built from table content } # 4. Append the text instruction (appears after all images in the message) user_content.append({ "type": "text", "text": DEFAULT_PROMPTS['[default]'] # You can change the prompt as needed }) # 5. Perform chat completion with vision response = llm.create_chat_completion( messages=[ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": user_content} ], max_tokens=10240, present_penalty=1.0, frequency_penalty=0.05 ) # 6. Print the model's reply print(response["choices"][0]["message"]["content"]) ```