この記事は、OctoAIの共同創設者兼DevRel責任者であるThierry Moreau氏によって寄稿されました。
ジェネレーティブAIモデルは、GPT3のような画期的なモデルで、過去1年間で計り知れない可能性を示してきました。5、 DALL-Eなど。 特に、オープンソースの基礎モデルは、クローズドソースの代替モデルと比較して、カスタマイズ可能で費用対効果が高く、透明性が高い開発者やエンタープライズユーザーの間で人気を博しています。
この記事では、オープンソースの基本モデルを、テキストだけで画像を操作して驚くほど良い結果を得ることができる合理化された画像変換パイプラインに構成する方法について説明します。
このアプローチにより、企業ロゴの楽しいバージョンを作成したり、子供の絵に命を吹き込んだり、製品写真を充実させたり、リビングルームを改造したりすることもできます(図 1)。
かなりクールでしょ? 舞台裏では多くのことを行う必要があり、これらの結果を自分で再現する方法を順を追って説明します。 マルチモーダルなGenAIパイプラインを OctoShop と呼ぶのは、人気の画像編集ソフトウェアにちなんでです。
いくつかの基本的なGenAIモデルをつなぎ合わせたいと思いませんか? これを可能にするテクノロジーについて詳しく見ていきましょう。
アーキテクチャの概要
これから構築するマルチモーダルパイプラインを構成するオープンソースの基盤となるGenAIモデルについて、さらに詳しく見ていきましょう。
今後は、「マルチモーダルなGenAIモデルパイプライン」ではなく、「モデルカクテル」という用語を使用します。テキストと画像は、GenAIモデルがデータを消費して生成するデータモダリティの例ですが、この概念はオーディオとビデオにも拡張できます(図 2)。
カクテル(または必要に応じてモクテル)を作るのに例えると、材料を混ぜる必要がありますが、材料を組み立てると、個々の部分の合計よりも大きくなります。
例えば、私のお気に入りのカクテルであるネグローニを例に挙げてみましょう。 準備は簡単です。ジン、ベルモット、カンパリを等量必要です。 同様に、OctoShopモデルカクテルは、画像生成(SDXL)、テキスト生成(Mistral-7B)、カスタム画像からテキスト生成(CLIPインテロゲーター)モデルの3つの材料を使用します。
プロセスは次のとおりです。
- CLIP Interrogatorは画像を取り込み、テキストによる説明を生成します(例:「背中に容器を乗せたクジラ」)。
- LLMモデルであるMistral-7Bは、ユーザープロンプト(例:「画像を空間に設定」)に基づいて、より豊富なテキストの説明を生成します。 その結果、LLMは説明文をユーザーのプロンプトに合ったより豊かなものに変換します(たとえば、「広大な宇宙で、雄大なクジラは背中にコンテナを背負っています」)。
- 最後に、SDXLモデルを使用して、LLMモデルによって変換されたテキストの説明に基づいて、AIが生成した最終的な画像を生成します。 また、 SDXL スタイルと ControlNet を利用して、スタイルとフレーミング/遠近法の観点から画像の出力をより適切に制御します。
前提 条件
カクテルを作るための前提条件を見ていきましょう。
必要なものは次のとおりです。
- OctoAIの 画像生成(SDXL)、テキスト生成(Mistral-7B)、およびコンピューティングソリューション(CLIP Interrogator)を使用するには、OctoAIアカウントにサインアップしてください。 すでに別のコンピューティング サービスを使用している場合は、代わりにそちらを自由に使用してください。
- Jupyter Notebook を実行して、GenAI モデルの適切な組み合わせを作成します。 ここは実験とミキシングのための場所なので、これがあなたのカクテルシェーカーになります。 ノートブックの実行と配布を容易にするために、 Google Colab を使用します。
- 最後に、モデルカクテルを Streamlitアプリとしてデプロイします。 アプリを構築し、フロントエンドを装飾することは、五感を高めるためのカクテル(グラス、氷、付け合わせの選択など)のプレゼンテーションと考えてください。
OctoAIを使い始める
まだ行っていない場合は、 octoai.cloud にアクセスしてアカウントを作成してください。 初回サインアップ時に10 ドルのクレジットを受け取ることができますが、ここで独自のワークフローを試すには十分です。
「 はじめに」ページの指示 に従って、OctoAI APIトークンを取得します — これにより、OctoAI APIを使用するたびに認証を受けることができます。
ノートブックのチュートリアル
Colab では Jupyter Notebook を作成し、モデルカクテルを構成するさまざまなモデルの使用方法を学習できるようにしました。従う手順は次のとおりです。
1. ノートブックを起動する
まず、次の Colab ノートブックを起動します。
ランタイムタイプを変更したり、GPUやTPUアクセラレータに頼ったりする必要はなく、AIの重労働はすべてOctoAIエンドポイントで行われるため、ここで必要なのはCPUだけです。
2. OctoAI SDKのセットアップ
OctoAI SDKのインストールから始めましょう。 SDK を使用して、SDXL や Mistral-7B など、使用しているさまざまなオープン ソースの基本モデルを呼び出します。 以下から pip
インストールできます。
# Install the OctoAI SDK
!pip install octoai-sdk
場合によっては、ランタイムで以前にインポートされたpipパッケージに関するメッセージが表示され、エラーが発生することがあります。 その場合は、下部にある [セッションの再起動] ボタンを選択すると、パッケージのバージョン管理の問題が解決されます。 この後、OctoAI SDKをpip-installするセルを問題なく再実行できるはずです。
3. SDXLで画像を生成する
まず、画像生成ソリューション API を使用して SDXL で画像を生成する方法を学習します。 以下のコードで各パラメーターが何を行うかについては、OctoAI の ImageGenerator クライアントを確認してください。
特に、 ImageGenerator API は、画像を生成するためにいくつかの引数を取ります。
- エンジン:SDXL、SD1などの安定した拡散モデルのバージョンから選択できます。5、およびSSD。
- プロンプト: 生成するイメージを記述します。
- ネガティブプロンプト:最終画像で避けたい特性を説明します。
- 幅、高さ:出力画像の解像度。
- 画像数: 一度に生成する画像の数。
- サンプラー: イメージのノイズ除去に使用するサンプリング方法を指定します。 このプロセスに慣れていない場合は、 この記事 で包括的な概要を説明します。
- ステップ数:ノイズ除去ステップの数 — ステップ数が多いほど品質は高くなりますが、一般的に 30 を超えると収穫逓減につながります。
- Cfgスケール:画像の説明にどれだけ忠実に従うか — 通常は 7〜12程度にとどまります。
- 絞り込み条件を使用: 画像の出力品質を向上させる SDXL 絞り込み条件モデルを適用するかどうか。
- シード: 画像生成の再現性を制御できるパラメータです(安定した入力パラメータが与えられた場合、常に同じ画像を取得するには、正の値に設定します)。
ステップ数、画像数、使用するサンプラーなどの画像生成パラメーターを微調整すると、画像の生成に必要な GPU コンピューティングの量に影響することに注意してください。 GPU サイクルを増やすと、イメージ生成の 価格に影響します 。
以下は、単純なパラメーターを使用した例です。
# To use OctoAI, we'll need to set up OctoAI to use it
from octoai.clients.image_gen import Engine, ImageGenerator
# Now let's use the OctoAI Image Generation API to generate
# an image of a whale with a container on its back to recreate
# the moby logo
image_gen = ImageGenerator(token=OCTOAI_API_TOKEN)
image_gen_response = image_gen.generate(
engine=Engine.SDXL,
prompt="a whale with a container on its back",
negative_prompt="blurry photo, distortion, low-res, poor quality",
width=1024,
height=1024,
num_images=1,
sampler="DPM_PLUS_PLUS_2M_KARRAS",
steps=20,
cfg_scale=7.5,
use_refiner=True,
seed=1
)
images = image_gen_response.images
# Display generated image from OctoAI
for i, image in enumerate(images):
pil_image = image.to_pil()
display(pil_image)
パラメータを自由に試して、結果の画像に何が起こるかを確認してください。 ここでは、Docker のロゴを説明するための簡単なプロンプトとして、「背中にコンテナを載せたクジラ」と表示しました。 また、探している画像のスタイルを生成するのに役立つ標準の否定的なプロンプトも追加しました。 図 3 に出力を示します。
4. ControlNetで画像出力を制御
SDXL でできることの 1 つは、AI が生成した画像の構成を制御することです。 たとえば、特定の人物のポーズを指定したり、特定の写真の構図や遠近法を制御したりできます。
Moby(Dockerのマスコット)を使った実験では、クジラとコンテナの同じ形、被写体の向き、サイズなど、元のロゴに簡単に重ね合わせることができるAI生成画像を取得したいと考えています。
ここで、ControlNetが役に立ちます: ControlNet は、制御画像を入力として供給することで、画像の生成を制限できます。 この例では、Moby ロゴの画像をコントロール入力としてフィードします。
ImageGenerator API で使用される以下のパラメーターを調整することで、SDXL 画像の生成を Moby のコントロール画像で制約しています。その制御画像は、深度推定モデルを使用して深度マップに変換され、ControlNetに供給されるため、SDXL画像の生成が制限されます。
# Set the engine to controlnet SDXL
engine="controlnet-sdxl",
# Select depth controlnet which uses a depth map to apply
# constraints to SDXL
controlnet="depth_sdxl",
# Set the conditioning scale anywhere between 0 and 1, try different
# values to see what they do!
controlnet_conditioning_scale=0.3,
# Pass in the base64 encoded string of the moby logo image
controlnet_image=image_to_base64(moby_image),
これで、結果は Moby のアウトラインとより密接に一致したように見えます (図 4)。 これがControlNetの力です。 パラメータを変化 controlnet_conditioning_scale
させることで強度を調整できます。 このようにして、出力画像をMobyのコントロール画像と多かれ少なかれ忠実に一致させることができます。
5. SDXLスタイルのプリセットで画像出力を制御
SDXLスタイルでカスタマイズのレイヤーを追加しましょう。 ここでは、3D Model スタイルプリセットを使用します(図 5)。舞台裏では、これらの スタイル プリセットによって、 SDXL モデルが取り込む肯定的および否定的なプロンプトにキーワードが追加されています。
図 6 は、 ImageGenerator API でこの 1 つのパラメーターを設定すると、AI が生成した Moby の画像がどのように変換されるかを示しています。 さあ、もっと多くのスタイルを試してみてください。インスピレーションを得るための ギャラリー を作成しました。
6. Mistral-7B LLMで画像を操作する
ここまでは、テキストから画像への生成を行うSDXLに依存してきました。 ControlNetをミックスに追加して、コンポジションの制約としてコントロール画像を適用しました。
次に、LLMをミックスに重ねて、元の画像プロンプトを「変換プロンプト」に基づいてクリエイティブでリッチなテキストの説明に変換します。
基本的には、LLMを使用してプロンプトを自動的に改善します。 これにより、OctoShopモデルのカクテルパイプラインでテキストを使用して画像操作を実行できます。
- 白鯨のロゴを撮る:宇宙で超リアルな写真に設定します。
- 子供が描いた絵を、ファンタジーの世界で生き生きとさせましょう。
- カクテルの写真を撮る: イタリアのビーチにカクテルをセットします。
- リビングルームの写真を撮る: デザイナーズハウスの演出されたリビングルームに変身させます。
このテキストからテキストへの変換を実現するには、次のように LLM ユーザー プロンプトを使用します。 これにより、白鯨の元のテキストの記述は、広大な空間という新しい設定に設定されます。
'''
Human: set the image description into space: “a whale with a container on its back”
AI: '''
LLMシステムプロンプトは、LLM応答が簡潔で、最大で1文の長さになるように設定されています。 長くすることもできますが、SDXL によって使用されるプロンプトには 77トークン コンテキストの制限があることに注意してください。
テキスト生成Python SDKと、テキスト生成に使用されるチャット補完APIの詳細については、以下を参照してください。
- モデル: Mixtral、Mistral、Llama2、Code Llama などの基本的なオープンソース モデルから選択できます (より多くのオープンソース モデルがリリースされるにつれて、選択肢が増えます)。
- メッセージ: 完了のコンテキストとして使用するメッセージ (システムおよびユーザー) のリストが含まれます。
- Max tokens: 出力トークンにハード制限を適用します (これにより、文の途中で補完応答がカットされる可能性があります)。
- 温度:回答の創造性をコントロールできます:温度が高いほど、可能性の低いトークンを選択できます。
モデル、インプット、アウトプットトークンの選択は、 OctoAIの価格に影響します。 この例では、 Mistral-7B LLMを使用していますが、これは優れたオープンソースのLLMモデルであり、パラメータサイズが小さいため、非常にパンチが効いています。
Mistral-7B LLMを呼び出すために使用されるコードを見てみましょう。
# Let's go ahead and start with the original prompt that we used in our
# image generation examples.
image_desc = "a whale with a container on its back"
# Let's then prepare our LLM prompt to manipulate our image
llm_prompt = '''
Human: set the image description into space: {}
AI: '''.format(image_desc)
# Now let's use an LLM to transform this craft clay rendition
# of Moby into a fun scify universe
from octoai.client import Client
client = Client(OCTOAI_API_TOKEN)
completion = client.chat.completions.create(
messages=[
{
"role": "system",
"content": "You are a helpful assistant. Keep your responses short and limited to one sentence."
},
{
"role": "user",
"content": llm_prompt
}
],
model="mistral-7b-instruct-fp16",
max_tokens=128,
temperature=0.01
)
# Print the message we get back from the LLM
llm_image_desc = completion.choices[0].message.content
print(llm_image_desc)
出力は次のとおりです。
私たちのLLMは、宇宙を旅するモビーの短いながらも想像力に富んだ説明を作成しました。 図 7 は、このLLMで生成されたテキスト記述をSDXLにフィードしたときの結果を示しています。
この画像は素晴らしいです。 宇宙の広大さを感じることができます。 LLMの力とSDXLの柔軟性により、画像の作成と操作を新たな高みに引き上げることができます。 そして素晴らしいのは、これらの画像を操作するために必要なのはテキストだけだということです。残りの作業は GenAI モデルが行います。
7. AIベースの画像ラベリングでワークフローを自動化
これまでの画像変換パイプラインでは、OctoShopモデルカクテルへの入力画像に手動でラベルを付ける必要がありました。 白鯨の画像を渡すだけでなく、その画像の説明をテキストで提供する必要がありました。
ありがたいことに、GenAIモデルを使用してテキストのラベル付けタスクを実行できます。このタスクは、SDXL が行うことの逆、つまり画像を取り込み、出力としてテキストを生成するものと考えてください。
開始するには、エンドポイントのどこかで実行される CLIP Interrogator モデルが必要です。 OctoAIでCLIP Interrogatorモデルのエンドポイントを取得するには、2つの方法があります。始めたばかりの場合はシンプルなアプローチをお勧めし、モデル エンドポイントをカスタマイズする気になった場合は、より高度なアプローチを使用できます。 たとえば、 最新バージョンの CLIP Interrogator を試してみたい場合があります。
これで、数行のコードで CLIP Interrogator モデルを呼び出すことができます。 ここでは、高速インテロゲーターモードを使用して、ラベルをできるだけ早く生成します。
# Let's go ahead and invoke the CLIP interrogator model
# Note that under a cold start scenario, you may need to wait a minute or two
# to get the result of this inference... Be patient!
output = client.infer(
endpoint_url=CLIP_ENDPOINT_URL+'/predict',
inputs={
"image": image_to_base64(moby_image),
"mode": "fast"
}
)
# All labels
clip_labels = output["completion"]["labels"]
print(clip_labels)
# Let's get just the top label
top_label = clip_labels.split(',')[0]
print(top_label)
トップラベルには、Mobyのロゴが次のように説明されています。
それはかなり的を射ています。 すべての材料を個別にテストしたので、モデルカクテルを組み立てて、興味深いユースケースでテストしましょう。
8. モデルカクテルの組み立て
3つのモデル(CLIPインテロゲーター、Mistral-7B、SDXL)をテストしたので、次の入力を受け取る1つの便利な関数にパッケージ化できます。
- 出力画像を制御するために使用され、CLIPインテロゲーターモデルによって自動的にラベル付けされる入力画像。
- 入力画像に適用する変換を記述する変換文字列 (例: "set the image description in space")。
- 画像に適用する変換とは無関係に、画像の芸術的出力をより適切に制御できるスタイル文字列(たとえば、絵画的なスタイルと映画的なスタイル)。
以下の関数は、上記で紹介したすべてのコードの焼き直しを 1 つの関数に詰め込んだものです。
def genai_transform(image: Image, transformation: str, style: str) -> Image:
# Step 1: CLIP captioning
output = client.infer(
endpoint_url=CLIP_ENDPOINT_URL+'/predict',
inputs={
"image": image_to_base64(image),
"mode": "fast"
}
)
clip_labels = output["completion"]["labels"]
top_label = clip_labels.split(',')[0]
# Step 2: LLM transformation
llm_prompt = '''
Human: {}: {}
AI: '''.format(transformation, top_label)
completion = client.chat.completions.create(
messages=[
{
"role": "system",
"content": "You are a helpful assistant. Keep your responses short and limited to one sentence."
},
{
"role": "user",
"content": llm_prompt
}
],
model="mistral-7b-instruct-fp16",
max_tokens=128,
presence_penalty=0,
temperature=0.1,
top_p=0.9,
)
llm_image_desc = completion.choices[0].message.content
# Step 3: SDXL+controlnet transformation
image_gen_response = image_gen.generate(
engine="controlnet-sdxl",
controlnet="depth_sdxl",
controlnet_conditioning_scale=0.4,
controlnet_image=image_to_base64(image),
prompt=llm_image_desc,
negative_prompt="blurry photo, distortion, low-res, poor quality",
width=1024,
height=1024,
num_images=1,
sampler="DPM_PLUS_PLUS_2M_KARRAS",
steps=20,
cfg_scale=7.5,
use_refiner=True,
seed=1,
style_preset=style
)
images = image_gen_response.images
# Display generated image from OctoAI
pil_image = images[0].to_pil()
return top_label, llm_image_desc, pil_image
これで、いくつかの画像、プロンプト、スタイルでこれを試すことができます。
モデル カクテルを Web アプリにパッケージ化する
独自のGenAIカクテルを混ぜたら、それをグラスに注ぎ、比喩的に飾ります。 独自のOctoShop GenAIモデルカクテルをデプロイし、その結果を友人や同僚と共有できる シンプルなStreamlitフロントエンド を構築しました(図 8)。 GitHubで確認できます。
READMEの指示に従って、アプリをローカルにデプロイするか、StreamlitのWebホスティングサービスでホストします。
どんな素晴らしい画像処理アプリが生まれるのか、楽しみにしています。 OctoAIの Discord サーバーで#built_with_octoチャンネルであなたの作品を共有してください!
OctoShopをDiscordボットの背後に配置したり、Dockerを使用して独自のモデルコンテナを構築したりする方法を知りたい場合は、 DockerCon で2023 OctoAIが主催する AI / MLワークショップ からそれを行う方法の説明もあります。
OctoAIについて
OctoAIは、GenAIを大規模、効率的、かつ堅牢に実行するためのインフラストラクチャを提供します。 Mixtral、Stable Diffusion XLなどのモデルを提供するためにOctoAIが提供するモデルエンドポイントはすべて、Dockerに依存してモデルをコンテナ化し、大規模なサービスを簡単に提供できるようにします。
octoai.cloud に行くと、開発者が GenAI 搭載のアプリとパイプラインを本番環境に導入するために構築できる 3 つの補完的なソリューションがあります。
- 画像生成ソリューション は、Stable Diffusion XLやSSDなどのオープンソースの基本モデルを中心に構築されたテキストから画像、画像から画像へのタスクを実行するためのエンドポイントとAPIを公開します。
- テキスト生成ソリューション は、Mixtral/Mistral、Llama2、CodeLlama などのオープン ソースの基本モデルに基づいて構築されたテキスト生成タスクを実行するためのエンドポイントと API を公開します。
- コンピュートソリューション により、Docker化されたモデルコンテナを有能なOctoAIクラウドエンドポイントにデプロイして管理し、要求の厳しいGenAIニーズに対応できます。 このコンピューティング サービスは、画像生成ソリューションとテキスト生成ソリューションのいずれでも現在すぐに利用できない AI タスクの無限のプログラミング可能性とカスタマイズ可能性を公開することで、画像生成およびテキスト生成ソリューションを補完します。
免責事項
OctoShopは、CLIP InterrogatorとSDXL、Mistral-7Bを基盤として構築されているため、これらのベースモデルに内在する潜在的な危険性を引き継ぐ可能性があります。意図しない、不適切、不快な、または誤った出力を生成する可能性があります。 したがって、このモデルを実際のアプリケーションに展開する前に、注意を払い、包括的な評価を行うことを強くお勧めします。
このGenAIモデルのワークフローは、人物の肖像が保持されないため、人物には機能しません。パイプラインは、シーン、オブジェクト、または動物で最適に機能します。 この問題に対処するためのソリューションとして、Dockerでコンテナ化してOctoAI Computeソリューションにデプロイできるフェイスマッピング技術(フェイススワッピングとも呼ばれます)がありますが、これについては別のブログ記事で取り上げます。
結論
この記事では、Dockerコンテナ化によって実現される移植性とスケーラビリティを備えたテキスト生成、画像生成、コンピューティングソリューションの組み合わせに依存して、GenAIモデルカクテルを構築するための基礎について説明しました。
このようなGenAIモデルカクテルの構築について詳しく知りたい方は、OctoAIのデモページをご覧いただくか、 Discord で OctoAI に参加して、人々が何を作っているのかをご覧ください。
確認
著者は、この記事のインスピレーションとなった DockerCon AI/ML ワークショップ 2023に貢献した Justin Gage 氏、および Luis Vega 氏、Sameer Farooqui 氏、Pedro Toruella 氏に感謝します。また、このブログ記事で使用した絵を描いてくれたCia Bodin氏と娘のAda氏にも感謝しています。
さらに詳しく
- DockerCon 2023 Docker for ML, AI, and Data Science ワークショップをご覧ください。
- Docker デスクトップの最新リリースを入手します。
- 次のものに投票してください! 公開ロードマップをご覧ください。
- 質問がありますか? Docker コミュニティがお手伝いします。
- ドッカーは初めてですか? 始めましょう。
フィードバック
「OctoAIとDockerでマルチモーダルGenAIアプリを構築する」に関する0の考え