CLIP
いまさら Stable Diffusion Web UI の CLIP について見てみる。
Open AI の CLIP モデル。Salesforce の BLIP が有名。あと Open CLIP。
次のようなコードで文章と画像の類似度が計算できる。
code:hoge.py
model, _, preprocess = open_clip.create_model_and_transforms('convnext_base_w', pretrained='laion2b_s13b_b82k_augreg')
model.eval()
context_length = model.context_length
vocab_size = model.vocab_size
print("Context length:", context_length)
print("Vocab size:", vocab_size)
image_input = torch.tensor(np.stack(images))
with torch.no_grad():
image_features = model.encode_image(image_input).float()
text_features = model.encode_text(text_tokens).float()
image_features /= image_features.norm(dim=-1, keepdim=True)
text_features /= text_features.norm(dim=-1, keepdim=True)
similarity = text_features.cpu().numpy() @ image_features.cpu().numpy().T
類似度をマトリックスで表現すると次のような画像になる。
https://gyazo.com/7dd14e82a014729bd7376fe954411dcc
文章はトークナイザによって77次元のベクトルに圧縮される。トークナイザが77次元にする理由は CLIP が扱うコンテキスト長が77であるため、77次元を期待しているから。
q.icon なぜ77次元なのか?
OpenCLIP のトークナイザはいくつか選べるようになっている。デフォルトは SimpleTokenizer
CLIP の論文を読めばわかるかも。CLIP の実装をみてみると 77 になっている。
q.icon 決められたコンテキスト長があるのに Stable Diffusion Web UI はたくさんのプロンプトを詰め込める。なぜだろうか?