CLIPに関連するプログラムを実行した際に出るurllib.error.URLError: の解決法 [Proxy]

画像生成のプログラムでよく出てくるCLIP。CLIPに依存しているプログラムは多く存在し、CLIP周りのエラーを解決しないと、目的のプログラムを実行することができなくなってしまう。

今回は、プロキシ環境下で出やすい下記エラーの解決方法を解説する。

Traceback (most recent call last):
File “clip_intro.py", line 6, in
model, preprocess = clip.load(“ViT-B/32", device=device)
File “/usr/local/lib/python3.8/dist-packages/clip/clip.py", line 120, in load
model_path = _download(_MODELS[name], download_root or os.path.expanduser(“~/.cache/clip"))
File “/usr/local/lib/python3.8/dist-packages/clip/clip.py", line 59, in _download
with urllib.request.urlopen(url) as source, open(download_target, “wb") as output:
File “/usr/lib/python3.8/urllib/request.py", line 222, in urlopen
return opener.open(url, data, timeout)
File “/usr/lib/python3.8/urllib/request.py", line 525, in open
response = self._open(req, data)
File “/usr/lib/python3.8/urllib/request.py", line 542, in _open
result = self._call_chain(self.handle_open, protocol, protocol +
File “/usr/lib/python3.8/urllib/request.py", line 502, in _call_chain
result = func(*args)
File “/usr/lib/python3.8/urllib/request.py", line 1397, in https_open
return self.do_open(http.client.HTTPSConnection, req,
File “/usr/lib/python3.8/urllib/request.py", line 1357, in do_open
raise URLError(err)
urllib.error.URLError:

解決方法は単純で、urllib による HTTP リクエストをプロキシ経由で行えるように設定することである。例えば、CLIPのgithubで紹介されている下記サンプルに対して、

import torch
import clip
from PIL import Image

device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load("ViT-B/32", device=device)

image = preprocess(Image.open("CLIP.png")).unsqueeze(0).to(device)
text = clip.tokenize(["a diagram", "a dog", "a cat"]).to(device)

with torch.no_grad():
    image_features = model.encode_image(image)
    text_features = model.encode_text(text)
    
    logits_per_image, logits_per_text = model(image, text)
    probs = logits_per_image.softmax(dim=-1).cpu().numpy()

print("Label probs:", probs)  # prints: [[0.9927937  0.00421068 0.00299572]]

以下のように変更を加える。これだけで筆者は外部からCLIPモデルのダウンロードが行えるようになり、サンプルは無事に実行された。

import torch
import clip
from PIL import Image
import urllib.request

PROXIES = {
    'http': 'http://proxy.example.com:8080',
    'https': 'https://proxy.example.com:8080',
    'ftp': 'ftp://proxy.example.com:8080'
}

def setup_proxy():
    proxy = urllib.request.ProxyHandler(PROXIES)
    opener = urllib.request.build_opener(proxy)
    urllib.request.install_opener(opener)

if __name__ == "__main__":
    setup_proxy()

    device = "cuda" if torch.cuda.is_available() else "cpu"
    model, preprocess = clip.load("ViT-B/32", device=device)

    image = preprocess(Image.open("CLIP.png")).unsqueeze(0).to(device)
    text = clip.tokenize(["a diagram", "a dog", "a cat"]).to(device)

    with torch.no_grad():
        image_features = model.encode_image(image)
        text_features = model.encode_text(text)

        logits_per_image, logits_per_text = model(image, text)
        probs = logits_per_image.softmax(dim=-1).cpu().numpy()

    print("Label probs:", probs)

参考

https://maku77.github.io/python/web/http-request-with-proxy.html

GenerativeAI,Python

Posted by vastee