W-CLIP-Base / wclip-base-inference-example.py
gatilin's picture
Upload 12 files
517bdbb verified
Raw History Blame Contribute Delete
2.57 kB
"""Standalone inference example for the wclip-base ONNX encoders.
Only needs onnxruntime + transformers (the copied tokenizer). No original
WeCLIP code or weights required.
Usage:
python wclip-base-inference-example.py [image_path] [text1] [text2] ...
"""
import sys, os
import numpy as np
import onnxruntime as ort
import cv2
from transformers import AutoTokenizer
BASE = os.path.dirname(os.path.abspath(__file__))
IMG_ONNX = os.path.join(BASE, 'wclip-base-image-encoder.onnx')
TXT_ONNX = os.path.join(BASE, 'wclip-base-text-encoder.onnx')
TOK_DIR = os.path.join(BASE, 'wclip-base-tokenizer')
TEMPERATURE = 0.01
def preprocess_image(img_path):
data = open(img_path, 'rb').read()
arr = np.frombuffer(data, np.uint8)
img = cv2.imdecode(arr, cv2.IMREAD_COLOR)[..., ::-1]
img = cv2.resize(img, (224, 224)).astype(np.float32) / 255.0
mean = np.array([0.48145466, 0.4578275, 0.40821073], np.float32)
std = np.array([0.26862954, 0.26130258, 0.27577711], np.float32)
img = (img - mean) * (1.0 / std)
return img.transpose(2, 0, 1)[None].astype(np.float32)
def main():
args = sys.argv[1:]
img_path = args[0] if args else os.path.join(BASE, '..', 'weclip', 'assets', 'demo.jpeg')
texts = args[1:] if len(args) > 1 else ['狗', '猫', '兔子', '熊猫']
img_t = preprocess_image(img_path)
tok = AutoTokenizer.from_pretrained(TOK_DIR, padding_side='right')
enc = tok(texts, padding='max_length', truncation=True, max_length=72,
return_tensors='np', return_attention_mask=True)
ids = enc['input_ids'].astype(np.int64)
mask = enc['attention_mask'].astype(np.int64)
img_sess = ort.InferenceSession(IMG_ONNX, providers=['CPUExecutionProvider'])
txt_sess = ort.InferenceSession(TXT_ONNX, providers=['CPUExecutionProvider'])
imf = img_sess.run(['image_embedding_1024'], {'image_tensor': img_t})[0]
outputs = txt_sess.run(['text_embedding_1024'],
{'text_token_id_tensor': ids, 'text_mask_tensor': mask})[0]
imf = imf / np.linalg.norm(imf, axis=-1, keepdims=True)
outputs = outputs / np.linalg.norm(outputs, axis=-1, keepdims=True)
logits = 100.0 * (imf @ outputs.T).squeeze()
logits = logits - logits.max()
probs = np.exp(logits) / np.exp(logits).sum()
print(f'image : {os.path.basename(img_path)}')
print(f'texts : {texts}')
print(f'probs : {[round(float(p), 4) for p in probs]}')
print(f'pred : {texts[int(np.argmax(probs))]}')
return texts[int(np.argmax(probs))]
if __name__ == '__main__':
main()