1import cv2
2import torch
3import os
4import numpy as np
5import onnxruntime as rt
6from huggingface_hub import hf_hub_download
7from torch.utils.data import DataLoader, Dataset
8from PIL import Image
9from tqdm import tqdm
10from threading import Thread
11
12
13class MyDataset(Dataset):
14 def __init__(self, image_list):
15 self.image_list = image_list
16
17 def __len__(self):
18 length = len(self.image_list)
19 return length
20
21 def __getitem__(self, index):
22 image = Image.open(self.image_list[index]).convert("RGB")
23 image = np.asarray(image)
24 s = 512
25 h, w = image.shape[:-1]
26 h, w = (s, int(s * w / h)) if h > w else (int(s * h / w), s)
27 ph, pw = s - h, s - w
28 image = cv2.resize(image, (w, h), interpolation=cv2.INTER_AREA)
29 image = cv2.copyMakeBorder(image, ph // 2, ph - ph // 2, pw // 2, pw - pw // 2, cv2.BORDER_REPLICATE)
30 image = image.astype(np.float32) / 255
31 image = torch.from_numpy(image)
32 idx = torch.tensor([index], dtype=torch.int32)
33 return image, idx
34
35
36def get_images(path):
37 def file_ext(fname):
38 return os.path.splitext(fname)[1].lower()
39
40 all_files = {
41 os.path.relpath(os.path.join(root, fname), path)
42 for root, _dirs, files in os.walk(path)
43 for fname in files
44 }
45 all_images = sorted(
46 os.path.join(path, fname) for fname in all_files if file_ext(fname) in [".png", ".jpg", ".jpeg"]
47 )
48 print(len(all_images))
49 return all_images
50
51
52def process(all_images, batch_size=8, score_threshold=0.35):
53 predictions = {}
54
55 def work_fn(images, device_id):
56 dataset = MyDataset(images)
57 dataloader = DataLoader(
58 dataset,
59 batch_size=batch_size,
60 shuffle=False,
61 persistent_workers=True,
62 num_workers=4,
63 pin_memory=True,
64 )
65 for data in tqdm(dataloader):
66 image, idxs = data
67 image = image.numpy()
68 probs = tagger_model[device_id].run(None, {"input_1": image})[0]
69 probs = probs.astype(np.float32)
70 bs = probs.shape[0]
71 for i in range(bs):
72 tags = []
73 for prob, label in zip(probs[i].tolist(), tagger_tags):
74 if prob > score_threshold:
75 tags.append((label, prob))
76 predictions[images[idxs[i].item()]] = tags
77
78 gpu_num = len(tagger_model)
79 image_num = (len(all_images) // gpu_num) + 1
80 ts = [Thread(target=work_fn, args=(all_images[i * image_num:(i + 1) * image_num], i)) for i in range(gpu_num)]
81 for t in ts:
82 t.start()
83 for t in ts:
84 t.join()
85 return predictions
86
87
88gpu_num = 4
89batch_size = 8
90tagger_model_path = hf_hub_download(repo_id="skytnt/deepdanbooru_onnx", filename="deepdanbooru.onnx")
91tagger_model = [
92 rt.InferenceSession(tagger_model_path, providers=['CUDAExecutionProvider'], provider_options=[{'device_id': i}]) for
93 i in range(gpu_num)]
94tagger_model_meta = tagger_model[0].get_modelmeta().custom_metadata_map
95tagger_tags = eval(tagger_model_meta['tags'])
96
97all_images = get_images("./data")
98predictions = process(all_images, batch_size)