diff --git a/examples/LLMs/cpp/Android.mk b/examples/LLMs/cpp/Android.mk index 4d46c5b..ad44272 100644 --- a/examples/LLMs/cpp/Android.mk +++ b/examples/LLMs/cpp/Android.mk @@ -1,6 +1,6 @@ LOCAL_PATH := $(call my-dir) -LLM_SDK_PATH := $(LOCAL_PATH)/../../01_src -3RDPARTY_PATH := $(LOCAL_PATH)/../../3rdparty +LLM_SDK_PATH := $(LOCAL_PATH)/../../../../amlnn-toolkit/npu_runtime/llmsdk +3RDPARTY_PATH := $(LOCAL_PATH)/../../../dependency $(warning $(LOCAL_PATH)) include $(CLEAR_VARS) @@ -8,11 +8,10 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := main.cpp LOCAL_C_INCLUDES := \ - $(LLM_SDK_PATH)/jni \ - $(3RDPARTY_PATH)/include \ + $(LLM_SDK_PATH)/include \ LOCAL_LDFLAGS := \ - -L$(LLM_SDK_PATH)/libs/arm64-v8a -lllmsdk + -L$(LLM_SDK_PATH)/android/arm64-v8a -lllmsdk LOCAL_LDLIBS := -llog -ldl -lm -fuse-ld=ld diff --git a/examples/LLMs/cpp/build-android.sh b/examples/LLMs/cpp/build-android.sh new file mode 100755 index 0000000..b037bf8 --- /dev/null +++ b/examples/LLMs/cpp/build-android.sh @@ -0,0 +1,11 @@ +#!/bin/bash +if [ ! -d "$NDK_PATH" ]; then + echo "Error: NDK_PATH '$NDK_PATH' not found." + echo "Please set NDK_PATH environment variable to your Android NDK directory." + exit 1 +fi + +$NDK_PATH/ndk-build \ + NDK_PROJECT_PATH=. \ + APP_BUILD_SCRIPT=./Android.mk \ + NDK_APPLICATION_MK=./Application.mk diff --git a/examples/LLMs/cpp/main.cpp b/examples/LLMs/cpp/main.cpp index cb388e7..ec40f9f 100644 --- a/examples/LLMs/cpp/main.cpp +++ b/examples/LLMs/cpp/main.cpp @@ -63,8 +63,6 @@ int main(int argc, char **argv) return -1; } - printf("\nWelcome to Amlogic LLM Demo!\n"); - LLMContext context; AML_LLMInitConfig init_config; memset(&init_config, 0, sizeof(AML_LLMInitConfig)); @@ -90,6 +88,31 @@ int main(int argc, char **argv) MyUserData my_data; memset(&my_data, 0, sizeof(MyUserData)); + printf("***************************************************\n"); + printf("* *\n"); + printf("* _____ _ _ _ _____ __ __ *\n"); + printf("* | ___|| \\ | | | || _ |\\ \\ / / *\n"); + printf("* | |__ | \\| | | || | | | \\ \\_/ / *\n"); + printf("* | __| | . ` | | || | | | \\ / *\n"); + printf("* | |___ | |\\ |__| || |_| | | | *\n"); + printf("* |_____||_| \\_|\\___/ \\___/ |_| *\n"); + printf("* *\n"); + printf("* _ __ __ _ ____ _____ _____ ____*\n"); + printf("* / \\ | \\/ | | / __ \\ / ____|_ _/ ___|*\n"); + printf("* / _ \\ | \\ / | | | | | | | __ | || | *\n"); + printf("* / ___ \\| |\\/| | | | | | | | |_ | | || | *\n"); + printf("* / / \\ \\ | | | |___| |__| | |__| |_| || |___ *\n"); + printf("* /_/ \\_\\_| |_|______\\____/ \\_____|_____\\____|*\n"); + printf("* *\n"); + printf("* _ _ __ __ *\n"); + printf("* | | | | | \\/ | *\n"); + printf("* | | | | | \\ / | *\n"); + printf("* | | | | | |\\/| | *\n"); + printf("* | |____| |____| | | | *\n"); + printf("* |______|______|_| |_| *\n"); + printf("* *\n"); + printf("***************************************************\n"); + printf("\nType your prompt and press Enter.\n"); printf("Commands: [exit] to quit, [new_talk] to reset context.\n"); diff --git a/examples/LLMs/model/llm-result0.png b/examples/LLMs/model/llm-result0.png new file mode 100644 index 0000000..15597ed Binary files /dev/null and b/examples/LLMs/model/llm-result0.png differ diff --git a/examples/LLMs/readme.md b/examples/LLMs/readme.md index 5cb52e7..c03a2d4 100644 --- a/examples/LLMs/readme.md +++ b/examples/LLMs/readme.md @@ -35,5 +35,56 @@ ADLA2: A311D2_3.2T / S905X5_4T | TinyLlama-1.1B-Chat-v0.4 | S905X5 | w8a8 | 64 | 320 | 256 | 733.01 | 6.28 | 1.11 | +## Compile + +### CPP +To compile the CPP project using Android NDK, follow these steps: + +1. **Get the llmsdk library and header files**: + Clone the `amlnn-toolkit` repository to get the necessary libraries for compilation. + ```bash + # Clone to the parent directory of amlnn-model-playground + git clone https://github.com/Amlogic-NN/amlnn-toolkit.git + ``` + +2. **Set the NDK path**: + ```bash + export NDK_PATH=/your/ndk/path/android-ndk-r25c + ``` + +3. **Add NDK to your PATH**: + ```bash + export PATH=$NDK_PATH:$PATH + ``` + +4. **Compile**: + Navigate to the `cpp` directory and run `build-android.sh`: + ```bash + cd examples/LLMs/cpp + ./build-android.sh + ``` + +5. **Run**: + Push the compiled executable, model, and tokenizer to your Android device. + + Optional configuration: + - **Push `llmsdk.so`**: If not already present on the device, push it to `/data/local/tmp`. + - **Set permissions**: + ```bash + chmod +x demo_llm_main + ``` + - **Set environment variable**: + ```bash + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/vendor/lib64/:/data/local/tmp + ``` + + Then execute: + ```bash + ./demo_llm_main Qwen2.5-1.5B-Instruct-F16_quant_i8_t7c.adla tokenizer.json + ``` + ## Result -![llm-result](./model/llm_result.png) \ No newline at end of file + +| Banner | Inference Result | +| :---: | :---: | +| ![llm-result0](./model/llm-result0.png) | ![llm-result](./model/llm_result.png) | \ No newline at end of file diff --git a/examples/yoloworld/README.md b/examples/yoloworld/README.md index e69de29..9c7c032 100644 --- a/examples/yoloworld/README.md +++ b/examples/yoloworld/README.md @@ -0,0 +1,72 @@ +## Demo Run + +### CPP + +#### 1. Compile + +**Prerequisites:** +- Android NDK (r25e recommended) +- `ANDROID_NDK_PATH` environment variable set + +**Build:** +```bash +# Build for arm64-v8a +cd examples/yoloworld/cpp +./build-android.sh -a arm64-v8a +``` + +The executable will be generated at `build/android/yolo_world_demo` (Note: executable name may vary, verify in build folder). + +#### 2. Run + +```bash +# Push executable to device +adb push build/android/yolo_world_demo /data/local/tmp/ +adb push model/yoloworld_int8_A311D2.adla /data/local/tmp/ +adb push test_image.jpg /data/local/tmp/ + +# Run on device +adb shell +cd /data/local/tmp +chmod +x yolo_world_demo +export LD_LIBRARY_PATH=/vendor/lib64 or (/vendor/lib) + +# Usage: ./yolo_world_demo +./yolo_world_demo yoloworld_int8_A311D2.adla test_image.jpg +``` + +**Note:** Replace `yoloworld_int8_A311D2.adla` with your actual model file path. + +### Python + +**Prerequisites:** +- Python 3.10 +- Required packages: `numpy`, `opencv-python`, `amlnnlite` + +**Install dependencies:** +```bash +pip install numpy opencv-python amlnnlite-1.0.0-cp310-cp310-linux_aarch64.whl +``` + +**Run on device:** +```bash +# Basic usage (process current directory) +python yoloworld.py --model-path ./yoloworld_int8_A311D2.adla + +# Specify image directory +python yoloworld.py --model-path ./yoloworld_int8_A311D2.adla --image-dir ./ +``` + +The script will automatically process all image files (`.jpg`, `.jpeg`, `.png`, `.bmp`) in the specified directory and save results to a `{model_name}_result` folder. + +## Results + +The program will print the detection count and detected objects for each processed image. The result image with bounding boxes will be saved to the specified output directory. + +You can pull the result image back to view it: +```bash +adb pull result.jpg. +``` +![alt text](result.jpg) + +The program detects objects from predefined classes (handbag, backpack, wallet, watch, necklace, bracelet, earrings, finger ring, sunglass, hat, shoes, belt, makeup palette, lipstick tube, car, truck, bicycle, motorcycle, phone, laptop, camera, wine bottle, stuffed toy) and draws bounding boxes with class labels on the result images. diff --git a/examples/yoloworld/py/yoloworld.py b/examples/yoloworld/py/yoloworld.py index 8c182c4..7b81d5b 100755 --- a/examples/yoloworld/py/yoloworld.py +++ b/examples/yoloworld/py/yoloworld.py @@ -456,7 +456,7 @@ Examples: conf_threshold=args.conf_threshold, iou_threshold=args.nms_threshold, num_classes=NUM_CLASSES, - reverse=1 # YOLOWorld format + reverse=1 ) # Print detection results @@ -469,11 +469,7 @@ Examples: print(" No objects detected") # Save result image - model_name = Path(args.model_path).stem - result_dir = f"{model_name}_result" - os.makedirs(result_dir, exist_ok=True) - img_name = Path(image_path).stem - save_path = os.path.join(result_dir, f"{img_name}_result.jpg") + save_path = "result.jpg" draw_detections(original_img, detections, str(save_path)) print(f" Result saved to: {save_path}") @@ -481,7 +477,6 @@ Examples: print(f"Error processing {os.path.basename(image_path)}: {e}") import traceback traceback.print_exc() - # Continue processing other images continue print() diff --git a/examples/yoloworld/result.jpg b/examples/yoloworld/result.jpg new file mode 100755 index 0000000..93f46f7 Binary files /dev/null and b/examples/yoloworld/result.jpg differ