diff --git a/models/cv/classification/clip/ixrt/README.md b/models/cv/classification/clip/ixrt/README.md new file mode 100644 index 0000000000000000000000000000000000000000..4eb88cb74d106f7bf319cd1be7281014d9fb4995 --- /dev/null +++ b/models/cv/classification/clip/ixrt/README.md @@ -0,0 +1,63 @@ +# CLIP (IxRT) + +## Model Description + +CLIP (Contrastive Language-Image Pre-Training) is a neural network trained on a variety of (image, text) pairs. It can be instructed in natural language to predict the most relevant text snippet, given an image, without directly optimizing for the task, similarly to the zero-shot capabilities of GPT-2 and 3. + +## Supported Environments + +| GPU | [IXUCA SDK](https://gitee.com/deep-spark/deepspark#%E5%A4%A9%E6%95%B0%E6%99%BA%E7%AE%97%E8%BD%AF%E4%BB%B6%E6%A0%88-ixuca) | Release | +| :----: | :----: | :----: | +| MR-V100 | 4.3.0 | 25.09 | + +## Model Preparation + +### Prepare Resources + +Pretrained model: + +Dataset: to download the validation dataset. + +```bash +git lfs install +git clone https://huggingface.co/openai/clip-vit-base-patch32 clip-vit-base-patch32 +``` + +### Install Dependencies + +```bash +pip3 install -r requirements.txt +``` + +### Model Conversion + +```bash +python3 export.py --output clip.onnx +``` + +## Model Inference + +```bash +git clone https://gitee.com/deep-spark/iluvatar-corex-ixrt.git --depth=1 +export OPTIMIER_FILE=./iluvatar-corex-ixrt/tools/optimizer/optimizer.py +export DATASETS_DIR=/path/to/imagenet_val/ +export PROJ_DIR=./ +export CHECKPOINTS_DIR=./ +export RUN_DIR=./ +export CONFIG_DIR=../../ixrt_common/config/CLIP_CONFIG +``` + +### FP16 + +```bash +# Accuracy +bash scripts/infer_clip_fp16_accuracy.sh +# Performance +bash scripts/infer_clip_fp16_performance.sh +``` + +## Model Results + +| Model | BatchSize | Precision | FPS | Top-1(%) | Top-5(%) | +| :----: | :----: | :----: | :----: | :----: | :----: | +| CLIP | 32 | FP16 | 350.94 | 59.68 | 86.14 | diff --git a/models/cv/classification/clip/ixrt/build_engine.py b/models/cv/classification/clip/ixrt/build_engine.py new file mode 100644 index 0000000000000000000000000000000000000000..4c4be776e74622d2d4a6afeac37a4142324fe95f --- /dev/null +++ b/models/cv/classification/clip/ixrt/build_engine.py @@ -0,0 +1,96 @@ +# Copyright (c) 2025, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import os +import cv2 +import argparse +import numpy as np + +import torch +import tensorrt +import ixrt + +TRT_LOGGER = tensorrt.Logger(tensorrt.Logger.WARNING) +from load_ixrt_plugin import load_ixrt_plugin +load_ixrt_plugin(TRT_LOGGER) + +def main(config): + if config.silent: + action = tensorrt.Logger.WARNING + else: + action = tensorrt.Logger.ERROR + IXRT_LOGGER = tensorrt.Logger(action) + builder = tensorrt.Builder(IXRT_LOGGER) + EXPLICIT_BATCH = 1 << (int)(tensorrt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) + network = builder.create_network(EXPLICIT_BATCH) + build_config = builder.create_builder_config() + parser = tensorrt.OnnxParser(network, IXRT_LOGGER) + if not parser.parse_from_file(config.model): + raise Exception(f"Failed to parse {config.model}, please check detailed debug info") + + precision = tensorrt.BuilderFlag.INT8 if config.precision == "int8" else tensorrt.BuilderFlag.FP16 + # print("precision : ", precision) + build_config.set_flag(precision) + + # due to fp16 of elementwise div of swin_v2 will exceed the range of f16 representation, so set fp32. + if ("swin_v2_s_model_sim" in config.model) and (config.precision == "float16"): + build_config.set_flag(ixrt.BuilderFlag.PREFER_PRECISION_CONSTRAINTS) + float32_set = {"/features/features.3/features.3.0/attn/Div_4", + "/features/features.3/features.3.1/attn/Div_4", + "/features/features.5/features.5.0/attn/Div_4", + "/features/features.5/features.5.1/attn/Div_4", + "/features/features.5/features.5.2/attn/Div_4", + "/features/features.5/features.5.3/attn/Div_4", + "/features/features.5/features.5.4/attn/Div_4", + "/features/features.5/features.5.5/attn/Div_4", + "/features/features.5/features.5.6/attn/Div_4", + "/features/features.5/features.5.7/attn/Div_4", + "/features/features.5/features.5.8/attn/Div_4", + "/features/features.5/features.5.9/attn/Div_4", + "/features/features.5/features.5.10/attn/Div_4", + "/features/features.5/features.5.11/attn/Div_4", + "/features/features.5/features.5.12/attn/Div_4", + "/features/features.5/features.5.13/attn/Div_4", + "/features/features.5/features.5.14/attn/Div_4", + "/features/features.5/features.5.15/attn/Div_4", + "/features/features.5/features.5.16/attn/Div_4", + "/features/features.5/features.5.17/attn/Div_4", + "/features/features.7/features.7.0/attn/Div_4", + "/features/features.7/features.7.1/attn/Div_4",} + for i in range(network.num_layers): + layer = network.get_layer(i) + if layer.name in float32_set: + layer.precision = ixrt.float32 + + plan = builder.build_serialized_network(network, build_config) + if not plan: + raise Exception("Failed to build engine, please check detailed debug info") + engine_file_path = config.engine + with open(engine_file_path, "wb") as f: + f.write(plan) + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument("--model", type=str) + parser.add_argument("--precision", type=str, choices=["float16", "int8", "float32"], default="int8", + help="The precision of datatype") + parser.add_argument("--engine", type=str, default=None) + parser.add_argument("--silent", action="store_true") + args = parser.parse_args() + return args + +if __name__ == "__main__": + args = parse_args() + main(args) diff --git a/models/cv/classification/clip/ixrt/calibration_dataset.py b/models/cv/classification/clip/ixrt/calibration_dataset.py new file mode 100644 index 0000000000000000000000000000000000000000..0e5efe4d33b48c1270d04446490c6de37c94dcc6 --- /dev/null +++ b/models/cv/classification/clip/ixrt/calibration_dataset.py @@ -0,0 +1,274 @@ +# Copyright (c) 2025, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import os +import numpy as np +from PIL import Image + +import torch +import torchvision.datasets +from torch.utils.data import DataLoader +from torchvision import models +from torchvision import transforms as T + + +class CalibrationImageNet(torchvision.datasets.ImageFolder): + def __init__(self, *args, **kwargs): + super(CalibrationImageNet, self).__init__(*args, **kwargs) + img2label_path = os.path.join(self.root, "val_map.txt") + if not os.path.exists(img2label_path): + raise FileNotFoundError(f"Not found label file `{img2label_path}`.") + + self.img2label_map = self.make_img2label_map(img2label_path) + + def make_img2label_map(self, path): + with open(path) as f: + lines = f.readlines() + + img2lable_map = dict() + for line in lines: + line = line.lstrip().rstrip().split("\t") + if len(line) != 2: + continue + img_name, label = line + img_name = img_name.strip() + if img_name in [None, ""]: + continue + label = int(label.strip()) + img2lable_map[img_name] = label + return img2lable_map + + def __getitem__(self, index): + path, target = self.samples[index] + sample = self.loader(path) + if self.transform is not None: + sample = self.transform(sample) + # if self.target_transform is not None: + # target = self.target_transform(target) + img_name = os.path.basename(path) + target = self.img2label_map[img_name] + + return sample, target + +class CalibrationRGBImageNet(torchvision.datasets.ImageFolder): + def __init__(self, *args, **kwargs): + super(CalibrationRGBImageNet, self).__init__(*args, **kwargs) + img2label_path = os.path.join(self.root, "val_map.txt") + if not os.path.exists(img2label_path): + raise FileNotFoundError(f"Not found label file `{img2label_path}`.") + + self.img2label_map = self.make_img2label_map(img2label_path) + + def make_img2label_map(self, path): + with open(path) as f: + lines = f.readlines() + + img2lable_map = dict() + for line in lines: + line = line.lstrip().rstrip().split("\t") + if len(line) != 2: + continue + img_name, label = line + img_name = img_name.strip() + if img_name in [None, ""]: + continue + label = int(label.strip()) + img2lable_map[img_name] = label + return img2lable_map + + def __getitem__(self, index): + path, target = self.samples[index] + sample = self.loader(path) + sample = sample.convert("RGB") + sample = np.array(sample)[:, :, ::-1] + sample = Image.fromarray(np.uint8(sample)) + if self.transform is not None: + sample = self.transform(sample) + img_name = os.path.basename(path) + target = self.img2label_map[img_name] + + return sample, target + + +def create_mobilenetv1_dataloaders(data_path, num_samples=1024, img_sz=224, batch_size=2, workers=0): + dataset = CalibrationRGBImageNet( + data_path, + transform=T.Compose( + [ + T.Resize(256), + T.CenterCrop(img_sz), + T.ToTensor(), + T.Normalize(mean=[103.940002441/255, 116.779998779/255, 123.680000305/255], std=[1.0/(255*0.0170000009239), 1.0/(255*0.0170000009239), 1.0/(255*0.0170000009239)]), + ] + ), + ) + + calibration_dataset = dataset + if num_samples is not None: + calibration_dataset = torch.utils.data.Subset( + dataset, indices=range(num_samples) + ) + + calibration_dataloader = DataLoader( + calibration_dataset, + shuffle=False, + batch_size=batch_size, + drop_last=False, + num_workers=workers, + ) + + verify_dataloader = DataLoader( + dataset, + shuffle=False, + batch_size=batch_size, + drop_last=False, + num_workers=workers, + ) + + return calibration_dataloader, verify_dataloader + + +def getmobilenetv1dataloader(dataset_dir, step=20, batch_size=32, workers=2, img_sz=224, total_sample=50000): + num_samples = min(total_sample, step * batch_size) + if step < 0: + num_samples = None + calibration_dataloader, _ = create_mobilenetv1_dataloaders( + dataset_dir, + img_sz=img_sz, + batch_size=batch_size, + workers=workers, + num_samples=num_samples, + ) + return calibration_dataloader + + +def create_dataloaders(data_path, num_samples=1024, img_sz=224, batch_size=2, workers=0): + dataset = CalibrationImageNet( + data_path, + transform=T.Compose( + [ + T.Resize(256), + T.CenterCrop(img_sz), + T.ToTensor(), + T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), + ] + ), + ) + + calibration_dataset = dataset + if num_samples is not None: + calibration_dataset = torch.utils.data.Subset( + dataset, indices=range(num_samples) + ) + + calibration_dataloader = DataLoader( + calibration_dataset, + shuffle=False, + batch_size=batch_size, + drop_last=False, + num_workers=workers, + ) + + verify_dataloader = DataLoader( + dataset, + shuffle=False, + batch_size=batch_size, + drop_last=False, + num_workers=workers, + ) + + return calibration_dataloader, verify_dataloader + + +def getdataloader(dataset_dir, step=20, batch_size=32, workers=2, img_sz=224, total_sample=50000): + num_samples = min(total_sample, step * batch_size) + if step < 0: + num_samples = None + calibration_dataloader, _ = create_dataloaders( + dataset_dir, + img_sz=img_sz, + batch_size=batch_size, + workers=workers, + num_samples=num_samples, + ) + return calibration_dataloader + +from transformers import CLIPProcessor +from glob import glob +import yaml +from torch.utils.data import Dataset, DataLoader + +with open('imagenet_labels.yaml', 'r') as file: + yaml_content = file.read() + +imagenet_labels = yaml.safe_load(yaml_content) + +imagenet_classes = [value for key, value in imagenet_labels['labels'].items()] + +class CLIPImageNetDataset(Dataset): + def __init__(self, image_dir_path, seq_len=22, checkpoint="clip-vit-base-patch32"): + self.image_dir_path = os.path.expanduser(image_dir_path) + + self.label_path = f"{self.image_dir_path}/val.txt" + self.img2label = {} + with open(self.label_path) as f: + lines = f.readlines() + for i in lines: + image, label = i.split() + self.img2label[image] = int(label) + + self.img_list = glob(f"{self.image_dir_path}/*/*") + + self.processor = CLIPProcessor.from_pretrained(checkpoint) + self.label = [f"a photo of a {imagenet_class}" for imagenet_class in imagenet_classes] + self.processed_text = self.processor.tokenizer(self.label, return_tensors='pt', padding="max_length", truncation=True, max_length=seq_len) + + self.input_ids = self.processed_text['input_ids'].numpy() + self.attention_mask = self.processed_text['attention_mask'].numpy() + + + def __getitem__(self, index): + image_path = self.img_list[index] + image = Image.open(image_path).convert('RGB') + + image = self.processor.image_processor(image, return_tensors="pt")["pixel_values"].numpy() + + image_name = os.path.basename(image_path) + label = self.img2label[image_name] + + return self.input_ids, image, self.attention_mask, label + + def __len__(self): + return len(self.img_list) + + @staticmethod + def collate_fn(batch): + input_ids, image, attention_mask, label = zip(*batch) + return input_ids[0], np.concatenate(image), attention_mask[0], label + +def getclipdataloader(batch_size, image_dir_path, input_dict): + assert len(input_dict) == 3 + input_name_list = list(input_dict.keys()) + assert set(["input_ids", "pixel_values", "attention_mask"]) == set(input_name_list), f"clip model from huggingface should use inputs [input_ids, pixel_values, attention_mask]" + + imagenet_class = input_dict["input_ids"][0] + assert imagenet_class == 1000, f"text model should use batch_size = 1000 to do imagenet classification" + seq_len = input_dict["input_ids"][1] + assert seq_len >= 22, f"clip imagenet classification need seq_len >= 22, got {seq_len}" + + dataset = CLIPImageNetDataset(image_dir_path, seq_len) + dataloader = DataLoader(dataset, batch_size=batch_size, drop_last=True, collate_fn=dataset.collate_fn) + + return dataloader \ No newline at end of file diff --git a/models/cv/classification/clip/ixrt/ci/prepare.sh b/models/cv/classification/clip/ixrt/ci/prepare.sh new file mode 100644 index 0000000000000000000000000000000000000000..d32e0591c0dc20200eb2bbd1e2abf032871982a8 --- /dev/null +++ b/models/cv/classification/clip/ixrt/ci/prepare.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Copyright (c) 2025, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -x + +pip3 install -r requirements.txt +python3 export.py --output clip.onnx +mv clip.onnx Clip.onnx +cp -r /root/data/3rd_party/iluvatar-corex-ixrt ./ \ No newline at end of file diff --git a/models/cv/classification/clip/ixrt/common.py b/models/cv/classification/clip/ixrt/common.py new file mode 100644 index 0000000000000000000000000000000000000000..a860392c58a325ecc83e2bf0b2d5d4a707e3776f --- /dev/null +++ b/models/cv/classification/clip/ixrt/common.py @@ -0,0 +1,136 @@ +# Copyright (c) 2025, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import os +import cv2 +import glob +import torch +import tensorrt +import numpy as np +from cuda import cuda, cudart + +def eval_batch(batch_score, batch_label): + batch_score = torch.tensor(torch.from_numpy(batch_score), dtype=torch.float32) + values, indices = batch_score.topk(5) + top1, top5 = 0, 0 + for idx, label in enumerate(batch_label): + + if label == indices[idx][0]: + top1 += 1 + if label in indices[idx]: + top5 += 1 + return top1, top5 + +def create_engine_context(engine_path, logger): + with open(engine_path, "rb") as f: + runtime = tensorrt.Runtime(logger) + assert runtime + engine = runtime.deserialize_cuda_engine(f.read()) + assert engine + context = engine.create_execution_context() + assert context + + return engine, context + +def _get_engine_io_bindings(engine): + # Setup I/O bindings + inputs = [] + outputs = [] + allocations = [] + + for i in range(engine.num_bindings): + is_input = False + if engine.binding_is_input(i): + is_input = True + name = engine.get_binding_name(i) + dtype = engine.get_binding_dtype(i) + shape = engine.get_binding_shape(i) + if is_input: + batch_size = shape[0] + size = np.dtype(tensorrt.nptype(dtype)).itemsize + for s in shape: + size *= s + err, allocation = cudart.cudaMalloc(size) + assert err == cudart.cudaError_t.cudaSuccess + binding = { + "index": i, + "name": name, + "dtype": np.dtype(tensorrt.nptype(dtype)), + "shape": list(shape), + "allocation": allocation, + "nbytes": size, + } + print(f"binding {i}, name : {name} dtype : {np.dtype(tensorrt.nptype(dtype))} shape : {list(shape)}") + allocations.append(allocation) + if engine.binding_is_input(i): + inputs.append(binding) + else: + outputs.append(binding) + return inputs, outputs, allocations + +def _convert_dtype_ort_to_np(type): + type = type.replace("tensor", "") + type = type.replace("(", "") + type = type.replace(")", "") + if type == "float": + type = "float32" + return np.dtype(type) + +def _get_bytes_of_tensor(shape, type: np.dtype): + size = type.itemsize + for s in shape: + size *= s + return size +def _alloc_gpu_tensor(shape, dtype): + size = _get_bytes_of_tensor(shape, dtype) + err, allocation = cudart.cudaMalloc(size) + assert err == cudart.cudaError_t.cudaSuccess + return allocation + +def _alloc_onnx_io_binding(io, index): + type = _convert_dtype_ort_to_np(io.type) + binding = { + "index": index, + "name": io.name, + "dtype": type, + "shape": io.shape, + "allocation": None, + "nbytes": _get_bytes_of_tensor(io.shape, type), + } + return binding +def _get_onnx_io_bindings(ort_session): + # Setup I/O bindings + inputs = [] + outputs = [] + allocations = [] + + index = 0 + for input in ort_session.get_inputs(): + binding = _alloc_onnx_io_binding(input, index) + index+=1 + inputs.append(binding) + allocations.append(binding) + for output in ort_session.get_outputs(): + binding = _alloc_onnx_io_binding(output, index) + index+=1 + outputs.append(binding) + allocations.append(binding) + return inputs, outputs, allocations + +def get_io_bindings(engine): + if isinstance(engine, tensorrt.ICudaEngine): + return _get_engine_io_bindings(engine) + else: + return _get_onnx_io_bindings(engine) diff --git a/models/cv/classification/clip/ixrt/export.py b/models/cv/classification/clip/ixrt/export.py new file mode 100644 index 0000000000000000000000000000000000000000..b0c71c6162220c635591bf349ede987d5ef1c116 --- /dev/null +++ b/models/cv/classification/clip/ixrt/export.py @@ -0,0 +1,50 @@ +# Copyright (c) 2025, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import argparse +from pathlib import Path +from transformers.onnx import export +from transformers.models.clip import CLIPOnnxConfig +from transformers import CLIPProcessor, CLIPModel + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--output", + type=str, + required=True, + help="export onnx model path.") + + args = parser.parse_args() + return args + +def main(): + args = parse_args() + + checkpoint = "clip-vit-base-patch32" + feature_extractor = CLIPProcessor.from_pretrained(checkpoint) + model = CLIPModel.from_pretrained(checkpoint) + + save_path = Path(args.output) + onnx_config = CLIPOnnxConfig(model.config) + + # export onnx model + export( + feature_extractor, model, onnx_config, + onnx_config.default_onnx_opset, save_path + ) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/clip/ixrt/imagenet_labels.yaml b/models/cv/classification/clip/ixrt/imagenet_labels.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b2949583a320a85b0deeae6f9b09c4be237ba083 --- /dev/null +++ b/models/cv/classification/clip/ixrt/imagenet_labels.yaml @@ -0,0 +1,1016 @@ +# Copyright (c) 2025, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the License); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an AS IS BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +labels: + 0: tench, Tinca tinca + 1: goldfish, Carassius auratus + 2: great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias + 3: tiger shark, Galeocerdo cuvieri + 4: hammerhead, hammerhead shark + 5: electric ray, crampfish, numbfish, torpedo + 6: stingray + 7: cock + 8: hen + 9: ostrich, Struthio camelus + 10: brambling, Fringilla montifringilla + 11: goldfinch, Carduelis carduelis + 12: house finch, linnet, Carpodacus mexicanus + 13: junco, snowbird + 14: indigo bunting, indigo finch, indigo bird, Passerina cyanea + 15: robin, American robin, Turdus migratorius + 16: bulbul + 17: jay + 18: magpie + 19: chickadee + 20: water ouzel, dipper + 21: kite + 22: bald eagle, American eagle, Haliaeetus leucocephalus + 23: vulture + 24: great grey owl, great gray owl, Strix nebulosa + 25: European fire salamander, Salamandra salamandra + 26: common newt, Triturus vulgaris + 27: eft + 28: spotted salamander, Ambystoma maculatum + 29: axolotl, mud puppy, Ambystoma mexicanum + 30: bullfrog, Rana catesbeiana + 31: tree frog, tree-frog + 32: tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui + 33: loggerhead, loggerhead turtle, Caretta caretta + 34: leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea + 35: mud turtle + 36: terrapin + 37: box turtle, box tortoise + 38: banded gecko + 39: common iguana, iguana, Iguana iguana + 40: American chameleon, anole, Anolis carolinensis + 41: whiptail, whiptail lizard + 42: agama + 43: frilled lizard, Chlamydosaurus kingi + 44: alligator lizard + 45: Gila monster, Heloderma suspectum + 46: green lizard, Lacerta viridis + 47: African chameleon, Chamaeleo chamaeleon + 48: Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis + 49: African crocodile, Nile crocodile, Crocodylus niloticus + 50: American alligator, Alligator mississipiensis + 51: triceratops + 52: thunder snake, worm snake, Carphophis amoenus + 53: ringneck snake, ring-necked snake, ring snake + 54: hognose snake, puff adder, sand viper + 55: green snake, grass snake + 56: king snake, kingsnake + 57: garter snake, grass snake + 58: water snake + 59: vine snake + 60: night snake, Hypsiglena torquata + 61: boa constrictor, Constrictor constrictor + 62: rock python, rock snake, Python sebae + 63: Indian cobra, Naja naja + 64: green mamba + 65: sea snake + 66: horned viper, cerastes, sand viper, horned asp, Cerastes cornutus + 67: diamondback, diamondback rattlesnake, Crotalus adamanteus + 68: sidewinder, horned rattlesnake, Crotalus cerastes + 69: trilobite + 70: harvestman, daddy longlegs, Phalangium opilio + 71: scorpion + 72: black and gold garden spider, Argiope aurantia + 73: barn spider, Araneus cavaticus + 74: garden spider, Aranea diademata + 75: black widow, Latrodectus mactans + 76: tarantula + 77: wolf spider, hunting spider + 78: tick + 79: centipede + 80: black grouse + 81: ptarmigan + 82: ruffed grouse, partridge, Bonasa umbellus + 83: prairie chicken, prairie grouse, prairie fowl + 84: peacock + 85: quail + 86: partridge + 87: African grey, African gray, Psittacus erithacus + 88: macaw + 89: sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita + 90: lorikeet + 91: coucal + 92: bee eater + 93: hornbill + 94: hummingbird + 95: jacamar + 96: toucan + 97: drake + 98: red-breasted merganser, Mergus serrator + 99: goose + 100: black swan, Cygnus atratus + 101: tusker + 102: echidna, spiny anteater, anteater + 103: platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus + 104: wallaby, brush kangaroo + 105: koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus + 106: wombat + 107: jellyfish + 108: sea anemone, anemone + 109: brain coral + 110: flatworm, platyhelminth + 111: nematode, nematode worm, roundworm + 112: conch + 113: snail + 114: slug + 115: sea slug, nudibranch + 116: chiton, coat-of-mail shell, sea cradle, polyplacophore + 117: chambered nautilus, pearly nautilus, nautilus + 118: Dungeness crab, Cancer magister + 119: rock crab, Cancer irroratus + 120: fiddler crab + 121: king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica + 122: American lobster, Northern lobster, Maine lobster, Homarus americanus + 123: spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish + 124: crayfish, crawfish, crawdad, crawdaddy + 125: hermit crab + 126: isopod + 127: white stork, Ciconia ciconia + 128: black stork, Ciconia nigra + 129: spoonbill + 130: flamingo + 131: little blue heron, Egretta caerulea + 132: American egret, great white heron, Egretta albus + 133: bittern + 134: crane + 135: limpkin, Aramus pictus + 136: European gallinule, Porphyrio porphyrio + 137: American coot, marsh hen, mud hen, water hen, Fulica americana + 138: bustard + 139: ruddy turnstone, Arenaria interpres + 140: red-backed sandpiper, dunlin, Erolia alpina + 141: redshank, Tringa totanus + 142: dowitcher + 143: oystercatcher, oyster catcher + 144: pelican + 145: king penguin, Aptenodytes patagonica + 146: albatross, mollymawk + 147: grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus + 148: killer whale, killer, orca, grampus, sea wolf, Orcinus orca + 149: dugong, Dugong dugon + 150: sea lion + 151: Chihuahua + 152: Japanese spaniel + 153: Maltese dog, Maltese terrier, Maltese + 154: Pekinese, Pekingese, Peke + 155: Shih-Tzu + 156: Blenheim spaniel + 157: papillon + 158: toy terrier + 159: Rhodesian ridgeback + 160: Afghan hound, Afghan + 161: basset, basset hound + 162: beagle + 163: bloodhound, sleuthhound + 164: bluetick + 165: black-and-tan coonhound + 166: Walker hound, Walker foxhound + 167: English foxhound + 168: redbone + 169: borzoi, Russian wolfhound + 170: Irish wolfhound + 171: Italian greyhound + 172: whippet + 173: Ibizan hound, Ibizan Podenco + 174: Norwegian elkhound, elkhound + 175: otterhound, otter hound + 176: Saluki, gazelle hound + 177: Scottish deerhound, deerhound + 178: Weimaraner + 179: Staffordshire bullterrier, Staffordshire bull terrier + 180: American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier + 181: Bedlington terrier + 182: Border terrier + 183: Kerry blue terrier + 184: Irish terrier + 185: Norfolk terrier + 186: Norwich terrier + 187: Yorkshire terrier + 188: wire-haired fox terrier + 189: Lakeland terrier + 190: Sealyham terrier, Sealyham + 191: Airedale, Airedale terrier + 192: cairn, cairn terrier + 193: Australian terrier + 194: Dandie Dinmont, Dandie Dinmont terrier + 195: Boston bull, Boston terrier + 196: miniature schnauzer + 197: giant schnauzer + 198: standard schnauzer + 199: Scotch terrier, Scottish terrier, Scottie + 200: Tibetan terrier, chrysanthemum dog + 201: silky terrier, Sydney silky + 202: soft-coated wheaten terrier + 203: West Highland white terrier + 204: Lhasa, Lhasa apso + 205: flat-coated retriever + 206: curly-coated retriever + 207: golden retriever + 208: Labrador retriever + 209: Chesapeake Bay retriever + 210: German short-haired pointer + 211: vizsla, Hungarian pointer + 212: English setter + 213: Irish setter, red setter + 214: Gordon setter + 215: Brittany spaniel + 216: clumber, clumber spaniel + 217: English springer, English springer spaniel + 218: Welsh springer spaniel + 219: cocker spaniel, English cocker spaniel, cocker + 220: Sussex spaniel + 221: Irish water spaniel + 222: kuvasz + 223: schipperke + 224: groenendael + 225: malinois + 226: briard + 227: kelpie + 228: komondor + 229: Old English sheepdog, bobtail + 230: Shetland sheepdog, Shetland sheep dog, Shetland + 231: collie + 232: Border collie + 233: Bouvier des Flandres, Bouviers des Flandres + 234: Rottweiler + 235: German shepherd, German shepherd dog, German police dog, alsatian + 236: Doberman, Doberman pinscher + 237: miniature pinscher + 238: Greater Swiss Mountain dog + 239: Bernese mountain dog + 240: Appenzeller + 241: EntleBucher + 242: boxer + 243: bull mastiff + 244: Tibetan mastiff + 245: French bulldog + 246: Great Dane + 247: Saint Bernard, St Bernard + 248: Eskimo dog, husky + 249: malamute, malemute, Alaskan malamute + 250: Siberian husky + 251: dalmatian, coach dog, carriage dog + 252: affenpinscher, monkey pinscher, monkey dog + 253: basenji + 254: pug, pug-dog + 255: Leonberg + 256: Newfoundland, Newfoundland dog + 257: Great Pyrenees + 258: Samoyed, Samoyede + 259: Pomeranian + 260: chow, chow chow + 261: keeshond + 262: Brabancon griffon + 263: Pembroke, Pembroke Welsh corgi + 264: Cardigan, Cardigan Welsh corgi + 265: toy poodle + 266: miniature poodle + 267: standard poodle + 268: Mexican hairless + 269: timber wolf, grey wolf, gray wolf, Canis lupus + 270: white wolf, Arctic wolf, Canis lupus tundrarum + 271: red wolf, maned wolf, Canis rufus, Canis niger + 272: coyote, prairie wolf, brush wolf, Canis latrans + 273: dingo, warrigal, warragal, Canis dingo + 274: dhole, Cuon alpinus + 275: African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus + 276: hyena, hyaena + 277: red fox, Vulpes vulpes + 278: kit fox, Vulpes macrotis + 279: Arctic fox, white fox, Alopex lagopus + 280: grey fox, gray fox, Urocyon cinereoargenteus + 281: tabby, tabby cat + 282: tiger cat + 283: Persian cat + 284: Siamese cat, Siamese + 285: Egyptian cat + 286: cougar, puma, catamount, mountain lion, painter, panther, Felis concolor + 287: lynx, catamount + 288: leopard, Panthera pardus + 289: snow leopard, ounce, Panthera uncia + 290: jaguar, panther, Panthera onca, Felis onca + 291: lion, king of beasts, Panthera leo + 292: tiger, Panthera tigris + 293: cheetah, chetah, Acinonyx jubatus + 294: brown bear, bruin, Ursus arctos + 295: American black bear, black bear, Ursus americanus, Euarctos americanus + 296: ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus + 297: sloth bear, Melursus ursinus, Ursus ursinus + 298: mongoose + 299: meerkat, mierkat + 300: tiger beetle + 301: ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle + 302: ground beetle, carabid beetle + 303: long-horned beetle, longicorn, longicorn beetle + 304: leaf beetle, chrysomelid + 305: dung beetle + 306: rhinoceros beetle + 307: weevil + 308: fly + 309: bee + 310: ant, emmet, pismire + 311: grasshopper, hopper + 312: cricket + 313: walking stick, walkingstick, stick insect + 314: cockroach, roach + 315: mantis, mantid + 316: cicada, cicala + 317: leafhopper + 318: lacewing, lacewing fly + 319: dragonfly, darning needle, devils darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk + 320: damselfly + 321: admiral + 322: ringlet, ringlet butterfly + 323: monarch, monarch butterfly, milkweed butterfly, Danaus plexippus + 324: cabbage butterfly + 325: sulphur butterfly, sulfur butterfly + 326: lycaenid, lycaenid butterfly + 327: starfish, sea star + 328: sea urchin + 329: sea cucumber, holothurian + 330: wood rabbit, cottontail, cottontail rabbit + 331: hare + 332: Angora, Angora rabbit + 333: hamster + 334: porcupine, hedgehog + 335: fox squirrel, eastern fox squirrel, Sciurus niger + 336: marmot + 337: beaver + 338: guinea pig, Cavia cobaya + 339: sorrel + 340: zebra + 341: hog, pig, grunter, squealer, Sus scrofa + 342: wild boar, boar, Sus scrofa + 343: warthog + 344: hippopotamus, hippo, river horse, Hippopotamus amphibius + 345: ox + 346: water buffalo, water ox, Asiatic buffalo, Bubalus bubalis + 347: bison + 348: ram, tup + 349: bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis + 350: ibex, Capra ibex + 351: hartebeest + 352: impala, Aepyceros melampus + 353: gazelle + 354: Arabian camel, dromedary, Camelus dromedarius + 355: llama + 356: weasel + 357: mink + 358: polecat, fitch, foulmart, foumart, Mustela putorius + 359: black-footed ferret, ferret, Mustela nigripes + 360: otter + 361: skunk, polecat, wood pussy + 362: badger + 363: armadillo + 364: three-toed sloth, ai, Bradypus tridactylus + 365: orangutan, orang, orangutang, Pongo pygmaeus + 366: gorilla, Gorilla gorilla + 367: chimpanzee, chimp, Pan troglodytes + 368: gibbon, Hylobates lar + 369: siamang, Hylobates syndactylus, Symphalangus syndactylus + 370: guenon, guenon monkey + 371: patas, hussar monkey, Erythrocebus patas + 372: baboon + 373: macaque + 374: langur + 375: colobus, colobus monkey + 376: proboscis monkey, Nasalis larvatus + 377: marmoset + 378: capuchin, ringtail, Cebus capucinus + 379: howler monkey, howler + 380: titi, titi monkey + 381: spider monkey, Ateles geoffroyi + 382: squirrel monkey, Saimiri sciureus + 383: Madagascar cat, ring-tailed lemur, Lemur catta + 384: indri, indris, Indri indri, Indri brevicaudatus + 385: Indian elephant, Elephas maximus + 386: African elephant, Loxodonta africana + 387: lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens + 388: giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca + 389: barracouta, snoek + 390: eel + 391: coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch + 392: rock beauty, Holocanthus tricolor + 393: anemone fish + 394: sturgeon + 395: gar, garfish, garpike, billfish, Lepisosteus osseus + 396: lionfish + 397: puffer, pufferfish, blowfish, globefish + 398: abacus + 399: abaya + 400: academic gown, academic robe, judges robe + 401: accordion, piano accordion, squeeze box + 402: acoustic guitar + 403: aircraft carrier, carrier, flattop, attack aircraft carrier + 404: airliner + 405: airship, dirigible + 406: altar + 407: ambulance + 408: amphibian, amphibious vehicle + 409: analog clock + 410: apiary, bee house + 411: apron + 412: ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin + 413: assault rifle, assault gun + 414: backpack, back pack, knapsack, packsack, rucksack, haversack + 415: bakery, bakeshop, bakehouse + 416: balance beam, beam + 417: balloon + 418: ballpoint, ballpoint pen, ballpen, Biro + 419: Band Aid + 420: banjo + 421: bannister, banister, balustrade, balusters, handrail + 422: barbell + 423: barber chair + 424: barbershop + 425: barn + 426: barometer + 427: barrel, cask + 428: barrow, garden cart, lawn cart, wheelbarrow + 429: baseball + 430: basketball + 431: bassinet + 432: bassoon + 433: bathing cap, swimming cap + 434: bath towel + 435: bathtub, bathing tub, bath, tub + 436: beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon + 437: beacon, lighthouse, beacon light, pharos + 438: beaker + 439: bearskin, busby, shako + 440: beer bottle + 441: beer glass + 442: bell cote, bell cot + 443: bib + 444: bicycle-built-for-two, tandem bicycle, tandem + 445: bikini, two-piece + 446: binder, ring-binder + 447: binoculars, field glasses, opera glasses + 448: birdhouse + 449: boathouse + 450: bobsled, bobsleigh, bob + 451: bolo tie, bolo, bola tie, bola + 452: bonnet, poke bonnet + 453: bookcase + 454: bookshop, bookstore, bookstall + 455: bottlecap + 456: bow + 457: bow tie, bow-tie, bowtie + 458: brass, memorial tablet, plaque + 459: brassiere, bra, bandeau + 460: breakwater, groin, groyne, mole, bulwark, seawall, jetty + 461: breastplate, aegis, egis + 462: broom + 463: bucket, pail + 464: buckle + 465: bulletproof vest + 466: bullet train, bullet + 467: butcher shop, meat market + 468: cab, hack, taxi, taxicab + 469: caldron, cauldron + 470: candle, taper, wax light + 471: cannon + 472: canoe + 473: can opener, tin opener + 474: cardigan + 475: car mirror + 476: carousel, carrousel, merry-go-round, roundabout, whirligig + 477: carpenters kit, tool kit + 478: carton + 479: car wheel + 480: cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM + 481: cassette + 482: cassette player + 483: castle + 484: catamaran + 485: CD player + 486: cello, violoncello + 487: cellular telephone, cellular phone, cellphone, cell, mobile phone + 488: chain + 489: chainlink fence + 490: chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour + 491: chain saw, chainsaw + 492: chest + 493: chiffonier, commode + 494: chime, bell, gong + 495: china cabinet, china closet + 496: Christmas stocking + 497: church, church building + 498: cinema, movie theater, movie theatre, movie house, picture palace + 499: cleaver, meat cleaver, chopper + 500: cliff dwelling + 501: cloak + 502: clog, geta, patten, sabot + 503: cocktail shaker + 504: coffee mug + 505: coffeepot + 506: coil, spiral, volute, whorl, helix + 507: combination lock + 508: computer keyboard, keypad + 509: confectionery, confectionary, candy store + 510: container ship, containership, container vessel + 511: convertible + 512: corkscrew, bottle screw + 513: cornet, horn, trumpet, trump + 514: cowboy boot + 515: cowboy hat, ten-gallon hat + 516: cradle + 517: crane + 518: crash helmet + 519: crate + 520: crib, cot + 521: Crock Pot + 522: croquet ball + 523: crutch + 524: cuirass + 525: dam, dike, dyke + 526: desk + 527: desktop computer + 528: dial telephone, dial phone + 529: diaper, nappy, napkin + 530: digital clock + 531: digital watch + 532: dining table, board + 533: dishrag, dishcloth + 534: dishwasher, dish washer, dishwashing machine + 535: disk brake, disc brake + 536: dock, dockage, docking facility + 537: dogsled, dog sled, dog sleigh + 538: dome + 539: doormat, welcome mat + 540: drilling platform, offshore rig + 541: drum, membranophone, tympan + 542: drumstick + 543: dumbbell + 544: Dutch oven + 545: electric fan, blower + 546: electric guitar + 547: electric locomotive + 548: entertainment center + 549: envelope + 550: espresso maker + 551: face powder + 552: feather boa, boa + 553: file, file cabinet, filing cabinet + 554: fireboat + 555: fire engine, fire truck + 556: fire screen, fireguard + 557: flagpole, flagstaff + 558: flute, transverse flute + 559: folding chair + 560: football helmet + 561: forklift + 562: fountain + 563: fountain pen + 564: four-poster + 565: freight car + 566: French horn, horn + 567: frying pan, frypan, skillet + 568: fur coat + 569: garbage truck, dustcart + 570: gasmask, respirator, gas helmet + 571: gas pump, gasoline pump, petrol pump, island dispenser + 572: goblet + 573: go-kart + 574: golf ball + 575: golfcart, golf cart + 576: gondola + 577: gong, tam-tam + 578: gown + 579: grand piano, grand + 580: greenhouse, nursery, glasshouse + 581: grille, radiator grille + 582: grocery store, grocery, food market, market + 583: guillotine + 584: hair slide + 585: hair spray + 586: half track + 587: hammer + 588: hamper + 589: hand blower, blow dryer, blow drier, hair dryer, hair drier + 590: hand-held computer, hand-held microcomputer + 591: handkerchief, hankie, hanky, hankey + 592: hard disc, hard disk, fixed disk + 593: harmonica, mouth organ, harp, mouth harp + 594: harp + 595: harvester, reaper + 596: hatchet + 597: holster + 598: home theater, home theatre + 599: honeycomb + 600: hook, claw + 601: hoopskirt, crinoline + 602: horizontal bar, high bar + 603: horse cart, horse-cart + 604: hourglass + 605: iPod + 606: iron, smoothing iron + 607: jack-o-lantern + 608: jean, blue jean, denim + 609: jeep, landrover + 610: jersey, T-shirt, tee shirt + 611: jigsaw puzzle + 612: jinrikisha, ricksha, rickshaw + 613: joystick + 614: kimono + 615: knee pad + 616: knot + 617: lab coat, laboratory coat + 618: ladle + 619: lampshade, lamp shade + 620: laptop, laptop computer + 621: lawn mower, mower + 622: lens cap, lens cover + 623: letter opener, paper knife, paperknife + 624: library + 625: lifeboat + 626: lighter, light, igniter, ignitor + 627: limousine, limo + 628: liner, ocean liner + 629: lipstick, lip rouge + 630: Loafer + 631: lotion + 632: loudspeaker, speaker, speaker unit, loudspeaker system, speaker system + 633: loupe, jewelers loupe + 634: lumbermill, sawmill + 635: magnetic compass + 636: mailbag, postbag + 637: mailbox, letter box + 638: maillot + 639: maillot, tank suit + 640: manhole cover + 641: maraca + 642: marimba, xylophone + 643: mask + 644: matchstick + 645: maypole + 646: maze, labyrinth + 647: measuring cup + 648: medicine chest, medicine cabinet + 649: megalith, megalithic structure + 650: microphone, mike + 651: microwave, microwave oven + 652: military uniform + 653: milk can + 654: minibus + 655: miniskirt, mini + 656: minivan + 657: missile + 658: mitten + 659: mixing bowl + 660: mobile home, manufactured home + 661: Model T + 662: modem + 663: monastery + 664: monitor + 665: moped + 666: mortar + 667: mortarboard + 668: mosque + 669: mosquito net + 670: motor scooter, scooter + 671: mountain bike, all-terrain bike, off-roader + 672: mountain tent + 673: mouse, computer mouse + 674: mousetrap + 675: moving van + 676: muzzle + 677: nail + 678: neck brace + 679: necklace + 680: nipple + 681: notebook, notebook computer + 682: obelisk + 683: oboe, hautboy, hautbois + 684: ocarina, sweet potato + 685: odometer, hodometer, mileometer, milometer + 686: oil filter + 687: organ, pipe organ + 688: oscilloscope, scope, cathode-ray oscilloscope, CRO + 689: overskirt + 690: oxcart + 691: oxygen mask + 692: packet + 693: paddle, boat paddle + 694: paddlewheel, paddle wheel + 695: padlock + 696: paintbrush + 697: pajama, pyjama, pjs, jammies + 698: palace + 699: panpipe, pandean pipe, syrinx + 700: paper towel + 701: parachute, chute + 702: parallel bars, bars + 703: park bench + 704: parking meter + 705: passenger car, coach, carriage + 706: patio, terrace + 707: pay-phone, pay-station + 708: pedestal, plinth, footstall + 709: pencil box, pencil case + 710: pencil sharpener + 711: perfume, essence + 712: Petri dish + 713: photocopier + 714: pick, plectrum, plectron + 715: pickelhaube + 716: picket fence, paling + 717: pickup, pickup truck + 718: pier + 719: piggy bank, penny bank + 720: pill bottle + 721: pillow + 722: ping-pong ball + 723: pinwheel + 724: pirate, pirate ship + 725: pitcher, ewer + 726: plane, carpenters plane, woodworking plane + 727: planetarium + 728: plastic bag + 729: plate rack + 730: plow, plough + 731: plunger, plumbers helper + 732: Polaroid camera, Polaroid Land camera + 733: pole + 734: police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria + 735: poncho + 736: pool table, billiard table, snooker table + 737: pop bottle, soda bottle + 738: pot, flowerpot + 739: potters wheel + 740: power drill + 741: prayer rug, prayer mat + 742: printer + 743: prison, prison house + 744: projectile, missile + 745: projector + 746: puck, hockey puck + 747: punching bag, punch bag, punching ball, punchball + 748: purse + 749: quill, quill pen + 750: quilt, comforter, comfort, puff + 751: racer, race car, racing car + 752: racket, racquet + 753: radiator + 754: radio, wireless + 755: radio telescope, radio reflector + 756: rain barrel + 757: recreational vehicle, RV, R.V. + 758: reel + 759: reflex camera + 760: refrigerator, icebox + 761: remote control, remote + 762: restaurant, eating house, eating place, eatery + 763: revolver, six-gun, six-shooter + 764: rifle + 765: rocking chair, rocker + 766: rotisserie + 767: rubber eraser, rubber, pencil eraser + 768: rugby ball + 769: rule, ruler + 770: running shoe + 771: safe + 772: safety pin + 773: saltshaker, salt shaker + 774: sandal + 775: sarong + 776: sax, saxophone + 777: scabbard + 778: scale, weighing machine + 779: school bus + 780: schooner + 781: scoreboard + 782: screen, CRT screen + 783: screw + 784: screwdriver + 785: seat belt, seatbelt + 786: sewing machine + 787: shield, buckler + 788: shoe shop, shoe-shop, shoe store + 789: shoji + 790: shopping basket + 791: shopping cart + 792: shovel + 793: shower cap + 794: shower curtain + 795: ski + 796: ski mask + 797: sleeping bag + 798: slide rule, slipstick + 799: sliding door + 800: slot, one-armed bandit + 801: snorkel + 802: snowmobile + 803: snowplow, snowplough + 804: soap dispenser + 805: soccer ball + 806: sock + 807: solar dish, solar collector, solar furnace + 808: sombrero + 809: soup bowl + 810: space bar + 811: space heater + 812: space shuttle + 813: spatula + 814: speedboat + 815: spider web, spiders web + 816: spindle + 817: sports car, sport car + 818: spotlight, spot + 819: stage + 820: steam locomotive + 821: steel arch bridge + 822: steel drum + 823: stethoscope + 824: stole + 825: stone wall + 826: stopwatch, stop watch + 827: stove + 828: strainer + 829: streetcar, tram, tramcar, trolley, trolley car + 830: stretcher + 831: studio couch, day bed + 832: stupa, tope + 833: submarine, pigboat, sub, U-boat + 834: suit, suit of clothes + 835: sundial + 836: sunglass + 837: sunglasses, dark glasses, shades + 838: sunscreen, sunblock, sun blocker + 839: suspension bridge + 840: swab, swob, mop + 841: sweatshirt + 842: swimming trunks, bathing trunks + 843: swing + 844: switch, electric switch, electrical switch + 845: syringe + 846: table lamp + 847: tank, army tank, armored combat vehicle, armoured combat vehicle + 848: tape player + 849: teapot + 850: teddy, teddy bear + 851: television, television system + 852: tennis ball + 853: thatch, thatched roof + 854: theater curtain, theatre curtain + 855: thimble + 856: thresher, thrasher, threshing machine + 857: throne + 858: tile roof + 859: toaster + 860: tobacco shop, tobacconist shop, tobacconist + 861: toilet seat + 862: torch + 863: totem pole + 864: tow truck, tow car, wrecker + 865: toyshop + 866: tractor + 867: trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi + 868: tray + 869: trench coat + 870: tricycle, trike, velocipede + 871: trimaran + 872: tripod + 873: triumphal arch + 874: trolleybus, trolley coach, trackless trolley + 875: trombone + 876: tub, vat + 877: turnstile + 878: typewriter keyboard + 879: umbrella + 880: unicycle, monocycle + 881: upright, upright piano + 882: vacuum, vacuum cleaner + 883: vase + 884: vault + 885: velvet + 886: vending machine + 887: vestment + 888: viaduct + 889: violin, fiddle + 890: volleyball + 891: waffle iron + 892: wall clock + 893: wallet, billfold, notecase, pocketbook + 894: wardrobe, closet, press + 895: warplane, military plane + 896: washbasin, handbasin, washbowl, lavabo, wash-hand basin + 897: washer, automatic washer, washing machine + 898: water bottle + 899: water jug + 900: water tower + 901: whiskey jug + 902: whistle + 903: wig + 904: window screen + 905: window shade + 906: Windsor tie + 907: wine bottle + 908: wing + 909: wok + 910: wooden spoon + 911: wool, woolen, woollen + 912: worm fence, snake fence, snake-rail fence, Virginia fence + 913: wreck + 914: yawl + 915: yurt + 916: web site, website, internet site, site + 917: comic book + 918: crossword puzzle, crossword + 919: street sign + 920: traffic light, traffic signal, stoplight + 921: book jacket, dust cover, dust jacket, dust wrapper + 922: menu + 923: plate + 924: guacamole + 925: consomme + 926: hot pot, hotpot + 927: trifle + 928: ice cream, icecream + 929: ice lolly, lolly, lollipop, popsicle + 930: French loaf + 931: bagel, beigel + 932: pretzel + 933: cheeseburger + 934: hotdog, hot dog, red hot + 935: mashed potato + 936: head cabbage + 937: broccoli + 938: cauliflower + 939: zucchini, courgette + 940: spaghetti squash + 941: acorn squash + 942: butternut squash + 943: cucumber, cuke + 944: artichoke, globe artichoke + 945: bell pepper + 946: cardoon + 947: mushroom + 948: Granny Smith + 949: strawberry + 950: orange + 951: lemon + 952: fig + 953: pineapple, ananas + 954: banana + 955: jackfruit, jak, jack + 956: custard apple + 957: pomegranate + 958: hay + 959: carbonara + 960: chocolate sauce, chocolate syrup + 961: dough + 962: meat loaf, meatloaf + 963: pizza, pizza pie + 964: potpie + 965: burrito + 966: red wine + 967: espresso + 968: cup + 969: eggnog + 970: alp + 971: bubble + 972: cliff, drop, drop-off + 973: coral reef + 974: geyser + 975: lakeside, lakeshore + 976: promontory, headland, head, foreland + 977: sandbar, sand bar + 978: seashore, coast, seacoast, sea-coast + 979: valley, vale + 980: volcano + 981: ballplayer, baseball player + 982: groom, bridegroom + 983: scuba diver + 984: rapeseed + 985: daisy + 986: yellow ladys slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum + 987: corn + 988: acorn + 989: hip, rose hip, rosehip + 990: buckeye, horse chestnut, conker + 991: coral fungus + 992: agaric + 993: gyromitra + 994: stinkhorn, carrion fungus + 995: earthstar + 996: hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa + 997: bolete + 998: ear, spike, capitulum + 999: toilet tissue, toilet paper, bathroom tissue \ No newline at end of file diff --git a/models/cv/classification/clip/ixrt/inference.py b/models/cv/classification/clip/ixrt/inference.py new file mode 100644 index 0000000000000000000000000000000000000000..4dc4b82f0b9654a7e53e1ae7b91688353ac7869b --- /dev/null +++ b/models/cv/classification/clip/ixrt/inference.py @@ -0,0 +1,245 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import argparse +import json +import os +import re +import time +from tqdm import tqdm + +import cv2 +import numpy as np +from cuda import cuda, cudart +import torch +import tensorrt + +from calibration_dataset import getclipdataloader +from common import eval_batch, create_engine_context, get_io_bindings + +TRT_LOGGER = tensorrt.Logger(tensorrt.Logger.WARNING) +from load_ixrt_plugin import load_ixrt_plugin +load_ixrt_plugin(TRT_LOGGER) + +class ModelRunner: + def __init__(self, model_path, logger): + self.model_path = model_path + self.logger = logger + + if model_path.endswith(".onnx"): + self.backend = "onnxruntime" + elif model_path.endswith(".engine"): + self.backend = "ixrt" + else: + raise Exception("No supported backend for executing ", model_path, "only support engine/onnx format") + + if self.is_ixrt_backend(): + self.init_ixrt() + elif self.is_ort_backend(): + self.init_onnxruntime() + else: + raise Exception("No supported backend for", self.backend) + def is_ixrt_backend(self): + return self.backend == "ixrt" + + def is_ort_backend(self): + return self.backend == "onnxruntime" + def init_ixrt(self): + self.engine, self.context = create_engine_context(self.model_path, self.logger) + self.inputs, self.outputs, self.allocations = get_io_bindings(self.engine) + + def init_onnxruntime(self): + import onnxruntime, onnx + raw_onnx = onnx.load(self.model_path) + self.ort_session = onnxruntime.InferenceSession( + raw_onnx.SerializeToString(), providers=["CPUExecutionProvider"] + ) + self.inputs, self.outputs, self.allocations = get_io_bindings(self.ort_session) + + def run(self): + if self.is_ixrt_backend(): + self.run_ixrt() + elif self.is_ort_backend(): + self.run_onnxruntime() + else: + raise Exception("No supported backend for", self.backend) + + def run_onnxruntime(self): + input_buffers = {} + for input in self.inputs: + input_buffers[input["name"]] = input["allocation"] + + output_names = [output["name"] for output in self.outputs] + ort_outs = self.ort_session.run(output_names, input_buffers) + + for i in range(len(output_names)): + self.outputs[i]["allocation"] = ort_outs[i] + def run_ixrt(self): + self.context.execute_v2(self.allocations) + +class ClassificationRunner(ModelRunner): + def load_input(self, input_id, image, attention): + if self.is_ixrt_backend(): + err, = cuda.cuMemcpyHtoD(self.inputs[0]["allocation"], input_id, input_id.nbytes) + assert(err == cuda.CUresult.CUDA_SUCCESS) + err, = cuda.cuMemcpyHtoD(self.inputs[1]["allocation"], image, image.nbytes) + assert(err == cuda.CUresult.CUDA_SUCCESS) + err, = cuda.cuMemcpyHtoD(self.inputs[2]["allocation"], attention, attention.nbytes) + assert(err == cuda.CUresult.CUDA_SUCCESS) + + elif self.is_ort_backend(): + self.inputs[0]["allocation"] = input_id + self.inputs[1]["allocation"] = image + self.inputs[2]["allocation"] = attention + else: + raise + + def fetch_output(self): + if self.is_ixrt_backend(): + output = self.outputs[0] + result = np.zeros(output["shape"],output["dtype"]) + err, = cuda.cuMemcpyDtoH(result, output["allocation"], output["nbytes"]) + assert(err == cuda.CUresult.CUDA_SUCCESS) + return [result] + + elif self.is_ort_backend(): + return [output["allocation"] for output in self.outputs] + else: + raise + +def main(config): + input_dict = {} + input_name_list = [] + + for input_info in ['input_ids:1000,22', 'pixel_values:32,3,224,224', 'attention_mask:1000,22']: + input_name, input_shape = input_info.split(":") + shape = tuple([int(s) for s in input_shape.split(",")]) + input_name_list.append(input_name) + input_dict[input_name] = shape + dataloader = getclipdataloader(config.bsz, config.datasets_dir, input_dict) + + logger = tensorrt.Logger(tensorrt.Logger.ERROR) + runner = ClassificationRunner(config.engine_file, logger) + + # Inference + if config.test_mode == "FPS": + # Warm up + if config.warm_up > 0: + print("\nWarm Start.") + for i in range(config.warm_up): + runner.run() + print("Warm Done.") + torch.cuda.synchronize() + start_time = time.time() + + for i in range(config.loop_count): + runner.run() + + torch.cuda.synchronize() + end_time = time.time() + forward_time = end_time - start_time + + num_samples = 50000 + if config.loop_count * config.bsz < num_samples: + num_samples = config.loop_count * config.bsz + fps = num_samples / forward_time + + print("FPS : ", fps) + print(f"Performance Check : Test {fps} >= target {config.fps_target}") + if fps >= config.fps_target: + print("pass!") + exit() + else: + print("failed!") + exit(1) + + elif config.test_mode == "ACC": + total_sample = 0 + acc_top1, acc_top5 = 0, 0 + + # for input_id, image, attention, label in tqdm(dataloader): + with tqdm(total= len(dataloader)) as _tqdm: + for idx, (input_id, image, attention, batch_label) in enumerate(dataloader): + image = image.astype(runner.inputs[1]["dtype"]) + image = np.ascontiguousarray(image) + total_sample += image.shape[0] + + runner.load_input(input_id, image, attention) + runner.run() + output = runner.fetch_output()[0] + + # squeeze output shape [32,1000,1,1] to [32,1000] for mobilenet_v2 model + if len(output.shape) == 4: + output = output.squeeze(axis=(2,3)) + + batch_top1, batch_top5 = eval_batch(output, batch_label) + acc_top1 += batch_top1 + acc_top5 += batch_top5 + + _tqdm.set_postfix(acc_1='{:.4f}'.format(acc_top1/total_sample), + acc_5='{:.4f}'.format(acc_top5/total_sample)) + _tqdm.update(1) + + print(F"Acc@1 : {acc_top1/total_sample} = {acc_top1}/{total_sample}") + print(F"Acc@5 : {acc_top5/total_sample} = {acc_top5}/{total_sample}") + acc1 = acc_top1/total_sample + print(f"Accuracy Check : Test {acc1} >= target {config.acc_target}") + if acc1 >= config.acc_target: + print("pass!") + exit() + else: + print("failed!") + exit(1) + +def parse_config(): + parser = argparse.ArgumentParser() + parser.add_argument("--test_mode", type=str, default="FPS", help="FPS MAP") + parser.add_argument( + "--engine_file", + type=str, + help="engine file path" + ) + parser.add_argument( + "--datasets_dir", + type=str, + default="", + help="ImageNet dir", + ) + parser.add_argument("--warm_up", type=int, default=-1, help="warm_up times") + parser.add_argument("--bsz", type=int, default=32, help="test batch size") + parser.add_argument( + "--imgsz", + "--img", + "--img-size", + type=int, + default=224, + help="inference size h,w", + ) + parser.add_argument("--use_async", action="store_true") + parser.add_argument( + "--device", type=int, default=0, help="cuda device, i.e. 0 or 0,1,2,3,4" + ) + parser.add_argument("--fps_target", type=float, default=-1.0) + parser.add_argument("--acc_target", type=float, default=-1.0) + parser.add_argument("--loop_count", type=int, default=-1) + + config = parser.parse_args() + return config + +if __name__ == "__main__": + config = parse_config() + main(config) diff --git a/models/cv/classification/clip/ixrt/load_ixrt_plugin.py b/models/cv/classification/clip/ixrt/load_ixrt_plugin.py new file mode 100644 index 0000000000000000000000000000000000000000..a2efd6c50d3c1cb27cb686a15a9457f7a968506a --- /dev/null +++ b/models/cv/classification/clip/ixrt/load_ixrt_plugin.py @@ -0,0 +1,28 @@ +# Copyright (c) 2025, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from os.path import join, dirname, exists +import tensorrt as trt +import ctypes + +def load_ixrt_plugin(logger=trt.Logger(trt.Logger.WARNING), namespace="", dynamic_path=""): + if not dynamic_path: + dynamic_path = join(dirname(trt.__file__), "lib", "libixrt_plugin.so") + if not exists(dynamic_path): + raise FileNotFoundError( + f"The ixrt_plugin lib {dynamic_path} is not existed, please provided effective plugin path!") + ctypes.CDLL(dynamic_path, mode=ctypes.RTLD_GLOBAL) + trt.init_libnvinfer_plugins(logger, namespace) + print(f"Loaded plugin from {dynamic_path}") \ No newline at end of file diff --git a/models/cv/classification/clip/ixrt/modify_batchsize.py b/models/cv/classification/clip/ixrt/modify_batchsize.py new file mode 100644 index 0000000000000000000000000000000000000000..e36f78a7114d964a826fb5dbd8aec9e53c592aba --- /dev/null +++ b/models/cv/classification/clip/ixrt/modify_batchsize.py @@ -0,0 +1,76 @@ +# Copyright (c) 2025, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import onnx +import argparse + +def change_input_dim(model, bsz): + batch_size = bsz + + # The following code changes the first dimension of every input to be batch_size + # Modify as appropriate ... note that this requires all inputs to + # have the same batch_size + inputs = model.graph.input + for input in inputs: + # Checks omitted.This assumes that all inputs are tensors and have a shape with first dim. + # Add checks as needed. + dim1 = input.type.tensor_type.shape.dim[0] + # update dim to be a symbolic value + if isinstance(batch_size, str): + # set dynamic batch size + dim1.dim_param = batch_size + elif (isinstance(batch_size, str) and batch_size.isdigit()) or isinstance(batch_size, int): + # set given batch size + dim1.dim_value = int(batch_size) + else: + # set batch size of 1 + dim1.dim_value = 1 + +def infer_node_shape(model): + # remove old shape of the node + for value_info in model.graph.value_info: + tensor_type = value_info.type.tensor_type + if tensor_type.HasField('shape'): + tensor_type.ClearField('shape') + + for output_info in model.graph.output: + tensor_type = output_info.type.tensor_type + if tensor_type.HasField('shape'): + tensor_type.ClearField('shape') + + from onnx import checker, shape_inference + model = shape_inference.infer_shapes(model, strict_mode=True) + checker.check_model(model) + + return model + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument("--batch_size", type=int) + parser.add_argument("--origin_model", type=str) + parser.add_argument("--output_model", type=str) + parser.add_argument("--strict_mode", action='store_true') + args = parser.parse_args() + return args + +if __name__ == "__main__": + args = parse_args() + model = onnx.load(args.origin_model) + change_input_dim(model, args.batch_size) + + if args.strict_mode: + model = infer_node_shape(model) + + onnx.save(model, args.output_model) diff --git a/models/cv/classification/clip/ixrt/requirements.txt b/models/cv/classification/clip/ixrt/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..8632e5db676f58d73cdd7836b7abaef67f2698ef --- /dev/null +++ b/models/cv/classification/clip/ixrt/requirements.txt @@ -0,0 +1,3 @@ +tqdm +onnxsim +transformers==4.33.2 \ No newline at end of file diff --git a/models/cv/classification/clip/ixrt/scripts/infer_clip_fp16_accuracy.sh b/models/cv/classification/clip/ixrt/scripts/infer_clip_fp16_accuracy.sh new file mode 100644 index 0000000000000000000000000000000000000000..c5601bf21d24d54e96043bb49289d665996883d3 --- /dev/null +++ b/models/cv/classification/clip/ixrt/scripts/infer_clip_fp16_accuracy.sh @@ -0,0 +1,112 @@ +#!/bin/bash +# Copyright (c) 2025, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +EXIT_STATUS=0 +check_status() +{ + if ((${PIPESTATUS[0]} != 0));then + EXIT_STATUS=1 + fi +} + +# Run paraments +BSZ=32 +TGT=-1 +WARM_UP=0 +LOOP_COUNT=-1 +RUN_MODE=ACC +PRECISION=float16 + +# Update arguments +index=0 +options=$@ +arguments=($options) +for argument in $options +do + index=`expr $index + 1` + case $argument in + --bs) BSZ=${arguments[index]};; + --tgt) TGT=${arguments[index]};; + esac +done + +source ${CONFIG_DIR} +ORIGINE_MODEL=${CHECKPOINTS_DIR}/${ORIGINE_MODEL} + +echo CHECKPOINTS_DIR : ${CHECKPOINTS_DIR} +echo DATASETS_DIR : ${DATASETS_DIR} +echo RUN_DIR : ${RUN_DIR} +echo CONFIG_DIR : ${CONFIG_DIR} +echo ====================== Model Info ====================== +echo Model Name : ${MODEL_NAME} +echo Onnx Path : ${ORIGINE_MODEL} + +step=0 + +# Change Input size and Simplify Model +let step++ +echo; +echo [STEP ${step}] : Change Batchsize and Simplify +SIM_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_${BSZ}_sim.onnx +if [ -f $SIM_MODEL ];then + echo " "Change Input size and Simplify Model Skip, $SIM_MODEL has been existed +else + onnxsim ${ORIGINE_MODEL} ${SIM_MODEL} \ + --overwrite-input-shape input_ids:1000,22 pixel_values:${BSZ},3,224,224 attention_mask:1000,22 + echo " "Generate ${SIM_MODEL} +fi + +# optimizer +let step++ +echo; +echo [STEP ${step}] : Optimizer +FINAL_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_${BSZ}_sim_end.onnx +if [ -f $FINAL_MODEL ];then + echo " "Optimizer Model Skip, $FINAL_MODEL has been existed +else + python3 ${OPTIMIER_FILE} --onnx ${SIM_MODEL} --model_type vit + echo " "Generate ${FINAL_MODEL} +fi + +# Build Engine +let step++ +echo; +echo [STEP ${step}] : Build Engine +ENGINE_FILE=${CHECKPOINTS_DIR}/${MODEL_NAME}_${PRECISION}_bs${BSZ}.engine +if [ -f $ENGINE_FILE ];then + echo " "Build Engine Skip, $ENGINE_FILE has been existed +else + python3 ${RUN_DIR}/build_engine.py \ + --precision ${PRECISION} \ + --model ${FINAL_MODEL} \ + --engine ${ENGINE_FILE} + echo " "Generate Engine ${ENGINE_FILE} +fi + +# Inference +let step++ +echo; +echo [STEP ${step}] : Inference +python3 ${RUN_DIR}/inference.py \ + --engine_file=${ENGINE_FILE} \ + --datasets_dir=${DATASETS_DIR} \ + --imgsz=${IMGSIZE} \ + --warm_up=${WARM_UP} \ + --loop_count ${LOOP_COUNT} \ + --test_mode ${RUN_MODE} \ + --acc_target ${TGT} \ + --bsz ${BSZ}; check_status + +exit ${EXIT_STATUS} diff --git a/models/cv/classification/clip/ixrt/scripts/infer_clip_fp16_performance.sh b/models/cv/classification/clip/ixrt/scripts/infer_clip_fp16_performance.sh new file mode 100644 index 0000000000000000000000000000000000000000..3873609d51c4deabb4bdfa90b0bfd9a1c09e6c83 --- /dev/null +++ b/models/cv/classification/clip/ixrt/scripts/infer_clip_fp16_performance.sh @@ -0,0 +1,112 @@ +#!/bin/bash +# Copyright (c) 2025, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +EXIT_STATUS=0 +check_status() +{ + if ((${PIPESTATUS[0]} != 0));then + EXIT_STATUS=1 + fi +} + +# Run paraments +BSZ=32 +TGT=-1 +WARM_UP=3 +LOOP_COUNT=20 +RUN_MODE=FPS +PRECISION=float16 + +# Update arguments +index=0 +options=$@ +arguments=($options) +for argument in $options +do + index=`expr $index + 1` + case $argument in + --bs) BSZ=${arguments[index]};; + --tgt) TGT=${arguments[index]};; + esac +done + +source ${CONFIG_DIR} +ORIGINE_MODEL=${CHECKPOINTS_DIR}/${ORIGINE_MODEL} + +echo CHECKPOINTS_DIR : ${CHECKPOINTS_DIR} +echo DATASETS_DIR : ${DATASETS_DIR} +echo RUN_DIR : ${RUN_DIR} +echo CONFIG_DIR : ${CONFIG_DIR} +echo ====================== Model Info ====================== +echo Model Name : ${MODEL_NAME} +echo Onnx Path : ${ORIGINE_MODEL} + +step=0 + +# Change Input size and Simplify Model +let step++ +echo; +echo [STEP ${step}] : Change Batchsize and Simplify +SIM_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_${BSZ}_sim.onnx +if [ -f $SIM_MODEL ];then + echo " "Change Input size and Simplify Model Skip, $SIM_MODEL has been existed +else + onnxsim ${ORIGINE_MODEL} ${SIM_MODEL} \ + --overwrite-input-shape input_ids:1000,22 pixel_values:${BSZ},3,224,224 attention_mask:1000,22 + echo " "Generate ${SIM_MODEL} +fi + +# optimizer +let step++ +echo; +echo [STEP ${step}] : Optimizer +FINAL_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_${BSZ}_sim_end.onnx +if [ -f $FINAL_MODEL ];then + echo " "Optimizer Model Skip, $FINAL_MODEL has been existed +else + python3 ${OPTIMIER_FILE} --onnx ${SIM_MODEL} --model_type vit + echo " "Generate ${FINAL_MODEL} +fi + +# Build Engine +let step++ +echo; +echo [STEP ${step}] : Build Engine +ENGINE_FILE=${CHECKPOINTS_DIR}/${MODEL_NAME}_${PRECISION}_bs${BSZ}.engine +if [ -f $ENGINE_FILE ];then + echo " "Build Engine Skip, $ENGINE_FILE has been existed +else + python3 ${RUN_DIR}/build_engine.py \ + --precision ${PRECISION} \ + --model ${FINAL_MODEL} \ + --engine ${ENGINE_FILE} + echo " "Generate Engine ${ENGINE_FILE} +fi + +# Inference +let step++ +echo; +echo [STEP ${step}] : Inference +python3 ${RUN_DIR}/inference.py \ + --engine_file=${ENGINE_FILE} \ + --datasets_dir=${DATASETS_DIR} \ + --imgsz=${IMGSIZE} \ + --warm_up=${WARM_UP} \ + --loop_count ${LOOP_COUNT} \ + --test_mode ${RUN_MODE} \ + --fps_target ${TGT} \ + --bsz ${BSZ}; check_status + +exit ${EXIT_STATUS} diff --git a/models/cv/classification/clip/ixrt/simplify_model.py b/models/cv/classification/clip/ixrt/simplify_model.py new file mode 100644 index 0000000000000000000000000000000000000000..bef33576a17235d24305fa32ae3dab6d7accc10e --- /dev/null +++ b/models/cv/classification/clip/ixrt/simplify_model.py @@ -0,0 +1,41 @@ +# Copyright (c) 2025, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import onnx +import argparse +from onnxsim import simplify + +# Simplify +def simplify_model(args): + onnx_model = onnx.load(args.origin_model) + model_simp, check = simplify(onnx_model) + model_simp = onnx.shape_inference.infer_shapes(model_simp) + onnx.save(model_simp, args.output_model) + print(" Simplify onnx Done.") + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument("--origin_model", type=str) + parser.add_argument("--output_model", type=str) + parser.add_argument("--reshape", action="store_true") + args = parser.parse_args() + return args + +args = parse_args() +simplify_model(args) + + + + diff --git a/models/cv/classification/ixrt_common/config/CLIP_CONFIG b/models/cv/classification/ixrt_common/config/CLIP_CONFIG new file mode 100644 index 0000000000000000000000000000000000000000..0aa1670b3e2e3836cdd785d983a78d9c057330d1 --- /dev/null +++ b/models/cv/classification/ixrt_common/config/CLIP_CONFIG @@ -0,0 +1,6 @@ +# IMGSIZE : 模型输入hw大小 +# MODEL_NAME : 生成onnx/engine的basename +# ORIGINE_MODEL : 原始onnx文件名称 +IMGSIZE=224 +MODEL_NAME=Clip +ORIGINE_MODEL=clip.onnx \ No newline at end of file diff --git a/tests/model_info.json b/tests/model_info.json index a445277773218d771fef10e2e097805cdd4b0ae3..e4e183625689c94a4c75be03c53e2b7c1e76f73c 100644 --- a/tests/model_info.json +++ b/tests/model_info.json @@ -7999,6 +7999,39 @@ "type": "inference", "hasDemo": false, "demoType": "" + }, + { + "display_name": "CLIP", + "model_name": "clip", + "framework": "ixrt", + "release_version": "25.09", + "release_sdk": "4.3.0", + "release_gpgpu": "MR-V100", + "latest_sdk": "", + "latest_gpgpu": "", + "category": "cv/classification", + "toolbox": "", + "mdims": "", + "dataset": "", + "license": "", + "model_path": "models/cv/classification/clip/ixrt/", + "readme_file": "models/cv/classification/clip/ixrt/README.md", + "bitbucket_repo": "", + "bitbucket_branch": "", + "bitbucket_path": "", + "develop_owner": "", + "github_repo": "", + "github_branch": "", + "github_path": "", + "datasets": "https://www.image-net.org/download.php", + "download_url": "https://huggingface.co/openai/clip-vit-base-patch32", + "need_third_part": "", + "precisions": [ + "fp16" + ], + "type": "inference", + "hasDemo": false, + "demoType": "" } ] } \ No newline at end of file diff --git a/tests/run_ixrt.py b/tests/run_ixrt.py index 20fa416365f4eb1d4046539c26b7bb1433e87fd3..36979d609533264fe714a1a52f9352677f273a32 100644 --- a/tests/run_ixrt.py +++ b/tests/run_ixrt.py @@ -174,16 +174,29 @@ def run_clf_testcase(model): for prec in model["precisions"]: logging.info(f"Start running {model_name} {prec} test case") - script = f""" - cd ../{model['model_path']} - export DATASETS_DIR=/root/data/datasets/imagenet-val - export PROJ_DIR=../../ixrt_common/ - export CHECKPOINTS_DIR=./checkpoints - export RUN_DIR=../../ixrt_common/ - export CONFIG_DIR=../../ixrt_common/config/{config_name}_CONFIG - bash scripts/infer_{model_name}_{prec}_accuracy.sh - bash scripts/infer_{model_name}_{prec}_performance.sh - """ + if model_name == "clip": + script = f""" + cd ../{model['model_path']} + export DATASETS_DIR=/root/data/datasets/imagenet-val + export OPTIMIER_FILE=./iluvatar-corex-ixrt/tools/optimizer/optimizer.py + export PROJ_DIR=../../ixrt_common/ + export CHECKPOINTS_DIR=./checkpoints + export RUN_DIR=../../ixrt_common/ + export CONFIG_DIR=../../ixrt_common/config/{config_name}_CONFIG + bash scripts/infer_{model_name}_{prec}_accuracy.sh + bash scripts/infer_{model_name}_{prec}_performance.sh + """ + else: + script = f""" + cd ../{model['model_path']} + export DATASETS_DIR=/root/data/datasets/imagenet-val + export PROJ_DIR=../../ixrt_common/ + export CHECKPOINTS_DIR=./checkpoints + export RUN_DIR=../../ixrt_common/ + export CONFIG_DIR=../../ixrt_common/config/{config_name}_CONFIG + bash scripts/infer_{model_name}_{prec}_accuracy.sh + bash scripts/infer_{model_name}_{prec}_performance.sh + """ if model_name == "swin_transformer_large": script = f"""