RKLLM Documentation

repository·main·Indexed 23 days ago

https://github.com/airockchip/rknn-llm

A software stack for deploying and accelerating Large Language Models (LLMs) and multimodal models on Rockchip NPU hardware. It includes a PC-based toolkit for model conversion and quantization, and a C/C++ runtime for on-device inference. Supports models such as Qwen2-VL, Qwen3-VL, DeepSeekOCR, and DeepSeek-R1-Distill-Qwen-1.5B, providing tools for ONNX export and RKLLM format conversion.

Tokens
14.2K
Snippets
23
Records
44
Agent score
32%

What's inside rknn-llm

  1. How the RKLLM software stack works

    main

    The RKLLM software stack enables the deployment of AI models to Rockchip chips through a three-part framework:

    1. RKLLM-Toolkit: A PC-based software development kit used to perform model conversion and quantization. It converts trained models into the .rkllm format.
    2. RKLLM Runtime: Provides C/C++ programming interfaces (APIs) for the Rockchip NPU platform to deploy and accelerate LLM applications.
    3. RKNPU Kernel Driver: The open-source driver responsible for interacting directly with the NPU hardware.

    Workflow: Convert model on PC using RKLLM-Toolkit $\rightarrow$ Deploy and run inference on the development board using RKLLM C API.

  2. Choose between TurboJPEG and libjpeg APIs

    main

    libjpeg-turbo provides two distinct APIs for JPEG compression and decompression:

    • TurboJPEG API: A straightforward, easy-to-use interface for in-memory operations. It is ideal for simple tasks and includes specialized functionality like generating planar YUV images or performing multiple simultaneous lossless transforms. The Java interface is built on top of this API.
    • libjpeg API: The industry-standard API. It is more powerful and complex than TurboJPEG. It is natively API/ABI-compatible and mathematically compatible with libjpeg v6b. It can be configured to emulate libjpeg v7 or v8.

    There is no significant performance difference between the two APIs when performing similar operations.

  3. Implement Function Calling (Tool Use)

    main

    Function calling allows the model to request tool execution. The workflow is:

    1. Request: Send user prompt and a list of TOOLS (OpenAI format) to the server.
    2. Model Output: The model returns a tool call instruction (e.g., wrapped in <tool_call> tags).
    3. Execution: Parse the instruction, execute the local function, and append the result to the message history with the role: "tool".
    4. Final Synthesis: Send the updated message history back to the model to get the final natural language answer.

    Note: The demo implementation is optimized for Qwen3 series models which use <tool_call> XML-like tags. Other models may require different parsing logic.

    from chat_api_flask import RKLLMClient, TOOLS, parse_tool_calls, execute_tool_calls
    
    client = RKLLMClient(base_url="http://x.x.x.x:8080")
    
    messages = [
        {"role": "system", "content": "You are Qwen..."},
        {"role": "user", "content": "What's the temperature in San Francisco now?"},
    ]
    
    # Step 1: Get tool calls from model
    resp = client.chat(messages=messages, tools=TOOLS, stream=False)
    tool_calls = parse_tool_calls(resp["choices"][0]["message"]["content"])
    
    # Step 2: Execute tools and update messages
    assistant_msg, tool_msgs = execute_tool_calls(tool_calls)
    messages.append(assistant_msg)
    messages.extend(tool_msgs)
    
    # Step 3: Get final answer
    resp = client.chat(messages=messages, tools=None, stream=False)
    print("A:", resp["choices"][0]["message"]["content"])
  4. Quickstart: Run a multimodal vision model demo

    main

    To test the stack using a pre-converted multimodal vision model (using RKNN for vision and RKLLM for language), follow these steps:

    1. Download: Get the pre-converted models and the demo executable from the rkllm_model_zoo (fetch code: rkllm).
    2. Transfer: Push the files to your local device via ADB:
    adb push ./demo_Linux_aarch64 /data
    adb push model.rkllm /data/demo_Linux_aarch64
    adb push model.rknn /data/demo_Linux_aarch64
    1. Setup Environment: Enter the device shell and set the library path:
    adb shell
    cd /data/demo_Linux_aarch64
    export LD_LIBRARY_PATH=./lib
    1. Execute: Run the ./demo command with the required arguments (see specific model commands below).
    adb push ./demo_Linux_aarch64 /data
    adb push model.rkllm /data/demo_Linux_aarch64
    adb push model.rknn /data/demo_Linux_aarch64
    
    adb shell
    cd /data/demo_Linux_aarch64
    export LD_LIBRARY_PATH=./lib
  5. Convert Qwen2-VL Vision component to ONNX

    main

    The Vision + Projector component of Qwen2-VL is exported to ONNX using export/export_vision_qwen2.py.

    Important Notes:

    • Flash Attention: If you encounter data type restrictions when loading weights, set "use_flash_attn": false in your config.json because RKNN currently only supports float32.
    • Step Parameter:
      • Use --step 1 the first time to generate cu_seqlens and rotary_pos_emb.
      • Use --step 0 (or any number except 1) for subsequent exports.
    • Re-generation: If you change the batch, height, or width, you must re-generate cu_seqlens and rotary_pos_emb by setting --step 1 again.
    # First time to generate cu_seqlens and rotary_pos_emb, need to set 'step' to 1
    python export/export_vision_qwen2.py --step 1 --path /path/to/Qwen2-VL-model --batch 1 --height 392 --width 392
    
    # Second time to export onnx model, need to set 'step' to any number except 1
    python export/export_vision_qwen2.py --step 0 --path /path/to/Qwen2-VL-model --savepath /path/to/save/qwen2-vl-vision.onnx --batch 1 --height 392 --width 392
  6. Deploy and Run the C++ LLM Demo

    main

    After building, follow these steps to deploy the demo to your device (e.g., via ADB) and run it:

    1. Push files to device:

      • Push the install directory.
      • Push the .rkllm model file.
      • Push the appropriate fixed-frequency script (e.g., fix_freq_rk3588.sh).
    2. Run the demo:

      • Enter the installation directory on the board.
      • Export the library path.
      • Execute the fixed-frequency script.
      • (Optional) Set RKLLM_LOG_LEVEL for performance analysis.
      • Run ./llm_demo with the model path, input length, and output length.
    # Deployment steps
    # push install dir to device
    adb push install/demo_Linux_aarch64 /data
    # push model file to device
    adb push DeepSeek-R1-Distill-Qwen-1.5B.rkllm /data/demo_Linux_aarch64
    # push the appropriate fixed-frequency script to the device
    adb push ../../../scripts/fix_freq_rk3588.sh /data/demo_Linux_aarch64
    
    # Execution steps
    adb shell
    cd /data/demo_Linux_aarch64
    # export lib path
    export LD_LIBRARY_PATH=./lib
    # Execute the fixed-frequency script
    sh fix_freq_rk3588.sh
    # Set the logging level for performance analysis
    export RKLLM_LOG_LEVEL=1
    ./llm_demo /path/to/your/rkllm/model 2048 4096
  7. Set CPU and NPU frequencies for benchmarking

    main
    Performance benchmark data is collected based on the maximum CPU and NPU frequencies of each platform. To replicate these conditions, use the scripts located in the scripts directory to set the frequencies.
  8. Run the C++ Multimodal Demo on Device

    main

    After pushing the files to the device, follow these steps to run the demo:

    1. Enter the /data/demo_Linux_aarch64 directory.
    2. Export the LD_LIBRARY_PATH to include the lib folder.
    3. Create a symbolic link to the models directory.
    4. Run imgenc to generate image features.
    5. Run demo for multimodal inference.

    Important: The max_context_len argument must be larger than text-token-num + image-token-num + max_new_tokens.

    Arguments for ./demo:

    • image_path: Path to the input image.
    • vision_model: Path to the RKNN vision model.
    • llm_model: Path to the RKLLM model.
    • max_context_len: Maximum context length.
    • max_new_tokens: Maximum number of new tokens to generate.
    • npu_core: Number of NPU cores.
    • target_platform: Target platform (e.g., rk3588).
    • vision_start_token: Token marking the start of vision data.
    • vision_end_token: Token marking the end of vision data.
    • image_pad_token: Token used for image padding.
    adb shell
    cd /data/demo_Linux_aarch64
    # export lib path
    export LD_LIBRARY_PATH=./lib
    # soft link models dir
    ln -s /data/models .
    # run imgenc
    ./imgenc models/qwen2-vl-vision_rk3588.rknn demo.jpg 3
    # run demo(Multimodal Example)
    ./demo demo.jpg models/qwen2-vl-vision_rk3588.rknn models/qwen2-vl-llm_rk3588.rkllm 2048 4096 3 rk3588 "<|vision_start|>" "<|vision_end|>" "<|image_pad|>"
  9. Convert a model to RKLLM format

    main

    To convert a model (e.g., DeepSeek-R1-Distill-Qwen-1.5B) to the .rkllm format, follow these steps:

    1. Create data_quant.json for quantization calibration using FP16 model generation results.
    2. Run the generation and export scripts in the export directory.

    Alternatively, you can download pre-converted models from the rkllm_model_zoo.

    cd export
    python generate_data_quant.py -m /path/to/DeepSeek-R1-Distill-Qwen-1.5B
    python export_rkllm.py
  10. Build the C++ Multimodal Demo

    main

    Compile the example code for Linux or Android using the provided build scripts. You must replace the cross-compiler path with your actual path. This generates an install/demo_Linux_aarch64 folder containing imgenc, llm, demo, and a lib folder.

    Note: In src/main.cpp, the values for 'img_start', 'img_end', and 'img_content' must be set specifically for your model.

    cd deploy
    # for linux
    ./build-linux.sh
    # for android
    ./build-android.sh
    
    # push install dir to device
    adb push ./install/demo_Linux_aarch64 /data
    # push model file to device
    adb push qwen2-vl-vision_rk3588.rknn /data/models
    adb push qwen2-vl-llm_rk3588.rkllm /data/models
  11. Build and Deploy the RKLLM-Server Demo

    main

    The RKLLM-Server Demo provides two ways to deploy the model on a board: a Flask server for API access and a Gradio server for a Web UI.

    Prerequisites:

    • The transformed RKLLM model file must be present on the board.
    • You must know the board's IP address (use ifconfig to find it).

    Deployment Options:

    1. Flask Server (OpenAI-compatible API): Use this for programmatic access via HTTP. It provides endpoints for listing models and generating chat completions.

    2. Gradio Server (Web UI): Use this for a visual chat interface. Once deployed, access it via http://<board-ip>:8080 in your browser.