Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

LiteStack for Ruby on Rails:1台のマシンで完結するワンストップ型データ管理ソリューション

本連載では、本番環境のすべてのデータを1台のマシン上でホスト・処理できるワンストップ型ソリューションLiteStack」を取り上げます。その名のとおり、LiteStackはSQLiteを活用し、以下の4つの機能を提供します。

  • LiteDBアダプタによるデータベース
  • ActiveJobバックエンド(LiteJob)
  • ActionCableバックエンド(LiteCable)
  • ActiveSupport::Cacheストア(LiteCache)

初回となるこの記事では、LiteStackの基本を紹介しながら、サンプルRailsアプリケーションのセットアップまで進めます。それでは始めましょう!

SQLiteとは

SQLiteは、何十年にもわたって多くの業界で組み込みデータベースの定番として親しまれてきました。ネイティブアプリ開発、テスト環境、キャッシュなど、幅広い場面で活用されています。

ところが近年、SQLiteはさまざまな実験や拡張の舞台として再び注目を集めています。中でも特に人気が高いのがLitestreamという拡張で、データベースの変更内容をS3互換バケットへストリーミングし、そこから復元できます。これにより、非常に低コストで本番データベースのレプリカを保持でき、いつでも障害から復旧可能になります。

こうした流れを受けて、SQLiteをRailsアプリの本番用データベースとして採用することが、現実的な選択肢になりつつあります。LiteStackのような本格的な開発スタックと組み合わせれば、「アプリを1台のマシンだけでホストする」という構想が現実のものとなります。本連載ではこの仮説を検証し、途中で立ちはだかる課題についても指摘していきます。

そのために、潜在的な問題を浮き彫りにできるほど複雑で、かつ連載で扱える程度にシンプルなサンプルアプリが必要です。

サンプルRailsアプリケーション

今回作成するのは、replicate.com上のStable Diffusionを使って、子どもの描いた絵を変換するアプリです。

たとえば、私の娘が描いたこちらのかわいいテディベアと、Stable Diffusionによる解釈例をいくつかご紹介します。

LiteStack for Ruby on Rails:1台のマシンで完結するワンストップ型データ管理ソリューション

大まかな流れとして、アプリは以下のステップをカバーします。

  1. ユーザーがテキストプロンプト付きで画像をアップロードする(ここで高度なSQLiteテクニックを紹介します)。
  2. ユーザーが画像スタイルを選択する(例:「カートゥーン」「油絵」「フォトリアル」「3Dレンダリング」)。
  3. 処理はバックグラウンドで実行される(LiteJobによるジョブが起動します)。
  4. 処理中はプレースホルダー画像を表示し、サーバーから送られてくるログを順次更新します。処理が完了したら、実際の生成画像へ差し替えます。ここでTurbo Streamsによる画像置換を通じて、LiteCableの実力を探れます。
  5. 生成された画像の予測結果を保存する。
  6. 計算コストの高いビューをLiteCacheでラップして高速化する。

これらのステップが本連載全体の骨格となりますが、この記事の残りの部分ではアプリのセットアップに焦点を当てます。

まずは、JavaScriptバンドラーにesbuild、CSSプリプロセッサにSASSを採用した「skAItch」という名前の新規Railsアプリを作成します。


LiteStackのインストール

続いて、同梱のジェネレータを使ってLiteStackをインストールします。


インストールが完了したら、セットアップを済ませて開発サーバーを起動しましょう。


認証とテナント

次に、プロンプトをユーザーと紐付けるための認証機構が必要です。Deviseのような定番gemを使う代わりに、ここでは別のアプローチを選びました。authentication-zero gemは、エンジンとして組み込むのではなく、認証システムのコードを柔軟に生成してくれる点が特徴です。しかも、以下のような便利なオプションが揃っています。

  • トークン認証(API向け)
  • 二要素認証
  • マルチテナント対応
  • レート制限
  • OmniAuthインターフェース
  • パスワードレス認証

今回は--tenantableオプションを有効にしました。データベースのレコードをアカウント単位で自動的にスコープするのは、常に良いプラクティスだからです。authentication-zeroは、AccountScopedというモデルconcernでこの機能を提供しています。


続いて、seeds経由で最初のユーザーを追加しましょう。


Promptスキャフォールド

さて、いよいよアプリ本体のロジックを書いていきます。まずはアプリの中心となるモデル「Prompt」を定義します。

Promptには、タイトル・説明文・作成者アカウントへの参照を持たせます。さらに、SQLiteの「ファイルシステム」的な能力を試すため、プロンプト画像をバイナリ形式で直接保存してみましょう。


config/routes.rbにはpromptsリソースのエントリも追加します。なお、authentication-zeroはデフォルトでApplicationControllerにユーザー認証用のbefore_actionを追加してくれる点に注目してください。


さらに、PromptモデルにAccountScoped concernをincludeすることで、ログイン中のアカウントごとにレコードをスコープできるようになります。加えて、タイトルと画像が必須であることを検証するバリデーションも設けます。


マルチテナント化の最後のステップとして、プロンプト作成時にアカウントを紐付ける処理が必要です。これはPromptsController内で行います。


RailsアプリをReplicate.comに接続する

Replicate.comは、高性能GPU上でAI予測を実行するための主要プラットフォームです。予測の作成、モデルの学習・保存などを行えるAPIを備えており、利用には https://replicate.com/account/api-tokens からAPIトークンを取得する必要があります。

注意: Replicateでの予測実行には料金が発生します。

幸い、このAPIと連携する公式・非公式のクライアントが複数存在します。そのひとつがreplicate-rails gemです。早速インストールしましょう。



APIキーは安全に保管したいので、Rails credentialsを使用します。



このファイルを編集・保存すると認証情報が暗号化され、開く際には正しいRAILS_MASTER_KEYが必要になります。

次に、これを実際に使っていきます。replicate-railsのREADMEにあるとおり、イニシャライザ内でReplicateに対して認証を行います。あわせてWebhookハンドラも定義します(今回は同じファイル内にクラスとして配置します)。なお、最初の動作確認のためbinding.irbブレークポイントを仕込んである点にご留意ください。


replicate-railsにはデフォルトのWebhookコントローラも同梱されており、上記のハンドラを呼び出してくれます。こちらはconfig/routes.rbにマウントするだけでOKです。


Webhookをローカルでテストするには、Ngrokなどでトンネルを設定する必要があります。具体的な手順は本記事の範囲外ですが、作業自体はとても簡単なので、Ngrokの公式ドキュメントを参照してください。

ただし、RailsにトンネルのURLを許可する設定は必要です。config/application.rballowed_hostsにURLを追加しましょう。


予測を実行する

それでは、予測の作成をテストしてみましょう。残る作業は、この処理をPromptsControllerに組み込むことだけです。全体のワークフローは次のとおりです。

  1. Replicateからモデルを取得する(今回はstable-diffusion-img2imgモデル)。
  2. 予測に使用する特定のバージョンを取得する(今回は最新版)。
  3. 予測を実行する。その際、以下を指定します。
    • 画像を説明するテキストプロンプト(今回はPromptのタイトルを使用)
    • Base64エンコード済みData URLとして渡す画像プロンプト
    • 予測完了時にpingされるWebhook(replicate-railsが提供するWebhookルートを指定)

https://YOUR_NGROK_URL/prompts/new にアクセスして画像とタイトルをアップロードすると、予測がトリガーされます。処理が完了すると、指定したWebhook経由でコールバックが届きます。binding.irbブレークポイントを設定しているため、コントローラアクションはREPLで一時停止し、中身をじっくり確認できます。


ご覧のとおり、初回のimg2img生成は無事成功しました。予測モデルは生成画像のURLを返しますが、Replicate側では一定期間後に画像が削除されるため、ローカルに保存しておく必要があります。このあたりの実装は次回詳しく見ていきます。

次回予告:LiteDB徹底解説

この初回記事では、Railsアプリの全コンポーネントを1台のマシンでホストする魅力的な選択肢として、LiteStack環境を紹介しました。さらに、AI画像生成のためにReplicate.comと通信するサンプルアプリのセットアップも完了しています。

シリーズ次回では、LiteStackの最初の、そして最も中心的な要素であるLiteDBを深掘りします。他にはない強力な特徴、よくある落とし穴、制限事項、トレードオフについて詳しく見ていきますので、お楽しみに。

それでは、Happy Coding!

P.S. Ruby Magicの最新記事をいち早く読みたい方は、ぜひRuby Magicニュースレターを購読してください。投稿を見逃すことはありません!

  1. AppSignalでカスタムメトリクスを追跡し、すぐに役立つ実用的なインサイトを得る方法

    カスタムメトリクスを設定すれば、ログを一行ずつ調べたり複雑なレポーティングツールに苦戦したりすることなく、必要な情報へのインサイトを即座に得られます。意味のあるメトリクスを追跡してアプリケーションの重要な監視データを補完することで、潜在的な問題を素早く特定し、解決につなげることができます。 本記事では、監視の死角をなくすためにカスタムメトリクスを設定・活用する方法を紹介します。AppSignalの監視ツール群と組み合わせてカスタムメトリクスを利用し、アプリケーションのパフォーマンスをより深く理解する方法をデモします。 カスタムメトリクスとは何か? メトリクスといえば、AppSignalはデフォ

  2. すべてのWeb開発者が機械学習を学ぶべき理由

    私はまだ子どもはいませんが、将来子どもを持ったら、二つのことを学ばせたいと思っています。個人の資産管理(ファイナンス)機械学習シンギュラリティ(技術的特異点)が近いと信じるかどうかは別として、現代の世界がデータによって動いているという事実は否定できません。データがどのように知識へと変換されるのかを理解することは、今の時代を生きるすべての人にとって重要であり、特に開発者にとっては不可欠です。本記事は、フルスタックのRuby開発者に機械学習(ML)をわかりやすく伝えることを目指したシリーズの第一弾です。MLツールへの理解を深めることで、ステークホルダーのより良い意思決定を支援できるようになります。