add some new python demos

This commit is contained in:
dian.yuan 2026-01-14 16:59:57 +08:00
parent d631c4d009
commit c598b3aef4
23 changed files with 2174 additions and 11 deletions

View file

@ -0,0 +1,95 @@
## Demo Run
### CPP
#### 1. Compile
**Prerequisites:**
- Android NDK (r25e recommended)
- `ANDROID_NDK_PATH` environment variable set
**Build:**
```bash
# Build for arm64-v8a
cd examples/clip/cpp
./build-android.sh -a arm64-v8a
```
The executable will be generated at `build/android_arm64-v8a/clip_demo` (Note: executable name may vary, verify in build folder).
#### 2. Run
```bash
# Push executable to device
adb push build/android_arm64-v8a/clip_demo /data/local/tmp/
adb push model/vision_model_int8_A311D2.adla /data/local/tmp/
adb push clip_datasets/ /data/local/tmp/
adb push test_hat_0.jpg /data/local/tmp/
# Run on device
adb shell
cd /data/local/tmp
chmod +x clip_demo
export LD_LIBRARY_PATH=/vendor/lib64 or (/vendor/lib)
# Usage: ./clip_demo <model_path> [base_dir] [json_filename]
./clip_demo vision_model_int8_A311D2.adla ./clip_datasets/ clip_text_res.json
```
**Note:**
- Replace `vision_model_int8_A311D2.adla` with your actual model file path.
- The `base_dir` and `json_filename` parameters are optional. You can also use environment variables `CLIP_BASE_DIR` and `CLIP_JSON_FILENAME`.
- The program will prompt you to enter image paths interactively. Enter "exit" to quit.
### Python
**Prerequisites:**
- Python 3.10
- Required packages: `numpy`, `Pillow`, `amlnnlite`
**Install dependencies:**
```bash
pip install numpy Pillow amlnnlite-1.0.0-cp310-cp310-linux_aarch64.whl
```
**Run on device:**
```bash
# Basic usage (process current directory)
python clip.py --model-path ./vision_model_int8_A311D2.adla
# Specify image directory or file
python clip.py --model-path ./vision_model_int8_A311D2.adla --image-dir ./
# Specify base directory and JSON filename
python clip.py --model-path ./vision_model_int8_A311D2.adla --base-dir ./clip_datasets/ --json-filename clip_text_res.json
```
The script will automatically process all image files (`.jpg`, `.jpeg`, `.png`, `.bmp`) in the specified directory or process a single image file, and display the best matching dataset for each image.
5. Results
The program will print the best matching dataset path for each processed image. The program searches through all dataset folders in the base directory and finds the text feature with the highest similarity to the input image.
**Example output:**
```
# python demo result
Model initialized successfully.
Found 2 image file(s) to process
Searching in base directory: ./clip_datasets/
Processing image: test_jacket_0.jpg
Best matching dataset: ./clip_datasets/shirt10_jacket7
Searching in base directory: ./clip_datasets/
Processing image: test_hat_0.jpg
Best matching dataset: ./clip_datasets/hat1_jd
Total results: 2
Index[0]: ./clip_datasets/shirt10_jacket7
Index[1]: ./clip_datasets/hat1_jd
Done.
```
The program returns the dataset folder path that contains the text feature with the highest similarity to the input image. Each result represents the best matching dataset for the corresponding input image.

304
examples/clip/py/clip.py Executable file
View file

@ -0,0 +1,304 @@
import numpy as np
import os
import argparse
import json
import re
from PIL import Image
from amlnnlite.api import AMLNNLite
def preprocess_image(image_path: str, target_size: int = 224) -> np.ndarray:
"""
Preprocess image for CLIP model.
Steps:
1. Load image and convert to RGB
2. Scale the shorter side to target_size
3. Center crop to target_size x target_size
4. Normalize with CLIP mean and std
Args:
image_path (str): Path to input image
target_size (int): Target image size (default: 224)
Returns:
np.ndarray: Preprocessed image data with shape (target_size, target_size, 3)
"""
# Load image
img = Image.open(image_path).convert("RGB")
width, height = img.size
# Scale the shorter side
scale = target_size / min(width, height)
new_w = int(round(width * scale))
new_h = int(round(height * scale))
# Resize
img = img.resize((new_w, new_h), Image.BILINEAR)
# Center crop
left = (new_w - target_size) // 2
top = (new_h - target_size) // 2
img = img.crop((left, top, left + target_size, top + target_size))
# Convert to numpy array and normalize to [0, 1]
img_array = np.array(img, dtype=np.float32) / 255.0
# CLIP normalization
mean = np.array([0.48145466, 0.4578275, 0.40821073], dtype=np.float32)
std = np.array([0.26862954, 0.26130258, 0.27577711], dtype=np.float32)
# Normalize: (x - mean) / std
img_array = (img_array - mean) / std
# Return in NHWC format
return img_array
def post_process(
image_features: np.ndarray,
text_features: np.ndarray,
scale: float = 100.00000762939453,
use_cosine: bool = True,
apply_scale: bool = True,
) -> float:
"""
Calculate similarity between image and text features.
Args:
image_features (np.ndarray): Image feature vector
text_features (np.ndarray): Text feature vector
scale (float): Scale factor for similarity calculation
use_cosine (bool): If True, L2-normalize both vectors before dot product (cosine similarity)
apply_scale (bool): If True, multiply by scale after dot product
Returns:
float: Similarity score
"""
img_vec = image_features.flatten().astype(np.float32)
txt_vec = np.array(text_features, dtype=np.float32).flatten()
if len(img_vec) != len(txt_vec):
raise ValueError(f"Feature dimension mismatch: image={len(img_vec)}, text={len(txt_vec)}")
if use_cosine:
img_norm = np.linalg.norm(img_vec) + 1e-8
txt_norm = np.linalg.norm(txt_vec) + 1e-8
img_vec = img_vec / img_norm
txt_vec = txt_vec / txt_norm
dot_product = np.dot(img_vec, txt_vec)
similarity = dot_product * scale if apply_scale else dot_product
return float(similarity)
def extract_index(filename: str) -> int:
"""
Extract index from filename pattern: test_xxx_index.jpg
Args:
filename (str): Filename to extract index from
Returns:
int: Extracted index, or -1 if pattern doesn't match
"""
pattern = r"test_\w+_(\d+)\.jpg"
match = re.match(pattern, filename)
if match:
return int(match.group(1))
return -1
def process_image_dir(
amlnn: AMLNNLite,
image_dir_path: str,
base_dir: str = "",
json_filename: str = ""
) -> list:
"""
Process image directory and find best matching text dataset.
Args:
amlnn: AMLNNLite instance
image_dir_path (str): Path to directory containing test images
base_dir (str): Base directory for clip datasets (optional, can use CLIP_BASE_DIR env var)
json_filename (str): JSON filename in each dataset folder (optional, can use CLIP_JSON_FILENAME env var)
Returns:
list: List of best matching dataset paths
"""
results = []
file_pattern = re.compile(r"test_(\w+)_\d+\.jpg")
image_extensions = {'.jpg', '.jpeg', '.png', '.bmp', '.JPG', '.JPEG', '.PNG', '.BMP'}
if not base_dir:
base_dir = os.getenv("CLIP_BASE_DIR", "./clip_datasets/")
if not json_filename:
json_filename = os.getenv("CLIP_JSON_FILENAME", "clip_text_res.json")
matched_files = []
if os.path.isdir(image_dir_path):
for filename in os.listdir(image_dir_path):
filepath = os.path.join(image_dir_path, filename)
if os.path.isfile(filepath):
if file_pattern.match(filename):
matched_files.append((filename, filepath, True))
elif any(filename.lower().endswith(ext) for ext in image_extensions):
matched_files.append((filename, filepath, False))
elif os.path.isfile(image_dir_path):
filename = os.path.basename(image_dir_path)
if any(filename.lower().endswith(ext) for ext in image_extensions):
has_pattern = bool(file_pattern.match(filename))
matched_files.append((filename, image_dir_path, has_pattern))
else:
print(f"Error: {image_dir_path} is not a valid image file")
return results
else:
print(f"Error: {image_dir_path} is not a valid directory or file")
return results
if not matched_files:
print(f"Warning: No image files found in {image_dir_path}")
return results
print(f"Found {len(matched_files)} image file(s) to process")
matched_files.sort(key=lambda x: extract_index(x[0]) if x[2] else 999999)
# Process each image
for filename, filepath, has_pattern in matched_files:
if has_pattern:
match = file_pattern.match(filename)
if match:
name = match.group(1)
else:
name = ""
else:
name = ""
# Preprocess image
try:
input_data = preprocess_image(filepath)
input_data = np.expand_dims(input_data, axis=0)
except Exception as e:
print(f"Error preprocessing image {filename}: {e}")
continue
# Run inference
try:
outputs = amlnn.inference(inputs=[input_data])
model_output = outputs[0]
if isinstance(model_output, np.ndarray):
model_output = model_output.astype(np.float32)
else:
model_output = np.array(model_output, dtype=np.float32)
model_output = model_output.flatten()
except Exception as e:
print(f"Error running inference on {filename}: {e}")
continue
max_sim = float('-inf')
best_key = ""
best_id = ""
if not os.path.isdir(base_dir):
print(f"Error: Base directory does not exist: {base_dir}")
continue
print(f"Searching in base directory: {base_dir}")
folder_count = 0
for folder_name in os.listdir(base_dir):
folder_path = os.path.join(base_dir, folder_name)
if not os.path.isdir(folder_path):
continue
if has_pattern and name and name not in folder_name:
continue
folder_count += 1
vit_res_path = os.path.join(folder_path, json_filename)
if not os.path.isfile(vit_res_path):
print(f"Warning: JSON file not found: {vit_res_path}")
continue
try:
with open(vit_res_path, 'r', encoding='utf-8') as f:
vit_json = json.load(f)
for key, text_vec in vit_json.items():
if isinstance(text_vec, list):
text_features = np.array(text_vec, dtype=np.float32)
sim_scaled = post_process(
model_output,
text_features,
use_cosine=True,
apply_scale=True,
)
if sim_scaled > max_sim:
max_sim = sim_scaled
best_key = key
best_id = folder_name
except Exception as e:
print(f"Error loading JSON file {vit_res_path}: {e}")
continue
if best_key and best_id:
best_path = os.path.join(base_dir, best_id)
results.append(best_path)
print(f"\nProcessing image: {filename}")
print(f" Best matching dataset: {best_path}")
else:
print(f"\nProcessing image: {filename}")
print(f" No matching dataset found (searched {folder_count} folder(s))")
return results
def main():
parser = argparse.ArgumentParser(description='CLIP Image-Text Matching Demo')
parser.add_argument('--model-path', required=True, help='Path to the CLIP model file')
parser.add_argument('--base-dir', default='./clip_datasets/', help='Base directory for clip datasets (can also use CLIP_BASE_DIR env var)')
parser.add_argument('--json-filename', default='clip_text_res.json', help='JSON filename in each dataset folder (can also use CLIP_JSON_FILENAME env var, default: clip_text_res.json)')
parser.add_argument('--image-dir', default='./', help='Image directory or single image file to process (optional, will prompt if not provided)')
args = parser.parse_args()
# Initialize AMLNNLite
print("Initializing model...")
amlnn = AMLNNLite()
amlnn.config(model_path=args.model_path)
amlnn.init()
print("Model initialized successfully.\n")
# Process images
if args.image_dir:
results = process_image_dir(amlnn, args.image_dir, args.base_dir, args.json_filename)
print(f"\nTotal results: {len(results)}")
for i, result in enumerate(results):
print(f"Index[{i}]: {result}")
else:
while True:
image_path = input("\nPlease enter the JPG image path or directory (enter 'exit' to quit):\n").strip()
if image_path.lower() == 'exit':
break
if not image_path:
print("The path cannot be empty.")
continue
results = process_image_dir(amlnn, image_path, args.base_dir, args.json_filename)
for i, result in enumerate(results):
print(f"Index[{i}]: {result}")
amlnn.uninit()
print("\nDone.")
if __name__ == "__main__":
main()

View file

@ -0,0 +1,106 @@
## Demo Run
### CPP
#### 1. Compile
**Prerequisites:**
- Android NDK (r25e recommended)
- `ANDROID_NDK_PATH` environment variable set
**Build:**
```bash
# Build for arm64-v8a
cd examples/mobilenet/cpp
./build-android.sh -a arm64-v8a
```
The executable will be generated at `build/android/mobilenet_v2_demo` (Note: executable name may vary, verify in build folder).
#### 2. Run
```bash
# Push executable to device
adb push build/android/mobilenet_v2_demo /data/local/tmp/
adb push model/mobilenet_v2_1.0_224_quant_A311D2.adla /data/local/tmp/
adb push model/cat_224x224.jpg /data/local/tmp/
adb push model/labels.txt /data/local/tmp/
# Run on device
adb shell
cd /data/local/tmp
chmod +x mobilenet_v2_demo
export LD_LIBRARY_PATH=/vendor/lib64 or (/vendor/lib)
# Usage: ./mobilenet_v2_demo <model_path> <image_path> <labels_path>
./mobilenet_v2_demo mobilenet_v2_1.0_224_quant_A311D2.adla cat_224x224.jpg labels.txt
```
**Note:** Replace `mobilenet_v2_1.0_224_quant_A311D2.adla` with your actual model file path.
### Python
**Prerequisites:**
- Python 3.10
- Required packages: `numpy`, `Pillow`, `amlnnlite`
**Install dependencies:**
```bash
pip install numpy Pillow amlnnlite-1.0.0-cp310-cp310-linux_aarch64.whl
```
**Run on device:**
```bash
# Basic usage
python mobilenetv2.py --model-path ./mobilenet_v2_1.0_224_quant_A311D2.adla
# Run with performance testing (100 cycles)
python mobilenetv2.py --model-path ./mobilenet_v2_1.0_224_quant_A311D2.adla --run-cycles 100
```
The script will automatically process all image files (`.jpg`, `.jpeg`, `.png`, `.bmp`) in the current directory and display top-5 classification results for each image.
## Results
The program will print the top-5 classification results with probabilities for each processed image.
**Example output:**
```
# python demo result
============================================================
Processing image 1/3: dog_224x224.jpg
============================================================
Top-5 Classification Results:
1. Shih-Tzu (probability: 0.9239)
2. Pekinese (probability: 0.0476)
3. Lhasa (probability: 0.0263)
4. Brabancon griffon (probability: 0.0004)
5. Dandie Dinmont (probability: 0.0003)
============================================================
Processing image 2/3: cat_224x224.jpg
============================================================
Top-5 Classification Results:
1. tiger cat (probability: 0.4774)
2. tabby (probability: 0.4324)
3. Egyptian cat (probability: 0.0542)
4. lynx (probability: 0.0150)
5. Persian cat (probability: 0.0025)
============================================================
Processing image 3/3: fish_224x224.jpeg
============================================================
Top-5 Classification Results:
1. goldfish (probability: 0.9998)
2. conch (probability: 0.0001)
3. trifle (probability: 0.0000)
4. axolotl (probability: 0.0000)
5. American lobster (probability: 0.0000)
```
The classification results show the model's confidence scores (probabilities) for each detected class, with the highest probability indicating the most likely classification.

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,158 @@
import numpy as np
import os
import glob
import argparse
import time
from PIL import Image
from amlnnlite.api import AMLNNLite
def preprocess(image_path: str) -> np.ndarray:
"""
Preprocess the input image for MobileNetV2 quantized model.
Steps:
1. Load image and convert to RGB
2. Resize to 224x224
3. Normalize to [-1, 1]
4. Quantize to uint8 with zero-point = 128, scale = 0.0078125
Args:
image_path (str): Path to input image
Returns:
np.ndarray: Preprocessed image data with shape (1, 224, 224, 3)
"""
img = Image.open(image_path).convert("RGB").resize((224, 224))
img = np.array(img, dtype=np.float32)
# Normalize to [-1, 1]
img = img / 127.5 - 1.0
# Expand batch dimension
data = np.expand_dims(img, axis=0)
# Quantization (uint8)
data = data / 0.0078125 + 128
data = np.clip(data, 0, 255).astype(np.uint8)
return data
def postprocess_topk(predictions: np.ndarray, labels_path: str, k: int = 5, use_softmax: bool = True) -> None:
"""
Postprocess model output and print top-K classification results.
Args:
predictions (np.ndarray): Raw model output (logits)
labels_path (str): Path to labels.txt
k (int): Number of top results to display
use_softmax (bool): If True, apply softmax to convert logits to probabilities
"""
predictions = predictions.reshape(-1).astype(np.float32)
if use_softmax:
exp_predictions = np.exp(predictions - np.max(predictions))
probabilities = exp_predictions / np.sum(exp_predictions)
scores = probabilities
score_label = "probability"
else:
scores = predictions
score_label = "score"
# Load labels
with open(labels_path, "r", encoding="utf-8") as f:
labels = [line.strip() for line in f.readlines()]
# Get top-k indices based on scores
top_indices = np.argsort(scores)[::-1][:k]
print(f"\nTop-{k} Classification Results:")
for rank, idx in enumerate(top_indices, start=1):
label = labels[idx] if idx < len(labels) else f"Class {idx}"
score = scores[idx]
if use_softmax:
print(f" {rank}. {label:<25} ({score_label}: {score:.4f})")
else:
print(f" {rank}. {label:<25} ({score_label}: {score:.6f})")
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--model-path', default='./mobilenet_v2_1.0_224_quant.tflite')
parser.add_argument('--run-cycles', type=int, default=1, help='Number of inference cycles to run (for performance testing)')
args = parser.parse_args()
# Initialize AMLNNLite
amlnn = AMLNNLite()
amlnn.config(
model_path=args.model_path # Model file path, Support ADLD and quantized TFlite models
)
amlnn.init()
# Find all image files in the 01_export_model directory
image_dir = "./"
image_extensions = ["*.jpg", "*.jpeg", "*.png", "*.bmp"]
image_files = []
for ext in image_extensions:
image_files.extend(glob.glob(os.path.join(image_dir, ext)))
image_files.extend(glob.glob(os.path.join(image_dir, ext.upper())))
if not image_files:
print("No image files found in", image_dir)
amlnn.uninit()
return
print(f"Found {len(image_files)} image files to process:")
for img_file in image_files:
print(f" - {os.path.basename(img_file)}")
print()
# Process each image
for i, image_path in enumerate(image_files, 1):
print(f"=" * 60)
print(f"Processing image {i}/{len(image_files)}: {os.path.basename(image_path)}")
print(f"=" * 60)
try:
# Preprocess input
input_data = preprocess(image_path)
# Run inference for specified cycles
inference_times = []
outputs = None
for cycle in range(args.run_cycles):
start_time = time.time()
outputs = amlnn.inference(
inputs=[input_data]
)
inference_time = (time.time() - start_time) * 1000 # Convert to milliseconds
inference_times.append(inference_time)
# Print performance statistics if running multiple cycles
if args.run_cycles > 1:
avg_time = np.mean(inference_times)
min_time = np.min(inference_times)
max_time = np.max(inference_times)
print(f"\nInference Performance ({args.run_cycles} cycles):")
print(f" Average: {avg_time:.2f} ms")
print(f" Min: {min_time:.2f} ms")
print(f" Max: {max_time:.2f} ms")
# Postprocess results (only show results from last inference)
postprocess_topk(outputs[0], "./labels.txt", k=5, use_softmax=True)
except Exception as e:
print(f"Error processing {os.path.basename(image_path)}: {e}")
print()
# Optional visualization
amlnn.visualize()
# Release resources
amlnn.uninit()
if __name__ == "__main__":
main()

View file

@ -0,0 +1,165 @@
# resnet
## 1.Overview
## 2.Model Download
- **Open Source model**
- **Open Source projects:**
- **Export Model Step:**
- **Install ultralytics**
pip install torch==2.4.1
pip install torchvision==0.19.1
pip install ultralytics==8.3.0
- **Download weights**
- **Export Model**
```
```
- **Exported Model**
link to amlogic server( **onnx model or quantized tflite**)
## 3. Model Conversion
```
cd model
Usage: ./adla_covnert.sh model_path adla_tookkit_path target_platform
example
```
| Parameter | Discription |
| ----------------- | ------------------------------------------------------------ |
| model_path | onnx model path |
| adla_tookkit_path | path to adla_toolkit |
| target_platform | Specify target platform. for A311D2 : PRODUCT_PID0XA003. for S905X5: PRODUCT_PID0XA005 |
## 4. Demo Run
### CPP
#### 1. Compile
**Prerequisites:**
- Android NDK (r25e recommended)
- `ANDROID_NDK_PATH` environment variable set
**Build:**
```bash
# Build for arm64-v8a
cd examples/resnet/cpp
./build-android.sh -a arm64-v8a
```
The executable will be generated at `build/android/resnet_demo` (Note: executable name may vary, verify in build folder).
#### 2. Run
```bash
# Push executable to device
adb push build/android/resnet_demo /data/local/tmp/
adb push model/res2net50_int8_A311D2.adla /data/local/tmp/
adb push imgs /data/local/tmp/
adb push labels.txt /data/local/tmp/
# Run on device
adb shell
cd /data/local/tmp
chmod +x resnet_demo
export LD_LIBRARY_PATH=/vendor/lib64 or (/vendor/lib)
# Usage: ./resnet_demo <model_path> <image_dir> <labels.txt>
./resnet_demo res2net50_int8_A311D2.adla imgs/ labels.txt
```
**Note:** Replace `res2net50_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
python resnet.py \
--model-path ./res2net50_int8_A311D2.adla \
--image-dir ./imgs \
--labels labels.txt \
--run-cycles 1 \
--loglevel INFO
```
Argument Descriptions:
| Argument | Description |
| ----------------- | ------------------------------------------------------------ |
| --board-work-path | Work path on board, default is /data/local/tmp |
| --model-path | path to .adla model |
| --image-dir | Directory containing test images |
| --labels | Path to synset_words.txt or labels.txt |
| --run-cycles | Number of inference cycles, default is 1 |
| --loglevel | Logging level: DEBUG / INFO / WARNING / ERROR, default is WARNING |
The script will automatically process all image files (`.jpg`, `.jpeg`, `.png`, `.bmp`) in the current directory and save results to a `{model_name}_result` folder.
## 5.Results
**Performance Feedback**
By setting the loglevel to INFO, the program provides real-time performance metrics upon completion. The console log will display essential hardware and execution details, including:
- Hardware Information: System and ADLA library versions.
- Model Overview: Basic input/output configurations.
- NPU Metrics: Total inference time (latency) and total DRAM bandwidth consumption.
**Classification Output**
For each image, the program prints the Top-5 classification results with their respective scores:
```bash
============================================================
Processing image 1/1: dog.jpg
============================================================ Top-5 Results:
1: Pekinese score=9.851644
2: West Highland white terrier score=5.055449
3: Maltese dog score=4.796195
4: basenji score=3.111045
5: Scotch terrier score=2.786978 ============================================================
```
**Profiling Visualization**
After a successful run of the Python demo, a folder named after the model (e.g., `{model_name}`) will be generated in the script directory. This folder contains 5 HTML files that provide a visual and detailed breakdown of per-layer performance:
- `hard_op_chart.html` & `soft_op_chart.html`: Hardware/Software op execution details.
- `dram_rd_chart.html` & `dram_wr_chart.html`: Bandwidth read/write distribution.
- `pie_charts_distribution.html`: Overall resource allocation.
You can pull the result folder back to view it:
```bash
adb pull /data/local/tmp/res2net50_int8_A311D2
```
Taking hard_op_chart.html as an example (shown below), each layer's ADLA operator name includes parentheses containing the index of the corresponding quantized .tflite layer(s); by default, these indices are suppressed, and operators are labeled generically as "hardware" or "software" without numerical suffixes.
![alt text](Visualization.png)

BIN
examples/resnet/Visualization.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View file

@ -52,8 +52,8 @@ def postprocess_topk(logits, labels, k=5):
def main(): def main():
parser = argparse.ArgumentParser(description="Classification AMLNNLite Demo") parser = argparse.ArgumentParser(description="Classification AMLNNLite Demo")
parser.add_argument('--board-work-path', default='/data/nn', help='Work path on board') parser.add_argument('--board-work-path', default='/data/local/tmp', help='Work path on board')
parser.add_argument('--model-path', required=True, help='Path to .adla or .tflite model') parser.add_argument('--model-path', required=True, help='Path to .adla model')
parser.add_argument('--image-dir', required=True, help='Directory containing test images') parser.add_argument('--image-dir', required=True, help='Directory containing test images')
parser.add_argument('--labels', required=True, help='Path to synset_words.txt or labels.txt') parser.add_argument('--labels', required=True, help='Path to synset_words.txt or labels.txt')
parser.add_argument('--run-cycles', type=int, default=1, help='Number of inference cycles') parser.add_argument('--run-cycles', type=int, default=1, help='Number of inference cycles')

View file

@ -0,0 +1,160 @@
# retinaface
## 1.Overview
## 2.Model Download
- **Open Source model**
- **Open Source projects:**
- **Export Model Step:**
- **Install ultralytics**
pip install torch==2.4.1
pip install torchvision==0.19.1
pip install ultralytics==8.3.0
- **Download weights**
- **Export Model**
- **Exported Model**
link to amlogic server( **onnx model or quantized tflite**)
## 3. Model Conversion
```
cd model
Usage: ./adla_covnert.sh model_path adla_tookkit_path target_platform
example
```
| Parameter | Discription |
| ----------------- | ------------------------------------------------------------ |
| model_path | onnx model path |
| adla_tookkit_path | path to adla_toolkit |
| target_platform | Specify target platform. for A311D2 : PRODUCT_PID0XA003. for S905X5: PRODUCT_PID0XA005 |
## 4. Demo Run
### CPP
#### 1. Compile
**Prerequisites:**
- Android NDK (r25e recommended)
- `ANDROID_NDK_PATH` environment variable set
**Build:**
```bash
# Build for arm64-v8a
cd examples/retinaface/cpp
./build-android.sh -a arm64-v8a
```
The executable will be generated at `build/android/retinaface_demo` (Note: executable name may vary, verify in build folder).
#### 2. Run
```bash
# Push executable to device
adb push build/android/retinaface_demo /data/local/tmp/
adb push model/RetinaFace_int8_A311D2.adla /data/local/tmp/
adb push imgs /data/local/tmp/
# Run on device
adb shell
cd /data/local/tmp
chmod +x retinaface_demo
export LD_LIBRARY_PATH=/vendor/lib64 or (/vendor/lib)
# Usage: ./retinaface_demo <model_path> <image_dir>
./retinaface_demo RetinaFace_int8_A311D2.adla ./imgs
```
**Note:** Replace `RetinaFace_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
python RetinaFace.py \
--model-path ./RetinaFace_int8_A311D2.adla \
--image-dir ./imgs \
--run-cycles 1 \
--loglevel INFO
```
Argument Descriptions:
| Argument | Description |
| ----------------- | ------------------------------------------------------------ |
| --board-work-path | Work path on board, default is /data/local/tmp |
| --model-path | path to .adla model |
| --image-dir | Directory containing test images |
| --run-cycles | Number of inference cycles, default is 1 |
| --loglevel | Logging level: DEBUG / INFO / WARNING / ERROR, default is WARNING |
The script will automatically process all image files (`.jpg`, `.jpeg`, `.png`, `.bmp`) in the current directory and save results to a `{model_name}_result` folder.
## 5.Results
**Performance Feedback**
By setting the loglevel to INFO, the program provides real-time performance metrics upon completion. The console log will display essential hardware and execution details, including:
- Hardware Information: System and ADLA library versions.
- Model Overview: Basic input/output configurations.
- NPU Metrics: Total inference time (latency) and total DRAM bandwidth consumption.
**Detection Output**
The program will print the detection count. The output images, featuring bounding boxes and five facial landmarks (eyes, nose, and mouth corners), will be saved to the `{model_name}_result` folder.
You can pull the result folder back to view it:
```bash
adb pull /data/local/tmp/RetinaFace_int8_A311D2_result
```
![alt text](result.jpg)
**Profiling Visualization**
After a successful run of the Python demo, a folder named after the model (e.g., `{model_name}`) will be generated in the script directory. This folder contains 5 HTML files that provide a visual and detailed breakdown of per-layer performance:
- `hard_op_chart.html` & `soft_op_chart.html`: Hardware/Software op execution details.
- `dram_rd_chart.html` & `dram_wr_chart.html`: Bandwidth read/write distribution.
- `pie_charts_distribution.html`: Overall resource allocation.
You can pull the result folder back to view it:
```bash
adb pull /data/local/tmp/RetinaFace_int8_A311D2
```
Taking hard_op_chart.html as an example (shown below), each layer's ADLA operator name includes parentheses containing the index of the corresponding quantized .tflite layer(s); by default, these indices are suppressed, and operators are labeled generically as "hardware" or "software" without numerical suffixes.
![alt text](Visualization.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View file

@ -55,7 +55,8 @@ int main(int argc, char** argv) {
size_t num_priors = priors.size(); size_t num_priors = priors.size();
std::vector<float> chw_buffer(kInputW * kInputH * 3); std::vector<float> chw_buffer(kInputW * kInputH * 3);
const std::string out_dir = "retinaface_result"; std::string model_stem = fs::path(argv[1]).stem().string();
const std::string out_dir = model_stem + "_result";
fs::create_directory(out_dir); fs::create_directory(out_dir);
std::vector<fs::path> image_paths; std::vector<fs::path> image_paths;

View file

@ -107,7 +107,7 @@ def preprocess(img_path, input_size=(320, 320)):
def main(): def main():
parser = argparse.ArgumentParser(description="RetinaFace AMLNNLite Demo") parser = argparse.ArgumentParser(description="RetinaFace AMLNNLite Demo")
parser.add_argument('--board-work-path', type=str, default='/data/nn') parser.add_argument('--board-work-path', type=str, default='/data/local/tmp')
parser.add_argument('--model-path', required=True, help='Path to .adla model') parser.add_argument('--model-path', required=True, help='Path to .adla model')
parser.add_argument('--image-dir', required=True, help='Directory of test images') parser.add_argument('--image-dir', required=True, help='Directory of test images')
parser.add_argument('--run-cycles', type=int, default=1, help='Inference cycles') parser.add_argument('--run-cycles', type=int, default=1, help='Inference cycles')
@ -122,13 +122,18 @@ def main():
amlnn.init() amlnn.init()
priors = PriorBox((320, 320)).forward() priors = PriorBox((320, 320)).forward()
image_files = sorted(glob.glob(os.path.join(args.image_dir, "*.[jp][pn][g]"))) image_files = []
for ext in ["*.jpg", "*.jpeg", "*.png", "*.bmp"]:
image_files.extend(glob.glob(os.path.join(args.image_dir, ext)))
image_files.extend(glob.glob(os.path.join(args.image_dir, ext.upper())))
image_files.sort()
if not image_files: if not image_files:
print(f"No images found in {args.image_dir}") print(f"No images found in {args.image_dir}")
amlnn.uninit(); return amlnn.uninit(); return
res_dir = "retinaface_result" model_stem = Path(args.model_path).stem
res_dir = f"{model_stem}_result"
os.makedirs(res_dir, exist_ok=True) os.makedirs(res_dir, exist_ok=True)
for idx, img_path in enumerate(image_files, start=1): for idx, img_path in enumerate(image_files, start=1):

BIN
examples/retinaface/result.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

View file

@ -0,0 +1,170 @@
# yolov11
## 1.Overview
YOLOv11 was released by Ultralytics on October 2, 2024. It introduces significant architectural refinements and efficiency optimizations, delivering superior accuracy-speed trade-offs compared to previous generations. With enhanced feature extraction capabilities, YOLOv11 is designed for high-performance real-time applications—including object detection, instance segmentation, and pose estimation—to handle demanding tasks in a wide range of applications.
## 2.Model Download
- **Open Source model**
- **Open Source projects:** https://github.com/ultralytics/ultralytics/tree/v8.3.0
- **Export Model Step:**
- **Install ultralytics**
pip install torch==2.4.1
pip install torchvision==0.19.1
pip install ultralytics==8.3.0
- **Download weights**
wget https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11m.pt
wget https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11s.pt
wget https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11n.pt
- **Export Model**
```
from ultralytics import YOLO
model = YOLO("yolo11n.pt")
model.export(format="onnx", opset=12, simplify=True, dynamic=False, imgsz=640)
```
- **Exported Model**
link to amlogic server( **onnx model or quantized tflite**)
## 3. Model Conversion
```
cd model
Usage: ./adla_covnert.sh model_path adla_tookkit_path target_platform
example
./adla_covnert.sh yolov11m.onnx /xxxx/adla-toolkit-binary-3.2.9.3 PRODUCT_PID0XA005
./adla_covnert.sh yolov11s.onnx /xxxx/adla-toolkit-binary-3.2.9.3 PRODUCT_PID0XA005
./adla_covnert.sh yolov11n.onnx /xxxx/adla-toolkit-binary-3.2.9.3 PRODUCT_PID0XA005
```
| Parameter | Discription |
| ----------------- | ------------------------------------------------------------ |
| model_path | onnx model path |
| adla_tookkit_path | path to adla_toolkit |
| target_platform | Specify target platform. for A311D2 : PRODUCT_PID0XA003. for S905X5: PRODUCT_PID0XA005 |
## 4. Demo Run
### CPP
#### 1. Compile
**Prerequisites:**
- Android NDK (r25e recommended)
- `ANDROID_NDK_PATH` environment variable set
**Build:**
```bash
# Build for arm64-v8a
cd examples/yolov11/cpp
./build-android.sh -a arm64-v8a
```
The executable will be generated at `build/android/yolo11_demo` (Note: executable name may vary, verify in build folder).
#### 2. Run
```bash
# Push executable to device
adb push build/android/yolo11_demo /data/local/tmp/
adb push model/yolov11n_int8_A311D2.adla /data/local/tmp/
adb push imgs /data/local/tmp/
# Run on device
adb shell
cd /data/local/tmp
chmod +x yolo11_demo
export LD_LIBRARY_PATH=/vendor/lib64 or (/vendor/lib)
# Usage: ./yolo11_demo <model_path> <image_dir>
./yolo11_demo yolov11n_int8_A311D2.adla ./imgs
```
**Note:** Replace `yolov11n_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
python yolov11.py \
--model-path ./yolov11n_int8_A311D2.adla \
--image-dir ./imgs \
--run-cycles 1 \
--loglevel INFO
```
Argument Descriptions:
| Argument | Description |
| ----------------- | ------------------------------------------------------------ |
| --board-work-path | Work path on board, default is /data/local/tmp |
| --model-path | path to .adla model |
| --image-dir | Directory containing test images |
| --run-cycles | Number of inference cycles, default is 1 |
| --loglevel | Logging level: DEBUG / INFO / WARNING / ERROR, default is WARNING |
The script will automatically process all image files (`.jpg`, `.jpeg`, `.png`, `.bmp`) in the current directory and save results to a `{model_name}_result` folder.
## 5.Results
**Performance Feedback**
By setting the loglevel to INFO, the program provides real-time performance metrics upon completion. The console log will display essential hardware and execution details, including:
- Hardware Information: System and ADLA library versions.
- Model Overview: Basic input/output configurations.
- NPU Metrics: Total inference time (latency) and total DRAM bandwidth consumption.
**Detection Output**
The program will print the detection count. The result image with bounding boxes will be saved to the specified output path (`{model_name}_result`).
You can pull the result folder back to view it:
```bash
adb pull /data/local/tmp/yolov11n_int8_A311D2_result
```
![alt text](result.jpg)
**Profiling Visualization**
After a successful run of the Python demo, a folder named after the model (e.g., `{model_name}`) will be generated in the script directory. This folder contains 5 HTML files that provide a visual and detailed breakdown of per-layer performance:
- `hard_op_chart.html` & `soft_op_chart.html`: Hardware/Software op execution details.
- `dram_rd_chart.html` & `dram_wr_chart.html`: Bandwidth read/write distribution.
- `pie_charts_distribution.html`: Overall resource allocation.
You can pull the result folder back to view it:
```bash
adb pull /data/local/tmp/yolov11n_int8_A311D2
```
Taking hard_op_chart.html as an example (shown below), each layer's ADLA operator name includes parentheses containing the index of the corresponding quantized .tflite layer(s); by default, these indices are suppressed, and operators are labeled generically as "hardware" or "software" without numerical suffixes.
![alt text](Visualization.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View file

@ -93,8 +93,8 @@ def postprocess(outputs, scale, pad, strides=[32,16,8], conf_threshold=0.25, iou
def main(): def main():
parser = argparse.ArgumentParser(description="YOLOV11 AMLNNLite Demo") parser = argparse.ArgumentParser(description="YOLOV11 AMLNNLite Demo")
parser.add_argument('--board-work-path', default='/data/nn', help='Work path on board') parser.add_argument('--board-work-path', default='/data/local/tmp', help='Work path on board')
parser.add_argument('-m', '--model-path', required=True, help='Path to .adla or .tflite model') parser.add_argument('-m', '--model-path', required=True, help='Path to .adla model')
parser.add_argument('--image-dir', required=True, help='Directory containing test images') parser.add_argument('--image-dir', required=True, help='Directory containing test images')
parser.add_argument('--run-cycles', type=int, default=1, help='Inference cycles for profiling') parser.add_argument('--run-cycles', type=int, default=1, help='Inference cycles for profiling')
parser.add_argument('--loglevel', default='WARNING', choices=['DEBUG', 'INFO', 'WARNING', 'ERROR'], help='Log level') parser.add_argument('--loglevel', default='WARNING', choices=['DEBUG', 'INFO', 'WARNING', 'ERROR'], help='Log level')
@ -110,7 +110,7 @@ def main():
amlnn.init() amlnn.init()
image_files = [] image_files = []
for ext in ["*.jpg", "*.jpeg", "*.png"]: for ext in ["*.jpg", "*.jpeg", "*.png", "*.bmp"]:
image_files.extend(glob.glob(os.path.join(args.image_dir, ext))) image_files.extend(glob.glob(os.path.join(args.image_dir, ext)))
image_files.extend(glob.glob(os.path.join(args.image_dir, ext.upper()))) image_files.extend(glob.glob(os.path.join(args.image_dir, ext.upper())))
image_files.sort() image_files.sort()

BIN
examples/yolov11/result.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

BIN
examples/yolov8/model/test.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

View file

@ -390,7 +390,6 @@ Examples:
traceback.print_exc() traceback.print_exc()
return 1 return 1
# Use try-finally to ensure resources are released
try: try:
# Find all image files in the specified directory # Find all image files in the specified directory
image_dir = args.image_dir image_dir = args.image_dir
@ -493,7 +492,6 @@ Examples:
amlnn.visualize() amlnn.visualize()
print("Visualization charts saved.") print("Visualization charts saved.")
finally: finally:
# Always release resources
if amlnn is not None: if amlnn is not None:
print("\nReleasing resources...") print("\nReleasing resources...")
amlnn.uninit() amlnn.uninit()

View file