0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ComfyUI用の、WANVideoやCogVideoXなどのローカル動画生成AIのモデルの一括ダウンロード法

Last updated at Posted at 2025-03-28
ComfyUI用の、WANVideoやCogVideoXなどのローカル動画生成AIのモデルの一括ダウンロード法

ComfyUIのフレームワークで動作するローカル動画生成AIを実験する場合、多くのモデルをダウンロードする必要があり、そのための待ち時間が長いので、出かける前や寝る前にしかけて一気にまとめてダウンロードするのが吉。
それを一気に行うpython用のコードをClaudeで生成した。

import os
import requests
import re
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path

def get_files_list(repo_url):
    """
    HuggingFaceリポジトリから.safetensorsファイルのURLリストを取得します
    """
    # APIエンドポイントのURLを作成
    api_url = repo_url.replace('https://huggingface.co/', 'https://huggingface.co/api/repos/').rstrip('/') + '/refs/main/tree'
    
    # APIリクエスト
    response = requests.get(api_url)
    if response.status_code != 200:
        raise Exception(f"APIリクエストエラー: {response.status_code}")
    
    repo_files = response.json()
    
    # .safetensorsファイルのみをフィルタリング
    safetensor_files = []
    
    def process_item(item):
        # ディレクトリの場合は再帰的に取得
        if item['type'] == 'directory':
            subdir_url = f"{api_url}/{item['path']}"
            subdir_response = requests.get(subdir_url)
            if subdir_response.status_code == 200:
                return process_items(subdir_response.json())
        # .safetensorsファイルの場合はリストに追加
        elif item['path'].endswith('.safetensors'):
            return [{
                'filename': os.path.basename(item['path']),
                'path': item['path'],
                'download_url': f"https://huggingface.co/{repo_url.split('https://huggingface.co/')[1]}/resolve/main/{item['path']}"
            }]
        return []
    
    def process_items(items):
        result = []
        for item in items:
            result.extend(process_item(item))
        return result
    
    safetensor_files = process_items(repo_files)
    
    return safetensor_files

def download_file(file_info, output_dir, max_retries=3):
    """
    ファイルをダウンロードする関数
    """
    filename = file_info['filename']
    download_url = file_info['download_url']
    output_path = os.path.join(output_dir, filename)
    
    # 既に存在するファイルはスキップ
    if os.path.exists(output_path):
        print(f"ファイルはすでに存在します: {filename}")
        return True
    
    for attempt in range(max_retries):
        try:
            response = requests.get(download_url, stream=True)
            response.raise_for_status()
            
            total_size = int(response.headers.get('content-length', 0))
            
            with open(output_path, 'wb') as file, tqdm(
                    desc=filename,
                    total=total_size,
                    unit='B',
                    unit_scale=True,
                    unit_divisor=1024,
            ) as progress_bar:
                for chunk in response.iter_content(chunk_size=1024*1024):
                    file.write(chunk)
                    progress_bar.update(len(chunk))
            
            return True
            
        except Exception as e:
            print(f"ダウンロード中にエラーが発生しました ({attempt+1}/{max_retries}): {filename} - {str(e)}")
            if attempt == max_retries - 1:
                print(f"ファイルのダウンロードに失敗しました: {filename}")
                return False

def main():
    # ダウンロード対象のリポジトリURL
    repo_url = "https://huggingface.co/Kijai/WanVideo_comfy/tree/main"
    
    # 出力ディレクトリ
    output_dir = "downloaded_safetensors"
    os.makedirs(output_dir, exist_ok=True)
    
    print(f"リポジトリからファイルリストを取得中: {repo_url}")
    files_to_download = get_files_list(repo_url)
    
    print(f"ダウンロードするファイル数: {len(files_to_download)}")
    
    # 複数スレッドでダウンロードを実行
    successful_downloads = 0
    with ThreadPoolExecutor(max_workers=4) as executor:
        results = list(executor.map(
            lambda file_info: download_file(file_info, output_dir),
            files_to_download
        ))
        successful_downloads = sum(results)
    
    print(f"ダウンロード完了: {successful_downloads}/{len(files_to_download)} ファイル")

if __name__ == "__main__":
    main()

WANVideoの場合は、上のコードの以下の部分がWANVideoのダウンロードもとを指定している。

   # ダウンロード対象のリポジトリURL
    repo_url = "https://huggingface.co/Kijai/WanVideo_comfy/tree/main"

ComfyUIの動作する環境で、上のコードをコピペしたファイルがgetmodels.pyとすると

python getmodels.py

でダウンロードが始まる。
モデルデータはでかいので、ダウンロードする場所の要領に注意

このコードはよくできていて、CogVideoX1.5-5B-SAT 関連のモデルをダウンロードしようと
以下のようのしたが、これは間違いでエラーがでるが代替の方法が示唆される

代替ダウンロード方法でエラーが発生しました: Command '['huggingface-cli', 'download', 'THUDM/CogVideoX1.5-5B-SAT/t5-v1_1-xxl', '--include=*.safetensors', '--local-dir', 'downloaded_safetensors']' returned non-zero exit status 1.
すべてのダウンロード方法が失敗しました。

代替方法2: 以下のコマンドを直接実行してみてください:
pip install huggingface_hub
python -c "from huggingface_hub import snapshot_download; snapshot_download('Kijai/WanVideo_comfy', local_dir='downloaded_safetensors', allow_patterns=['*.safetensors'])"

それにしたがって、snapshot_download('Kijai/WanVideo_comfy' のクォーテーション内をHuggingFaceで検索したレポジトリ名に入れ替えて

python -c "from huggingface_hub import snapshot_download; snapshot_download('THUDM/CogVideoX1.5-5B-SAT', local_dir='downloaded_safetensors', allow_patterns=['*.safetensors'])"

と実行することで、CogVideoX1.5-5B-SAT を無事ダウンロードできた。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?