見出し画像

Generative-AI in Grasshopper (1) -導入

Grasshopper における 生成AIの導入方法と用途を模索してみる



1. 開発者用の生成AIプラットフォーム

GHに生成AIを導入するにあたって利用可能な開発者用サービスはいくつかある。ここで提供されている様々なモデルを、pythonやc#で取り込み組み合わせて利用していく。API経由で利用するものが多く、トークン数に従って少しずつ課金していくことになる。

以下の4つのプラットフォームを紹介する。

1. OpenAI API
2. Stability AI API
3. Hugging Face
4. Replicate

1-1. OpenAI API

ChatGPT や DALL-E を提供する OpenAI の公式API。
GPT, Embedding, Image, Fine-tuning などを利用できる。

テキストモデルが多いが、本格的にLLMを扱うとなると、ファインチューニングなどがより自由に出来る LLaMA や日本語モデルなど、GPT以外も触る必要が出てくる。


1-2. Stability AI API

Stable Diffusion を提供する Stability AI の公式API。
画像系の機能が豊富。
Stable Diffusion で可能な機能の多くを利用可能。


1-3. Hugging Face

モデルやデータセットを共有し、利用するためのオープンソースプラットフォーム。Transformersライブラリなど様々なツールを提供。


1-4. Replicate

Hugging Face のようにユーザがモデルを公開し共有することができるプラットフォーム。画像系も豊富。



2. GrasshopperでのAIの導入方法

GHにデフォルトで用意されている Python コンポーネントは、IronPython という種類のもので、バージョンも古く、対応していないライブラリも多い。
そこで、別の方法で Python を利用する必要が出てくる。いくつかの方法を紹介する。

1. Hopsを用いたCPython
2. C#でのコンポーネント作成
3. Ambrosinus-Toolkit
4. その他

2-1. Hopsを用いたCPython

RhinoCompute とのHTTP通信を通して、様々な処理を可能にすることが出来るプラグイン。使い方の1つにCPythonでのコンポーネントの作成があり、これを用いて各APIを導入していく。

Hiron さんの以下の記事がとても分かりやすいので、導入する際は参考にしていただきたい。


2-2. C#でのコンポーネント作成

Visual Studio 上でC#を用いてコンポーネントを作成することが出来る。.ghaファイルと.dllファイルを出力することが出来るため、コンポーネントを配布する場合はHopsよりも適しているはず。
ただ、AIはPythonが主流のため、C#では対応していないものも多い。少なくとも OpenAI は C#用のSDKが配布されているため利用可能である。

Mtさんの以下の記事がとても分かりやすいので、導入する際は参考にしていただきたい。


2-3. Ambrosinus-Toolkit

lucianoambrosini さんが公開している生成AIのGHプラグインがある。Stable Diffusion や GPT を応用したもので、様々な目的で使えそう。Hopsなどを用いて自分で作成する前に、一度触ってみると雰囲気が掴めるのでおすすめ。ただ、自分でカスタマイズは出来ないので、ある程度参考にしつつ用途に応じて自作したい。


2-4. その他

他にもGHやRhinoを制御する手法は幾つかある。
CpythonをGH上で扱うための GH Python Remote や、RhinoやGHを他のアプリケーションと連携させる Rhino Inside など。



3. 実装例

以上を用いて簡単な実装をしてみる。

3-1. Hops を用いたAPIの導入

まずはHopsを用いてAPIを導入してみる。

Pythonの仮想環境に必要なライブラリをインストールしたら、VSCode を用いてプログラムを書いていく。Replicate から Stable Diffusion(SDXL) を用いてGH上で画像生成するためのシンプルなプログラムを紹介する。

import os
import replicate
from flask import Flask
import ghhops_server as hs
import rhino3dm

os.environ["REPLICATE_API_TOKEN"] = "YOUR_REPLICATE_API_KEY"

app = Flask(__name__)
hops = hs.Hops(app)

@hops.component(
    "/rep_sdxl",
    name="rep_sdxl",
    description="sdxl img from replicate",
    inputs=[
        hs.HopsString("p","p","prompt")
    ],
    outputs=[
        hs.HopsString("o","o","output url"),
    ],
)
def rep_sdxl(prompt):
    url = replicate.run(
    "stability-ai/sdxl:d830ba5dabf8090ec0db6c10fc862c6eb1c929e1a194a5411852d25fd954ac82",
    input={"prompt": prompt}
    )
    return url

if __name__ == "__main__":
    app.run(debug=True)
  1. Hops用ライブラリ(Flask, ghhops_server, rhino3dm) とReplicate を import する

  2. APIを利用するために、Replicate からapi key を取得する

  3. @hops.component の中身がコンポーネントの情報やインプット・アウトプット項目になるので、それぞれ設定する。
    input: プロンプト、output: 生成画像のurl

  4. def で関数を定義する。ここで Replicate を通してSDXLを利用する。モデルによって replicate.run の中身が変わってくるので、各ドキュメントに従って書く

  5. app.run で起動

起動するとターミナルに以下の文章が表示される。ここに表示されるhttp://~~ の後ろに/func_name を加え、GH上のHopsコンポーネントのPathに設定すると、準備は完了。 

作成したコンポーネントを実行する。画像生成用のプロンプトを繋ぐと、10秒ほど(SDXL, 1024x1024の場合)した後にurlが表示される。
今回は、ShapeDiverというプラグインを用いて、url先の画像をbitmapとして取得した。

"studio photo of a rainbow grasshopper"

3-2. C#を用いたコンポーネントの作成

C#を用いたコンポーネントの作成も紹介してみる。

Visual Studio で、GrasshopperBetalgo.OpenAI.GPT3 のパッケージを使用して書いていく。(現在はBetalgo.OpenAI.GPT4も使用可能)

  1. コンポーネントの情報の設定、入力、出力の設定

  2. OpenAI の api key を取得

  3. メソッドを記述。ここでは GPT3 の ChatCompletion を利用。事前にsystemの役割を与え、userとの円滑なチャットを実現する。
    input: プロンプト、output: 返答

  4. await, async を使い処理を実行する

  5. デバッグをすると、ghaファイルが出力される

using Grasshopper;
using Grasshopper.Kernel;
using Rhino.Geometry;
using System;
using System.Collections.Generic;
using OpenAI.GPT3;
using OpenAI.GPT3.Managers;
using OpenAI.GPT3.ObjectModels.RequestModels;
using OpenAI.GPT3.ObjectModels;
using System.Linq;
using System.Threading.Tasks;

namespace gpttest
{
    public class gpttest1 : GH_Component
    {
        public gpttest1()
          : base("gpttest1", "gpttest1",
            "test1",
            "Maths", "Util")
        {
        }

        // コンポーネントの入力の設定
        protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
        {
            //promptの入力
            pManager.AddTextParameter("prompt", "prompt", "message to gpt", GH_ParamAccess.item);
        }

        // コンポーネントの出力の設定
        protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
        {
            //返信の出力
            pManager.AddTextParameter("output", "output", "output from gpt", GH_ParamAccess.item);
        }

        // メソッド
        protected override async void SolveInstance(IGH_DataAccess DA)
        {
            //apikeyの設定
            var apikey = "YOUR_OPENAI_API_KEY";
            //apikeyを登録、OpenAIService型として
            var openAiService = new OpenAIService(new OpenAiOptions(){ApiKey = apikey});

            //systemを設定
            var fromsystem = "you are a grasshopper assistant";

            //messageを設定
            var fromuser = "";
            DA.GetData(0, ref fromuser);

            //await
            //gptとやりとりするメインの処理
            var completionResult = await GetCompletionAsync(openAiService, fromsystem, fromuser);
            
            //outputに格納する
            DA.SetData(0, completionResult);
        }


        //async
        //gptとのやりとりの処理
        private async Task<string> GetCompletionAsync(OpenAIService openAiService, string fromsystem,string fromuser )
        {

            //メイン処理
            var completionResult = await openAiService.ChatCompletion.CreateCompletion(new ChatCompletionCreateRequest
            {
                Messages = new List<ChatMessage>
                {
                    ChatMessage.FromSystem(fromsystem),
                    ChatMessage.FromUser(fromuser)
                },
                Model = Models.ChatGpt3_5Turbo
            });

            //成功したらメッセージのみを返す
            if (completionResult.Successful)
            {
                return completionResult.Choices.First().Message.Content;
            }

            //失敗したらfailedメッセージを返す
            return "Completion Failed!!;

        }


        /// Provides an Icon for every component that will be visible in the User Interface.
        protected override System.Drawing.Bitmap Icon => null;

        /// Each component must have a unique Guid to identify it. 
        public override Guid ComponentGuid => new Guid("1c4895ef-a2e2-47ef-8c06-87035e550b10");
    }
}

プログラムが完成しデバッグを実行すると、.ghaファイルや.dllファイルが出力される。これらをGHのcomponentフォルダに配置することで利用可能となる。プロンプトに返答するシンプルなコンポーネントを実装できた。



4. 展望

ここまで、GHに生成AIを導入する方法をいくつか模索してみた。
個人的には Hops がとても使いやすかった。また、Replicate はUIも含め初心者にも扱いやすく、SDXLやLoRAも既に提供されているため、まずは触ってみたいプラットフォームだと感じた。

建築学生としては、やはりRhino+GH上で生成AIを活用できると色々可能性が広がると思う。一方で、これがまだどのように面白く使えるかが見えておらず、これから模索していく必要があると感じる。3D生成はまだ先の話なので、現時点でどのように実用的にAIを活用するか、または思索的にAIを実験するか。GHに導入することでどのようなメリットがあるのか。

この記事以降、数回に分けて考えていきたいと思う。

最後に一つだけ事例を紹介する。
VUILDが提供する家具制作サービスEMARFでは、チャットAIとの会話を介してデザインをサポートするツールが試験的に公開された。こちらももともとRhino+GHにChatGPTを導入することから始まったプロジェクトである。
AIとシームレスに共同作業できることが、Rhino+GHへの導入の効果の1つだと感じる。


この記事が気に入ったらサポートをしてみませんか?