Shap-e のインストールと立体生成を行う.
Shap-e は、テクスチャ付きメッシュ (textured mesh)や neural radient fields としてレンダリングできる出力を生成 する能力を特徴とする。 Point-E との比較では、高速、高品質の生成が可能であるとされている。
【目次】
【文献】
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
【関連する外部ページ】
Gitは,バージョン管理システム.ソースコードの管理や複数人での共同に役立つ.
【サイト内の関連ページ】
Windows での Git のインストール: 別ページ »で説明している.
【関連する外部ページ】
Git の公式ページ: https://git-scm.com/
【サイト内の関連ページ】
【関連する外部ページ】
Python の公式ページ: https://www.python.org/
【サイト内の関連ページ】
NVIDIA グラフィックスボードを搭載しているパソコンの場合には, NVIDIA ドライバ, NVIDIA CUDA ツールキット, NVIDIA cuDNN のインストールを行う.
【関連する外部ページ】
コマンドプロンプトを管理者として実行: 別ページ »で説明
PyTorch のページ: https://pytorch.org/index.html
次のコマンドは, PyTorch 2.0 (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 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())"
【サイト内の関連ページ】
【関連する外部ページ】
Windows でのインストールと日本語化: 別ページ »で説明している.
コマンドプロンプトを管理者として実行: 別ページ »で説明
cd %HOMEPATH% rmdir /s /q shap-e git clone --recursive https://github.com/openai/shap-e cd shap-e python -m pip install -e .
テキストからの立体生成を行ってみる.
参考ページ: https://github.com/openai/shap-e/blob/main/shap_e/examples/sample_text_to_3d.ipynb
cd %HOMEPATH%\shap-e notepad a.py
このプログラムは, 公式ページ 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)
Python プログラムの実行
Python 開発環境(Jupyter Qt Console, Jupyter ノートブック (Jupyter Notebook), Jupyter Lab, Nteract, Spyder, PyCharm, PyScripterなど)も便利である.
Python のまとめ: 別ページ »にまとめ
プログラムを a.pyのようなファイル名で保存したので, 「python a.py」のようなコマンドで行う.
python a.py
GPU のメモリが足りなくて実行できない場合,GPUがない場合は,a.py の次の2箇所を変更して実行.
「device = 'cpu'」に変更
「use_fp16=False」に変更
このうち example_mesh_0.obj をBlenderで確認してみる.結果は次の通り.
実行時にプロンプトを指定する.
このコマンドの実行は1回だけで良い
python -m pip install PyOpenGL PyOpenGL-accelerate pygame pywavefront
cd %HOMEPATH%\shap-e notepad d.py
このプログラムは, 公式ページ 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)
Python プログラムの実行
Python 開発環境(Jupyter Qt Console, Jupyter ノートブック (Jupyter Notebook), Jupyter Lab, Nteract, Spyder, PyCharm, PyScripterなど)も便利である.
Python のまとめ: 別ページ »にまとめ
プログラムを d.pyのようなファイル名で保存したので, 「python d.py」のようなコマンドで行う.
python d.py
GPU のメモリが足りなくて実行できない場合,GPUがない場合は,a.py の次の2箇所を変更して実行.
「device = 'cpu'」に変更
「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 ができる.
マウスの左クリックとマウス移動により回転できる.マウスホイールにより,前後移動する.
プロンプトを tree に変えて実行してみた結果