Python transformers で Hugging Face からモデルダウンロード時に発生する certificate verify failed: self signed certificate in certificate chain / Missing Authority Key Identifier エラーに対応する

Python transformers のパッケージで Hugging Face からモデルをダウンロードする際、TLS インスペクションが入っている環境で発生する certificate verify failed: self signed certificate in certificate chain エラーと Python 3.13 で発生する certificate verify failed: Missing Authority Key Identifier エラーに対応する方法を紹介します。

やりたいこと

企業の環境等で TLS インスペクションが入っている環境において transformers パッケージで Hugging Face からモデルをダウンロードする際 certificate verify failed: self signed certificate in certificate chain エラーが発生することがあります。また Python 3.13 では ssl.create_default_context() で作成される ss.SSLContext.verify_flags のデフォルト値が変更されたことにより certificate verify failed: Missing Authority Key Identifier エラーが発生することがあります。これらの対応方法を紹介したいと思います。

環境

OS
Microsoft Windows 11 23H2
Python
3.13.7
transformers
4.56.1

事象

transformers パッケージでモデルを使用する場合、pipeline()AutoModelForCausalLM.from_pretrained() でモデルをロードしますが、ローカルキャッシュに対応するモデルがない場合、Hugging Face リポジトリからダウンロードされます。例えば以下のようなコードを実行します。

import torch
from transformers import pipeline

pipe = pipeline(
  "text-generation", 
  model="TinyLlama/TinyLlama-1.1B-Chat-v1.0", 
  torch_dtype=torch.bfloat16, 
  device_map="auto"
  )

messages = [
  {"role": "user", "content": "素数を小さい順に 5 つ教えてください"},
]
prompt = pipe.tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
outputs = pipe(prompt, max_new_tokens=256, do_sample=True, temperature=0.7, top_k=50, top_p=0.95)
print(outputs[0]["generated_text"])

この際 TLS インスペクションがある環境の場合 [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain というエラーが発生することがあります。

このエラーは TLS インスペクションが入っていることにより証明書検証でエラーとなっていることがほとんどです。 TLS インスペクションの簡単な説明と、後ほど使用する証明書の特定、取得方法を こちらの記事 で紹介していますので必要であればご参照ください。

対応方法

transformers は HTTP リクエストの実行に requests パッケージを使用しています。こちらの記事 で詳しく説明していますが、requests では環境変数 REQUESTS_CA_BUNDLE で証明書を指定することができます。

import torch
from transformers import pipeline

import os

os.environ["REQUESTS_CA_BUNDLE"] = "C://path/to/cert.pem"

from huggingface_hub import configure_http_backend
from backend_factory import backend_factory

pipe = pipeline(
  "text-generation", 
  model="TinyLlama/TinyLlama-1.1B-Chat-v1.0", 
  torch_dtype=torch.bfloat16, 
  device_map="auto"
  )

messages = [
  {"role": "user", "content": "素数を小さい順に 5 つ教えてください"},
]
prompt = pipe.tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
outputs = pipe(prompt, max_new_tokens=256, do_sample=True, temperature=0.7, top_k=50, top_p=0.95)
print(outputs[0]["generated_text"])

環境変数 REQUESTS_CA_BUNDLE に証明書パスを指定することで [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain エラーが出ずにモデルダウンロードができるようになります。繰り返しになりますが、追加する証明書の特定、取得方法を こちらの記事 で紹介していますので必要であればご参照ください。

Python 3.13 以降

Python 3.13 以降では上記対応を行っても、次は [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Missing Authority Key Identifier エラーが発生することがあります。これは Python 3.13 で ssl.create_default_context() が作成する ssl.SSLContextverify_flags のデフォルト値が変更されたことが原因です。詳しくは こちらの記事 で説明しています。

これに対応するにはカスタムした ssl.SSLContext を使用して HTTPS リクエストをさせる必要があるのですが、requests.Session()huggingface_hub.configure_http_backend を使用することで実現することができます。

huggingface_hub.configure_http_backend

( backend_factory: typing.Callable[[], requests.sessions.Session] = <function _default_backend_factory at 0x7f7b97a6a0e0> )

Configure the HTTP backend by providing a backend_factory. Any HTTP calls made by huggingface_hub will use a Session object instantiated by this factory.
Utilities

具体的な実装は以下の通りです。ついでに先ほどの [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain エラーへの対応は環境変数ではなく、カスタム ssl.SSLContext 内で対応します。

まず backend_factory.py モジュールを用意します。このコードの詳しい説明は こちらの記事 を参照してください。

import ssl
import requests
from requests.adapters import HTTPAdapter 

class CustomSSLAdapter(HTTPAdapter):
  def init_poolmanager(self, connections, maxsize, block=False, **pool_kwargs):
    ctx = ssl.create_default_context()
    ctx.verify_flags = ssl.VERIFY_X509_TRUSTED_FIRST | ssl.VERIFY_X509_PARTIAL_CHAIN
    ctx.load_verify_locations(cafile="C:/path/to/cert.pem")
    pool_kwargs["ssl_context"] = ctx
    return super().init_poolmanager(connections, maxsize, block, **pool_kwargs)

def backend_factory():
  session = requests.Session()
  session.mount("https://", CustomSSLAdapter())
  return session

その上で、メインのコードで backend_factory モジュールを使用し、huggingface_hub.configure_http_backend に割り当てます。

import torch
from transformers import pipeline

from huggingface_hub import configure_http_backend
from backend_factory import backend_factory

configure_http_backend(backend_factory=backend_factory)

pipe = pipeline(
  "text-generation", 
  model="TinyLlama/TinyLlama-1.1B-Chat-v1.0", 
  torch_dtype=torch.bfloat16, 
  device_map="auto"
  )

messages = [
  {"role": "user", "content": "素数を小さい順に 5 つ教えてください"},
]
prompt = pipe.tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
outputs = pipe(prompt, max_new_tokens=256, do_sample=True, temperature=0.7, top_k=50, top_p=0.95)
print(outputs[0]["generated_text"])

これで [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Missing Authority Key Identifier エラーが出なくなり、モデルのダウンロードができるようになります。

(非推奨) 証明書検証をオフにする

セキュリティー的におすすめしませんが、証明書検証をオフにすることで上記両方のエラーが出なくなります。

import requests
from huggingface_hub import configure_http_backend

def backend_factory():
  session = requests.Session(verify=False)
  return session

configure_http_backend(backend_factory=backend_factory)

あとがき

Python 3.13 で ssl.create_default_context() で作成される ssl.SSLContextverify_flags のデフォルト値が変わったのが結構インパクト大きいですね。transformers は HTTP バックエンドをいじれるようになっていたので何とかなりました。requests 等の HTTP リクエストパッケージを内包していて、外から requests をいじれるような API が用意されていないパッケージにおいてはしばらく Python 3.12 で使用するしかないかもしれませんね。