Shap-E のインストールと動作確認(テキストや画像からの立体生成)(Python,PyTorch を使用)(Windows 上)

Shap-e のインストールと立体生成を行う.

Shap-E

Shap-e は、テクスチャ付きメッシュ (textured mesh)や neural radient fields としてレンダリングできる出力を生成 する能力を特徴とする。 Point-E との比較では、高速、高品質の生成が可能であるとされている。

目次

  1. 前準備
  2. Shap-E のインストール(Windows 上)
  3. Shap-E の動作確認(Windows 上)
  4. Shap-E を使う Python プログラムの実行(Windows 上)

文献

Heewoo Jun, Alex Nichol, Shap-E: Generating Conditional 3D Implicit Functions, https://arxiv.org/abs/2305.02463, 2023.

https://arxiv.org/pdf/2305.02463v1.pdf

関連する外部ページ

前準備

Build Tools for Visual Studio 2022 のインストール(Windows 上)

Build Tools for Visual Studio は,Visual Studio の IDE を含まない C/C++ コンパイラ,ライブラリ,ビルドツール等のコマンドライン向け開発ツールセットである。

以下のコマンドを管理者権限コマンドプロンプトで実行する (手順:Windowsキーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」)。

REM VC++ ランタイム
winget install --scope machine --id Microsoft.VCRedist.2015+.x64 -e --silent --disable-interactivity --force --accept-source-agreements --accept-package-agreements --override "/quiet /norestart"

REM Build Tools + Desktop development with C++(VCTools)+ 追加コンポーネント(一括)
winget install --id Microsoft.VisualStudio.2022.BuildTools --accept-source-agreements --accept-package-agreements ^
    --override "--passive --wait --norestart --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --add Microsoft.VisualStudio.Component.VC.Llvm.Clang --add Microsoft.VisualStudio.ComponentGroup.ClangCL --add Microsoft.VisualStudio.Component.VC.CMake.Project --add Microsoft.VisualStudio.Component.Windows11SDK.26100"

--add で追加されるコンポーネント

上記のコマンドでは,まず Build Tools 本体と Visual C++ 再頒布可能パッケージをインストールし,次に setup.exe を用いて以下のコンポーネントを追加している。

インストール完了の確認

winget list Microsoft.VisualStudio.2022.BuildTools

上記以外の追加のコンポーネントが必要になった場合は Visual Studio Installer で個別にインストールできる。

Visual Studio の機能を必要とする場合は、追加インストールできる。

Python 3.12 のインストール(Windows 上) [クリックして展開]

以下のいずれかの方法で Python 3.12 をインストールする。Python がインストール済みの場合、この手順は不要である。

方法1:winget によるインストール

管理者権限コマンドプロンプトで以下を実行する。管理者権限のコマンドプロンプトを起動するには、Windows キーまたはスタートメニューから「cmd」と入力し、表示された「コマンドプロンプト」を右クリックして「管理者として実行」を選択する。

winget install --scope machine --id Python.Python.3.12 -e --silent --disable-interactivity --force --accept-source-agreements --accept-package-agreements --override "/quiet InstallAllUsers=1 PrependPath=1 Include_pip=1 Include_test=0 Include_launcher=1 InstallLauncherAllUsers=1"

--scope machine を指定することで、システム全体(全ユーザー向け)にインストールされる。このオプションの実行には管理者権限が必要である。インストール完了後、コマンドプロンプトを再起動すると PATH が自動的に設定される。

方法2:インストーラーによるインストール

  1. Python 公式サイト(https://www.python.org/downloads/)にアクセスし、「Download Python 3.x.x」ボタンから Windows 用インストーラーをダウンロードする。
  2. ダウンロードしたインストーラーを実行する。
  3. 初期画面の下部に表示される「Add python.exe to PATH」に必ずチェックを入れてから「Customize installation」を選択する。このチェックを入れ忘れると、コマンドプロンプトから python コマンドを実行できない。
  4. 「Install Python 3.xx for all users」にチェックを入れ、「Install」をクリックする。

インストールの確認

コマンドプロンプトで以下を実行する。

python --version

バージョン番号(例:Python 3.12.x)が表示されればインストール成功である。「'python' は、内部コマンドまたは外部コマンドとして認識されていません。」と表示される場合は、インストールが正常に完了していない。

Git のインストール

管理者権限コマンドプロンプトで以下を実行する。管理者権限のコマンドプロンプトを起動するには、Windows キーまたはスタートメニューから「cmd」と入力し、表示された「コマンドプロンプト」を右クリックして「管理者として実行」を選択する。

REM Git をシステム領域にインストール
winget install --scope machine --id Git.Git -e --silent --disable-interactivity --force --accept-source-agreements --accept-package-agreements --override "/VERYSILENT /NORESTART /NOCANCEL /SP- /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /COMPONENTS=""icons,ext\reg\shellhere,assoc,assoc_sh"" /o:PathOption=Cmd /o:CRLFOption=CRLFCommitAsIs /o:BashTerminalOption=MinTTY /o:DefaultBranchOption=main /o:EditorOption=VIM /o:SSHOption=OpenSSH /o:UseCredentialManager=Enabled /o:PerformanceTweaksFSCache=Enabled /o:EnableSymlinks=Disabled /o:EnableFSMonitor=Disabled"

関連する外部ページ

Build Tools for Visual Studio 2022,NVIDIA ドライバ,NVIDIA CUDA ツールキット 11.8,NVIDIA cuDNN 8.9.7 のインストール(Windows 上)

サイト内の関連ページNVIDIA グラフィックスボードを搭載しているパソコンの場合には, NVIDIA ドライバNVIDIA CUDA ツールキットNVIDIA cuDNN のインストールを行う.

関連する外部ページ

PyTorch のインストール(Windows 上)

  1. 以下の手順を管理者権限コマンドプロンプトで実行する (手順:Windowsキーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」)。
  2. PyTorch のページを確認

    PyTorch の公式ページ: https://pytorch.org/index.html

  3. 次のようなコマンドを実行(実行するコマンドは,PyTorch のページの表示されるコマンドを使う).

    次のコマンドを実行することにより, PyTorch 2.3 (NVIDIA CUDA 11.8 用)がインストールされる. 但し,Anaconda3を使いたい場合には別手順になる.

    事前に NVIDIA CUDA のバージョンを確認しておくこと(ここでは,NVIDIA CUDA ツールキット 11.8 が前もってインストール済みであるとする).

    PyTorch で,GPU が動作している場合には,「torch.cuda.is_available()」により,True が表示される.

    python -m pip install -U --ignore-installed pip
    python -m pip uninstall -y torch torchvision torchaudio torchtext xformers
    python -m pip install -U torch torchvision torchaudio numpy --index-url https://download.pytorch.org/whl/cu118
    
    python -c "import torch; print(torch.__version__, torch.cuda.is_available())" 
    
    Anaconda3を使いたい場合には, Anaconda プロンプト (Anaconda Prompt)管理者として実行し, 次のコマンドを実行する. (PyTorch と NVIDIA CUDA との連携がうまくいかない可能性があるため,Anaconda3を使わないことも検討して欲しい).
    conda install -y pytorch torchvision torchaudio pytorch-cuda=11.8 cudnn -c pytorch -c nvidia
    py -c "import torch; print(torch.__version__, torch.cuda.is_available())" 
    

    サイト内の関連ページ

    関連する外部ページ

Shap-E のインストール(Windows 上)

Blender のインストール

Windows でのインストールと日本語化: 別ページ »で説明

Shap-E のインストール(Windows 上)

  1. 以下の手順を管理者権限コマンドプロンプトで実行する (手順:Windowsキーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」)。
  2. インストール
    cd /d c:%HOMEPATH%
    rmdir /s /q shap-e
    git clone --recursive https://github.com/openai/shap-e
    cd shap-e
    python -m pip install -e .
    

    (以下省略)

Shap-E の動作確認(Windows 上)

テキストからの立体生成を行ってみる.

参考ページ: https://github.com/openai/shap-e/blob/main/shap_e/examples/sample_text_to_3d.ipynb

  1. Windows で,コマンドプロンプトを実行
  2. エディタを起動
    cd /d c:%HOMEPATH%\shap-e
    notepad a.py
    
  3. エディタで,次のプログラムを保存

    このプログラムは, 公式ページ https://github.com/openai/shap-e/blob/main/shap_e/examples/sample_text_to_3d.ipynbで公開されているものを変更して使用している.

    import torch
    import matplotlib.pyplot as plt
    from PIL import Image
    
    from shap_e.diffusion.sample import sample_latents
    from shap_e.diffusion.gaussian_diffusion import diffusion_from_config
    from shap_e.models.download import load_model, load_config
    from shap_e.util.notebooks import create_pan_cameras, decode_latent_images, gif_widget
    
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    
    xm = load_model('transmitter', device=device)
    model = load_model('text300M', device=device)
    diffusion = diffusion_from_config(load_config('diffusion'))
    
    batch_size = 4
    guidance_scale = 15.0
    prompt = "a shark"
    
    latents = sample_latents(
        batch_size=batch_size,
        model=model,
        diffusion=diffusion,
        guidance_scale=guidance_scale,
        model_kwargs=dict(texts=[prompt] * batch_size),
        progress=True,
        clip_denoised=True,
        use_fp16=True,
        use_karras=True,
        karras_steps=64,
        sigma_min=1e-3,
        sigma_max=160,
        s_churn=0,
    )
    
    render_mode = 'nerf' # you can change this to 'stf'
    size = 64 # this is the size of the renders; higher values take longer to render.
    
    cameras = create_pan_cameras(size, device)
    for i, latent in enumerate(latents):
        images = decode_latent_images(xm, latent, cameras, rendering_mode=render_mode)
        fig, axes = plt.subplots(nrows=len(images), figsize=(8, 8))
        for ax, image in zip(axes, images):
            ax.imshow(image)
            ax.axis('off')
        plt.tight_layout()
        plt.show()
    
    # Example of saving the latents as meshes.
    from shap_e.util.notebooks import decode_latent_mesh
    
    for i, latent in enumerate(latents):
        t = decode_latent_mesh(xm, latent).tri_mesh()
        with open(f'example_mesh_{i}.ply', 'wb') as f:
            t.write_ply(f)
        with open(f'example_mesh_{i}.obj', 'w') as f:
            t.write_obj(f)
    
  4. Python プログラムの実行

    プログラムを a.pyのようなファイル名で保存したので, 「python a.py」のようなコマンドで行う.

    python a.py
    
    GPU のメモリが足りなくて実行できない場合,GPUがない場合は,a.py の次の2箇所を変更して実行.
    • device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

      device = 'cpu'」に変更

    • use_fp16=True

      use_fp16=False」に変更

  5. 実行後に,画像が複数回表示される.そのたびに,右上の「x」で閉じる.
  6. 実行終了を確認.
  7. example_mesh_0.obj, example_mesh_0.ply, example_mesh_1.obj, example_mesh_1.ply, example_mesh_2.obj, example_mesh_2.ply, example_mesh_3.obj, example_mesh_3.ply ができる.

    このうち example_mesh_0.obj をBlenderで確認してみる.結果は次の通り.

Shap-E を使う Python プログラムの実行(Windows 上)

実行時にプロンプトを指定する.

  1. 前準備として,コマンドプロンプトを管理者として開き, 次のコマンドを実行する

    このコマンドの実行は1回だけで良い

    python -m pip install PyOpenGL PyOpenGL-accelerate pygame pywavefront
    
  2. Windows で,コマンドプロンプトを実行
  3. エディタを起動
    cd /d c:%HOMEPATH%\shap-e
    notepad d.py
    
  4. エディタで,次のプログラムを保存

    このプログラムは, 公式ページ https://github.com/openai/shap-e/blob/main/shap_e/examples/sample_text_to_3d.ipynbで公開されているものを変更して使用している.

    後半には,ply ファイルを表示するプログラムを追加している.

    import torch
    import matplotlib.pyplot as plt
    from PIL import Image
    
    from shap_e.diffusion.sample import sample_latents
    from shap_e.diffusion.gaussian_diffusion import diffusion_from_config
    from shap_e.models.download import load_model, load_config
    from shap_e.util.notebooks import create_pan_cameras, decode_latent_images, gif_widget
    
    print("prompt=")
    prompt = input()
    
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    
    xm = load_model('transmitter', device=device)
    model = load_model('text300M', device=device)
    diffusion = diffusion_from_config(load_config('diffusion'))
    
    batch_size = 4
    guidance_scale = 15.0
    
    latents = sample_latents(
        batch_size=batch_size,
        model=model,
        diffusion=diffusion,
        guidance_scale=guidance_scale,
        model_kwargs=dict(texts=[prompt] * batch_size),
        progress=True,
        clip_denoised=True,
        use_fp16=True,
        use_karras=True,
        karras_steps=64,
        sigma_min=1e-3,
        sigma_max=160,
        s_churn=0,
    )
    
    render_mode = 'nerf' # you can change this to 'stf'
    size = 64 # this is the size of the renders; higher values take longer to render.
    
    cameras = create_pan_cameras(size, device)
    for i, latent in enumerate(latents):
        images = decode_latent_images(xm, latent, cameras, rendering_mode=render_mode)
    
    # Example of saving the latents as meshes.
    from shap_e.util.notebooks import decode_latent_mesh
    
    for i, latent in enumerate(latents):
        t = decode_latent_mesh(xm, latent).tri_mesh()
        with open(f'example_mesh_{i}.ply', 'wb') as f:
            t.write_ply(f)
        with open(f'example_mesh_{i}.obj', 'w') as f:
            t.write_obj(f)
    
    import pygame
    from pygame.locals import *
    from OpenGL.GL import *
    from OpenGL.GLUT import *
    from OpenGL.GLU import *
    from plyfile import PlyData, PlyElement
    
    # PLYファイルを読み込む
    import tkinter as tk
    from tkinter import filedialog
    
    root = tk.Tk()
    root.withdraw()
    fpath = filedialog.askopenfilename()
    
    plydata = PlyData.read(fpath)
    vertex_data = plydata['vertex'].data
    face_data = plydata['face'].data
    
    # 頂点と面をリストとして取得
    vertices = [list(elem) for elem in vertex_data]
    faces = [face[0] for face in face_data]
    
    # PygameとOpenGLを初期化
    pygame.init()
    display = (800, 600)
    pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
    gluPerspective(45, (display[0] / display[1]), 0.1, 50.0)
    glTranslatef(0.0, 0.0, -5)
    
    # マウス操作のための変数
    rotation_enabled = False
    rotation_start = (0, 0)
    zoom = 0.0
    
    # メインループ
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:  # 左クリック
                    rotation_enabled = True
                    rotation_start = pygame.mouse.get_pos()
                elif event.button == 4:  # ホイール回転(上方向)
                    zoom = 1
                elif event.button == 5:  # ホイール回転(下方向)
                    zoom = -1
            elif event.type == pygame.MOUSEBUTTONUP:
                if event.button == 1:  # 左クリック解除
                    rotation_enabled = False
            elif event.type == pygame.MOUSEMOTION:
                if rotation_enabled:
                    dx = event.pos[0] - rotation_start[0]
                    dy = event.pos[1] - rotation_start[1]
                    glRotatef(dx, 0, 1, 0)  # y軸周りに回転
                    glRotatef(dy, 1, 0, 0)  # x軸周りに回転
                    rotation_start = event.pos
    
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    
        # 視点の移動範囲を制限
        max_zoom = 5.0
        min_zoom = -5.0
        zoom = max(min_zoom, min(max_zoom, zoom))
        glTranslatef(0.0, 0.0, -zoom)
        zoom = 0
    
        glBegin(GL_TRIANGLES)
        for face in faces:
            for vertex_i in face:
                glVertex3fv(vertices[vertex_i][:3])
        glEnd()
    
        pygame.display.flip()
        pygame.time.wait(10)
    
  5. Python プログラムの実行

    プログラムを d.pyのようなファイル名で保存したので, 「python d.py」のようなコマンドで行う.

    python d.py
    
    GPU のメモリが足りなくて実行できない場合,GPUがない場合は,a.py の次の2箇所を変更して実行.
    • device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

      device = 'cpu'」に変更

    • use_fp16=True

      use_fp16=False」に変更

    その後,プロンプトを入力する.

    example_mesh_0.obj, example_mesh_0.ply, example_mesh_1.obj, example_mesh_1.ply, example_mesh_2.obj, example_mesh_2.ply, example_mesh_3.obj, example_mesh_3.ply ができる.

  6. ファイルダイアログが開く.確認したい ply ファイルを1つ選ぶ
  7. 選んだファイルが表示される.これは確認のため.

    マウスの左クリックとマウス移動により回転できる.マウスホイールにより,前後移動する.

  8. example_mesh_0.obj をBlenderで確認してみる.結果は次の通り.

    プロンプトを tree に変えて実行してみた結果