TECH PLAY

サイオステクノロジー(Tech.Lab)

サイオステクノロジー(Tech.Lab) の技術ブログ

621

こんにちは。サイオステクノロジーの和田拓也です。今回はAzure OpenAIを使って音声認識アプリを作ってみたので、作成手順や使用感を書いていきたいと思います。 前提条件 今回はPythonのStreamlitを使ってブラウザのマイクからインプットした音声をAIを使って文字お越ししていきます。StreamlitはPythonでWebアプリケーションを簡単に作ることができるフレームワークです。ここからはStreamlitが動く環境があることを前提に話を進めていきます。 Azure OpenAIモデル作成 まず初めにAzurePortalにアクセスして、リソースを作成します。MarketplaceでAzure OpenAIと検索して、リソース作成画面に飛びます。 作成をクリックすると、リソースの作成画面に飛びます。必要な項目を入力してリソースを作成します。今回はEast US 2をリージョンとして作成しました。 リソースの作成が終わったら、概要の上のほうにGo to Azure AI Foundry portalというボタンがあるのでクリックします。すると以下のようなページに移動します。   左側のメニューからデプロイをクリックします。すると、モデルのデプロイが行える画面が表示されます。モデルのデプロイをクリックして、基本モデルをデプロイするを選択します。   このような画面が表示されます。今回は音声認識のモデルを利用したいので、音声認識で絞り込みます。whisperというモデルのみが使えるみたいなので、今回はこちらを使用していきます。 モデルを作成し終わったら、左のメニューからホームをクリックして、表示されているエンドポイントとAPIキーをメモしておきます。 ソースコード実装 続いてソースコードのほうを実装していきます。Pythonを用いて以下のソースコードで動かしていきます。 main.py import streamlit as st from audio_recorder_streamlit import audio_recorder import tempfile from openai import AzureOpenAI endpoint = "メモしたエンドポイント" key = "メモしたAPIキー" version = "2024-10-01-preview" deployment_id = "whisper" client = AzureOpenAI( api_key=key, api_version=version, azure_endpoint = endpoint ) def transcribe_audio_to_text(audio_bytes): with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as temp_audio_file: temp_audio_file.write(audio_bytes) temp_audio_file_path = temp_audio_file.name result = client.audio.transcriptions.create( file=open(temp_audio_file_path, "rb"), model=deployment_id ) return result.text st.title("Voice to Text Transcription") # Streamlitウィジェットを使用して音声を録音 audio_bytes = audio_recorder(pause_threshold=30) # 録音した音声を再生 if audio_bytes: st.audio(audio_bytes, format='audio/wav') # OpenAI Whisper APIを使用して音声をテキストに変換 if audio_bytes: transcript = transcribe_audio_to_text(audio_bytes) st.write(transcript) これで一通り動く準備ができたので、実際に動作を確認していきたいと思います。 動作確認 Streamlitで立ち上げたブラウザにアクセスすると、以下のような画面が表示されます。 マイクのボタンをクリックして音声を録音します。すると、録音した音声を再生するボタンと、Azure OpenAIを使って文字お越しされたテキストが表示されます。   まとめ 今回は、Azure OpenAIの音声認識を使って音声認識アプリを作ってみました。使ってみた感想としては、音声認識の精度はかなり良い印象でした。しかし、無音の状態だとハルシネーションを起こすことがあったので、リアルタイムで音声認識させたい場合はすこし工夫が必要だと感じました。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Azure OpenAIの音声認識試してみた first appeared on SIOS Tech. Lab .
はじめに 皆さんこんにちは!エンジニアの細川です。 今月はサイオステクノロジーのアドベントカレンダー、テーマは「サイオス社員が今年一年で新たに学んだ技術」です! 今月2回目の執筆ですが、今回はJavaScriptなどの開発に使える高速なテスト用パッケージVitestを紹介します! Vitestとは 既にかなり話題になっているのでご存知の方も多いかもしれませんが、VitestはJavaScriptやTypeScriptの開発で利用可能なTest用のパッケージです。 もっとも有名なものはJestかと思いますが、VitestはJestとほとんど同じ機能を提供しており、移行もしやすいためVitestに移行している方も多いそうです。 Vitestのメリット 非常に高速 VitestはJestに比べて非常に高速に動作します。依存関係を事前に解決しておくなどの処理で早くなるそうです。解決しなければならない依存関係によって変わると思いますが、NestJSのserviceの単体テストを回した場合、体感で3-5倍程度早くなったので初めて導入した時は驚きました。 Jestからの移行が簡単 describe や it , expect など、Jestで提供されている機能の多くが提供されており、移行がかなり簡単かと思います。 BuildツールでViteを利用していなくても利用可能 VitestはViteでbuildをすることで高速化しているようですが、プロジェクトのbuildツールでViteを採用していなくても利用することができます。buildツールを後から変更するのはいろいろ怖い部分もあるかと思うので、buildツールを変えなくてもいいというのもメリットかなと思います。 ESMOnlyのパッケージを利用できる NestJSはcommonJSを前提としているので、あまり意識しないかもしれませんが、JestもNestJS同様commonJSを前提に動作しています。そのため、ESMOnlyのパッケージなどを利用する場合、別に設定をする必要がありました。しかしVitestではESMにも対応しているため、ESMOnlyのパッケージもそのまま利用できます。NestJSを使っていてもESMOnlyのパッケージを利用する場合もあるかと思うのでそのような場合はぜひVitestへの移行をお勧めします。(NestJSでESMOnlyパッケージを使う方法については こちら で解説しています。) Vitestのデメリット Vitestのデメリットとしては、既にJestで大量のテストを記述済みの場合などに完全に書き換えずに移行ができないという点です。 詳細は こちら のドキュメントを確認していただきたいのですが、mockの書き方や名前空間の有無など一部書き方が異なるため移行するにはそれらを書き換える必要があります。 思いつくデメリットとしてはこれくらいなので、許容できるプロジェクトではぜひ導入を検討してみてください。 前提の環境 今回のパッケージなどのバージョンは以下になります パッケージ バージョン Node.js 22.11.0 NestJS 10.0.0 Vitest 2.1.3 導入方法(NestJSの場合) Vitestの導入方法を紹介します。今回はNestJSの場合ですが、他の場合でも手順はそんなに変わらないかなと思います。 Jestの削除 NestJSはデフォルトでJestがインストールされていると思いますので、Jestの削除をしておくことをお勧めします。 デフォルトの場合、testディレクトリにe2eテスト用のconfigファイル jest-e2e.json ができていると思いますので、削除しておきます。 また、以下のコマンドでパッケージも削除しておきましょう npm uninstall -D jest @types/jest ts-jest Vitest導入 まずは以下のコマンドでパッケージのインストールを行います。 npm i --save-dev vitest unplugin-swc @swc/core @vitest/coverage-v8 その後 vitest.config.mts を作成します。 import { resolve } from "node:path"; import swc from 'unplugin-swc'; import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { globals: true, root: './', include: ["src/**/*.spec.ts"], exclude: ["node_modules", "dist"], coverage: { reporter: ["text", "json", "html"], reportsDirectory: resolve(dirname, "../coverage"), include: ["**/*.(t|j)s"], }, }, plugins: [ // This is required to build the test files with SWC swc.vite(), ], }); NestJSは基本的にcommonJSのはずですが、こちらのconfigファイルはESMの形式で書かれているので、拡張子を .ts ではなく、 .mts にしている点に注意してください。 また、 vitest.config.e2e.mts も作成しておきます。 import swc from 'unplugin-swc'; import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { include: ['**/*.e2e-spec.ts'], globals: true, root: './', }, plugins: [swc.vite()], }); 続いて、 package.json にテスト用のスクリプトを設定します。 "vitest:common": "vitest --config ./vitest.config.mts", "vitest:e2e": "vitest run --config ./vitest.config.e2e.mts", "test": "npm run vitest:common run", "test:watch": "npm run vitest:common", "test:cov": "npm run vitest:common -- --coverage", "test:e2e": "npm run vitest:e2e", あとは npm run test を叩くだけでテストを実行できます。 もちろん以下のようにファイル名を指定すれば一つだけ実行することなども可能です。 npm run test src/app.controller.spec.ts configファイルなどの設定は皆さんのプロジェクトに合わせて読み変えてください。 まとめ Vitestは非常に高速! Jestから簡単に移行できる 一部書き方を変える必要あり Viteを使ってなくても利用可能 ESMOnlyパッケージも利用できる おわりに 今回はVitestの導入方法について紹介しました! Vitestにはたくさんメリットがありますので、ぜひ皆さんのプロジェクトでも導入を検討してみてください! 今月はサイオステクノロジーのアドベントカレンダーで他にもたくさん記事が出ますのでぜひ読んでみてください!!(URLは こちら ) 今回参考にさせていただいた記事 https://devlog.mescius.jp/vitest-quickstart/ https://zenn.dev/ot_offcial/articles/6933b5e8be3091 https://vitest.dev/guide/ ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post NestJSでJestからVitestに移行してみた first appeared on SIOS Tech. Lab .
はじめに こんにちは!11月は登壇2本に講師対応と忙しかったですが、今月は社内で導入を検討しているシステムの調査をしているなーがです。前回から少し時間が空いてしまいましたが、今回はアドベントカレンダー21日目として、Azure DevOpsのCDパイプラインでデプロイ時に発生したエラーを解決した方法について書こうと思います。 とある先日のこと 先輩があるシステムでデプロイを行った際にエラーが発生したので調査を依頼されました。そのシステムはAzure上にデプロイされており、ソースコードはAzure DevOpsで管理されているためAzure PipelinesのCDパイプライン(Releases)のログを確認しました。すると、下記のようなエラーが確認できました。 Unsupported authentication scheme ‘WorkloadIdentityFederation’ for Azure endpoint. Azure エンドポイントでサポートされていない認証スキーム ‘WorkloadIdentityFederation’ があります。 そのため、AzureとAzure Pipelinesの接続設定である Service connections の該当リソースからManage App registrationをクリックし、サービスプリンシパルを確認しました。 すると、クライアントシークレットの有効期限が切れていました。 調査結果を先輩に報告したところ、先程エラーとなっていたCDパイプライン内のタスク「AzureBlob File Copy」がバージョン3であることからクライアントシークレットを使う必要があり、その有効期限が切れていたためデプロイが失敗していると判明しました。 現在では「AzureBlob File Copy」のバージョンは6まで出ており、  ワークロード ID フェデレーション を使用するサービス接続も サポートされる ようになっています。 そのため、先輩に  ワークロード ID フェデレーション への切り替えとCDパイプラインの実行をしてもらったところ、無事にデプロイが成功しました。 めでたしめでたし… と思ったのも束の間! デプロイしたアプリケーションにアクセスしてみると、CSSが適用されていませんでした… ここからが本題です! CDNに対してデプロイしたファイルが、どれも404エラーでアプリから読み込めなくなっていました。そこでAzureのCDNリソースを確認してみると、cdnというフォルダが作成されてその中にアップロードされていたためでした。 これはCIパイプラインでビルド成果物の公開名(Artifact name)で cdn とし、CDパイプラインのソースで以下のように参照していたためです。 CIパイプライン CDパイプライン 「AzureBlob File Copy」のバージョンが3の時は問題なくデプロイされてCSSも適切に適用されていました。そこで、AzureFileCopyに関する MSの公式ドキュメント や リポジトリの変更履歴 、 Issue を見ても解決方法が分かりませんでした。(ご存じの方はコメントで教えて頂けると助かります!) どうするか ダメもとで、CDパイプラインのソースで以下のように設定してみたところ、デプロイが成功し、無事にCSSも適用されていました。 さいごに 今回はAzure DevOpsのCDパイプラインでデプロイ時に発生したエラーを解決した方法について書きました。公式に記載がないため根拠があるわけではありませんが、同様の現象で困っている方の参考になれば幸いです。今後も業務で学んだことをブログにしていきたいと思います。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Azure Pipelinesのタスク「AzureBlob File Copy」をバージョンアップした際にハマった話 first appeared on SIOS Tech. Lab .
サーバーレスアーキテクチャを採用することで、開発者はトラフィックやスケーリングなどのインフラストラクチャに関する作業を気にすることなく、コスト削減やパフォーマンス向上を実現し、アプリケーション開発に集中することが可能です。 OpenShift 環境では、Red Hat OpenShift Serverless を導入することでサーバーレスアーキテクチャを実現でき、以前の記事で紹介した OpenShift Pipelines や OpenShift GitOps と組み合わせることで、CI/CD パイプラインを通じたサーバーレスアプリケーションのデプロイもスムーズに行えます。 本記事では Red Hat が提供する OpenShift Serverless と、そのベースとなっている Knative について簡単に概要をつかめるようにまとめていきます。 OpenShift Serverless とは? OpenShift Serverless は、OpenShift クラスタ上でサーバーレスのアプリケーションを実行させるサービスです。OSS の Knative プロジェクトをベースとしています。通常、アプリを動かすにはサーバーの設定やメンテナンスが必要ですが、OpenShift Serverless を使うと、それらを気にせずにサービスを提供できます。必要な時にだけ Pod を立ち上げるため、リソースの節約にもつながります。 OpenShift Serverless のメリット アプリケーションのデプロイメントやスケーリングを自動で行い、サーバーの管理に関する手間を省くことができます。 イベントをトリガーとしてアプリケーションを実行させることが可能で、リアルタイムデータ処理などのイベントベースのアプリケーションを容易に構築できます。 アプリケーションのトラフィックに応じてリソースを自動的にスケールアップ・ダウンするため、パフォーマンスを最適化し、リソースの無駄遣いを防ぐことができます。 OpenShift Serverless のコンポーネント OpenShift Serverless には主に以下のコンポーネントがあります。以前は Knative Build もありましたが、現在(執筆時点のバージョン 1.34.1)は CI/CD の OpenShift Pipelines に移行されています。 Knative Serving アプリケーションのデプロイメント、オートスケーリング(自動でスケールアップやスケールダウンを行う)、トラフィック管理を担当します。リクエストに応じてコンテナを起動し、不要になれば停止することでリソースの節約を図ることができます。リビジョン管理も可能で、バージョン管理を容易にし、ブルー/グリーンデプロイメントやカナリアリリースなどのデプロイメント戦略もとることができます。 Knative Eventing イベント駆動型アーキテクチャを実現するためのコンポーネントで、様々なイベントソース(Event Producer)からのイベントを受け取り、それを CloudEvents 仕様へ成形してサービス(Event Consumer)に渡します。CloudEvents 仕様とは、イベントデータの標準化を目的とした CNCF のプロジェクトで、イベントの形式やプロトコルを統一して、異なるシステム間でのイベントの受け渡しを容易にします。Knative Eventing はこの仕様に準拠し、イベントのルーティングやフィルタリング、変換を行うことができます。定期的なイベントであったり、Kafka の Topic メッセージ、GitHub からの Webhook などをイベントソースとして利用することができます。 ユースケース イベント駆動型アプリケーション Knative Eventing を利用することで、開発者はイベントソースからのイベントを受け取り、それに応じてサービスをトリガーすることができます。これにより、リアルタイムでのデータ処理や、ユーザーの行動に応じた動的なレスポンスを実現することが可能になります。 API やマイクロサービスの構築 Knative Serving を使用して、トラフィックに基づいて自動的にスケールする API やマイクロサービスを作成できます。アプリケーションは必要に応じてリソースを確保し、使用していないときはリソースを解放します。 類似サービス AWS Lambda Amazon Web Services が提供するサーバーレスコンピューティングサービスです。Kubernetes とは異なり、AWS の独自のインフラストラクチャ上で動作します。OpenShift Serverless と比較すると、プログラミング言語のサポートやオートスケールの機能に関しては類似していますが、管理が OpenShift か AWS といった点が大きな違いになります。そのため、OpenShift Serverless(Knative)は特定のクラウドプロバイダーにロックインされるリスクを軽減することができます。 Kubeless、Fission Kubeless と Fission はどちらも Kubernetes 上で軽量に動作するオープンソースのサーバレスフレームワークです。OpenShift Serverless と比較すると、こちらも管理が OpenShift か Kubernetes といった点が違いにはなりますが、OpenShift Serverless のベースとなっているKnative は同じ Kubernetes 上で動作します。Fission と Kubeless もオートスケールはサポートしていますが、ゼロスケールはサポートしていない点も違いになります。Fission と Kubeless は、よりシンプルで軽量なフレームワークを求める場合などの要件に適しています。 まとめ OpenShift Serverless( Knative)について簡単にまとめてみました。OpenShift Serverless を実際に構築してみる記事も投稿する予定なのでそちらも読んでみてください。 参考文献 https://www.redhat.com/ja/technologies/cloud-computing/openshift/serverless https://www.scsk.jp/sp/openshift/developer5.html https://docs.openshift.com/serverless/1.34/about/about-serverless.html https://www.redhat.com/ja/blog/introducing-using-openshift-serverless-event-driven-applications?channel=blog/channel/red-hat-openshift&page=3 https://rheb.hatenablog.com/entry/2021/12/14/%E3%81%82%E3%82%89%E3%81%9F%E3%82%81%E3%81%A6Knative%E5%85%A5%E9%96%80%EF%BC%81%EF%BC%88Knative_Serving%E3%82%84%E3%82%84%E7%99%BA%E5%B1%95%E7%B7%A8%EF%BC%89 https://www.densify.com/openshift-tutorial/openshift-serverless/ ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Red Hat OpenShift Serverlessとは? first appeared on SIOS Tech. Lab .
PS/SLの佐々木です。 アドベントカレンダー19日目です。 今回は2年ほど続けてきた輪読会の取り組みについて紹介します。 輪読会の目的 輪読会の開催目的には以下のようなものがあります。 エンジニアの基礎レベルの底上げ 書籍による体系的な知識の取得 共通言語を用いたコミュニケーションが取れるようにする 学習習慣、学習文化の形成 特に学習文化の形成という点に関しては継続的、自律的に組織としての技術レベルを向上させるために非常に重要だと考えています。 今までの取扱書籍 Unit Testing ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本 フロントエンド開発入門 プロフェッショナルな開発ツールと設計・実装 OAuth, OAuth認証、OpenID Connectの違いを整理して理解できる本 今日から始める情報設計 リーダブルコード 雰囲気でOAuth2.0を使っているエンジニアがOAuth2.0を理解して、手を動かしながら学べる本 今更聞けない暗号技術&認証・認可 達人に学ぶDB設計 活動内容 活動は週1日の夕方に行っています。 参加メンバーは若手中心で若手の中で課題図書の担当の発表を行いそこに、先輩エンジニアにも入ってもらい議論に参加していただいたり、技術的なアドバイスをいただいたりしています。 発表資料は綺麗に作るのは大変なのでnotionにまとめてもらい、画面共有しながら発表しています。 また技術書を読む際に理解ができないものや、内容が抽象的すぎて解釈が色々できてしまうものに関しては発表の段階で自分で頑張って調べて結論をだすのではなく、発表の時にその部分をみんなで議論するという進め方をして参加のハードルをなるべく下げるようにして運用してます。( 大学のゼミみないなのは結構辛いですよね。。) 効果 1. エンジニアの基礎スキルの向上 輪読会を通じて体系的な知識を習得することができ、エンジニアとしての基礎スキルが着実に向上します。特に書籍を活用することで、断片的な情報ではなく、基礎から応用まで一貫性のある内容を学べるため、業務に直結するスキルを効果的に強化することができたと思います 2. 共通言語の形成による円滑なコミュニケーション 同じ書籍を通じて学習することで、用語や概念に関する共通の理解が生まれ、コミュニケーションがスムーズになっていくと思います。またメンバー間で技術的な考え方やアプローチについて議論することで、より深い理解と協調が生まれ、実務でも技術的な議論がしやすくなると考えています。 3. 学習文化・習慣の定着 輪読会は単発の学習活動ではなく、週ごとに定期的に開催されることで、継続的な学習の基盤を築いています。これにより、組織全体に学び続ける文化が根付くと同時に、若手エンジニアが自ら主体的に学ぼうとする姿勢が自然と養われます。また、輪読会では、抽象的で難解なテーマについても個人で結論を出す必要はなく、みんなで議論しながら理解を深めるスタイルを取っており、初心者にとっても学びやすい環境を提供できていると考えています。 4. 心理的安全性の向上 情報を取りまとめて人と前で発表する経験が積めるとともにディスカッションを行っており、経験の浅い若手エンジニアでも安心して発言や質問ができる場が提供できています。 このような場でコミュニケーションをとることにより実務でもコミュニケーションがとりやすくなったりと、技術力向上以外の面においても組織の成長に貢献できる取り組みになっていると思います。 まとめ 今回はPS/SLで行っている輪読会の取り組みと2年間運用してきた効果をまとめてみました。 わかりやすく技術力向上という面以外にも様々なメリットがあり、この輪読会きっかけて課題図書以外の技術的な議論も盛んになっていくと面白い会になるなと思っています。 輪読会の中で実際にペアプロをして動かしてみたりするのも面白そうだなと思っているので会の中で他の試作も取り入れてみようと思います。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post SIOS輪読会の取り組み first appeared on SIOS Tech. Lab .
こんにちは! 今月も「OSSのサポートエンジニアが気になった!OSSの最新ニュース」をお届けします。 FINOS が Linux Foundation Research と協力して、業界の最新動向を調査したレポート「金融サービスにおけるオープンソースの現状 – 2024」を公開しました。 FINOS & LF Research 調査レポート「金融サービスにおけるオープンソースの現状 – 2024」を公開 https://prtimes.jp/main/html/rd/p/000000329.000042042.html 2024/12/16、LPI-Japan は無償でダウンロード可能な「Linux標準教科書 バージョン4.0.0」をリリースしました。 LPI-Japan、無償教材「Linux標準教科書」の最新版をリリース https://japan.zdnet.com/article/35227352/ NTT コミュニケーションズがサーバ攻撃対策として準備した内容、一連の被害体験で得た教訓までを公表しました。 NTTコムが「サイバー攻撃の被害」公表前にした準備 顧客を傷つけず、社内の混乱を抑えた方策とは https://news.yahoo.co.jp/articles/422c9a380b7a4449909948ee60aafa80b1fc4295 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【2024年12月】OSSサポートエンジニアが気になった!OSS最新ニュース first appeared on SIOS Tech. Lab .
今号は、前号の「 パッケージマネージャについて 」の続きになります! 今回は Debian 系システムの apt で、以前紹介できなかったサブコマンドについてご紹介します。 apt の便利なサブコマンド パッケージの情報を表示 apt-cache show コマンドを実行すると、特定のパッケージの詳細な情報を表示します。 例えば、git というパッケージの情報を表示する場合は、下記の様なコマンドになります。 # apt-cache show git … Package: git Architecture: amd64 Version: 1:2.34.1-1ubuntu1.6 Multi-Arch: foreign Priority: optional Section: vcs Origin: Ubuntu Maintainer: Ubuntu Developers original-Maintainer: Jonathan Nieder Bugs: https://bugs.launchpad.net/ubuntu/+filebug Installed-Size: 18484 Provides: git-completion, git-core Depends: libc6 (>= 2.34), libcurl3-gnutls (>= 7.56.1), libexpat1 (>= 2.0.1), libpcre2-8-0 (>= 10.34), zlib1g (>= 1:1.2.0), perl, liberror-perl, git-man ( = 1:2.34.1-.) Recommends: ca-certificates, patch, less, ssh-client Suggests: gettext-base, git-daemon-run | git-daemon-sysvinit, git-doc, git-email, git-gui, gitk, gitweb, git-cvs, git-mediawiki, git-svn … (長いため省略) この時、結果には アーキテクチャ、パッケージバージョン、ライセンス情報、依存パッケージ (Depends) の情報など 、様々な情報が表示されます。 なお、上記のコマンドはネットワーク上のリポジトリから情報を取得してくるため、 対象のパッケージがインストールされていなくても情報が表示されます。 パッケージの依存関係を表示 apt-cache depends コマンドを実行すると、特定のパッケージの依存関係を表示します。 例えば、git というパッケージと依存関係のあるパッケージ一覧を表示する場合は、下記の様なコマンドになります。 依存関係の情報は apt-cache show でも確認できますが、 apt-cache depends の方が整理された状態で、より分かりやすく表示されます。 # apt-cache depends git Depends: libc6 Depends: libcurl3-gnutls Depends: libexpat1 Depends: libpcre2-8-0 Depends: zlib1g Depends: perl Depends: liberror-perl Depends: git-man Depends: git-man Recommends: ca-certificates Recommends: patch patch:i386 Recommends: less less:i386 Recommends: openssh-client openssh-client:i386 Suggests: gettext-base gettext-base:i386 Suggests: git-daemon-run Suggests: git-daemon-sysvinit Suggests: git-doc Suggests: git-email Suggests: git-gui Suggests: gitk Suggests: gitweb Suggests: git-cvs Suggests: git-mediawiki Suggests: git-svn この時、結果には Depends、Recommends、Suggests という 3種類の情報が表示されます。 ・Depends:対象のパッケージが動作するために必須となる、依存パッケージ ・Recommends:依存パッケージではないが、インストールが推奨されるパッケージ ・Suggests:依存パッケージではないが、あると便利な機能を提供するパッケージ パッケージをインストールする際、デフォルトの動作では Depends、Recommends のパッケージがインストールされます。 ただし、 –no-install-recommends オプションを指定した場合 Recommends はインストールされず、Depends のパッケージのみがインストールされます。 # apt-get install --no-install-recommends git パッケージのリストを表示 apt list コマンドを実行すると、特定の条件に合致するパッケージのリストを表示します。 例えば、git という文字列から始まるパッケージのリスト (一覧) を表示する場合は、下記の様なコマンドになります。 # apt list git* … git-absorb/jammy 0.6.6-2build2 amd64 [installed] git-all/jammy-updates,jammy-updates,jammy-security,jammy-security, 1:2.34.1-1ubuntu1.11 all git-annex-remote-rclone/jammy,jammy 0.6-1 all git-annex/jammy 8.20210223-2ubuntu2 amd64 git-autofixup/jammy,jammy 0.003001-2 all git-big-picture/jammy,jammy 1.1.1-1 all git-build-recipe/jammy,jammy 0.3.6 all git-buildpackage-rpm/jammy,jammy 0.9.25 all git-buildpackage/jammy,jammy 0.9.25 all git-bump/jammy,jammy 1.1.0-2 all … (長いため省略) 上記は、 ご利用環境で有効になっているリポジトリから、指定した条件でパッケージを検索しています。 また、上記の条件に併せてインストール済みパッケージのみを抽出することができます。 例えば、git という文字列から始まるパッケージのうち、インストール済みのパッケージのみを表示する場合は、下記の様なコマンドになります。 # apt list --installed git* 補足:apt 関連のコマンドの実行履歴は確認できる? apt には dnf history のようなサブコマンドはありません。 そのため /var/log/apt 配下に出力されるログから確認する必要があります。 /var/log/apt 配下には、下記の様なログが出力されます。 /var/log/apt/history.log パッケージのインストール/アップデート/削除などの実行履歴を記録するログです。 /var/log/apt/term.log パッケージのインストール/アップデート/削除などを実行した際、コンソール上に表示された内容を記録するログです。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 知っておくとちょっと便利!パッケージマネージャについて4 ~Debian 系システム編・続き~ first appeared on SIOS Tech. Lab .
  こんにちは、サイオステクノロジーの佐藤 陽です。 今回ははCosmosDBのインデックス機能についてご紹介したいと思います。 RDBにおいても登場するインデックスですが、CosmosDBにおいても重要な概念です。 ただRDBとは設定方法などは異なってくるため、CosmosDBにおけるインデックスについてご紹介していきたいと思います。 はじめに CosmosDBのインデックスについてご紹介していきます。 インデックスを正しく設定・使用することで、検索速度の向上や、使用するRUの削減にもつながります。 CosmosDBにおいて どのようにインデックスが構築されるのか どのようにインデックスが使われるのか について見ていきたいと思います。 インデックスの作成 CosmosDBにおいては、アイテムが追加・削除などされたタイミングでインデックスが自動で設定されます。 そのため基本的に何も設定しなくても高い検索パフォーマンスが得られます。 逆インデックス CosmosDBにおいては、格納されるアイテムを元にツリーが形成され、そのツリーを元に 逆インデックス というものが構築されます。 これはアイテムが追加されるたびに行われ、常にツリーの内容に反映されます。 と言われてもピンとこない気がするので、 前回まで扱っていた値(を少し修正したもの)を例にして提示したいと思います。 以下のデータがCosmosDBにおいて格納されているとします。 {     "id": "1",     "name": "寿司",     "price": 2000,     "ingredients": [         {"name":"米"},         {"name":"魚"}] }, {     "id": "2",     "name": "うどん",     "price": 500,     "ingredients": [         {"name":"小麦"},         {"name":"塩"},         {"name":"水"}] }, {     "id": "3",     "name": "パスタ",     "price": 1000,     "ingredients": [         {"name":"デュラム小麦"},         {"name":"塩"},         {"name":"水"}] } その場合、これらのアイテムは以下のようなツリーで表示されます。 配列を持つアイテムに関しては、配列内のそのエントリのインデックス (0、1 など) でラベル付けされた中間ノードを取得します。 これをベースとして、逆インデックスを作成していきます。 まず、各アイテムのidがツリーにおけるどのルートに対応するかを見ていきます。 全てのルートに対して図示すると見づらいので、Ingredientsのノードだけ確認します。 ここで①、②、③はそれぞれ各アイテムのidを表します。 例えば root/ingredients/1/name/塩 というルートは うどん , パスタ のアイテムの値が存在しているため②,③のマーキングがしてあります。 このツリーを元に、逆インデックス表を作成します。 (あくまでイメージです) パス 値 id /name 寿司 1 /name うどん 2 /name パスタ 3 /price 500 2 /price 1000 3 /price 2000 1 /ingredients/0/name 米 1 /ingredients/0/name 小麦 2 /ingredients/0/name デュラム小麦 3 /ingredients/1/name 魚 1 /ingredients/1/name 塩 2,3 /ingredients/2/name 水 2,3 この逆インデックス表がどのように使われるのかというと 例えば、 うどん という名前の料理を取得したい場合は以下のクエリを実行します。 select * from c where c.name = "うどん" この時、クエリエンジンは各アイテム(寿司、うどん、パスタ)を個別には検索しません。 逆インデックス表から 「name=うどん」ということは、idが1のアイテムだな という事がすぐに判明するため、id=1のアイテムのみを取得します。 …といったものが全体像になります。 ここからインデックスを用いた検索についてもう少し詳しく見ていきます。 検索 検索の流れとしては、 検索エンジンがクエリのフィルターを評価する 作成したツリーを利用してルートからプロパティまで走査する 該当するアイテムを返す といった流れです。 検索エンジンは、次に記載する評価方法のうち最も効率的なものを自動で選択し、評価を行います。 なお、これらの評価方法一覧は 公式ドキュメント にまとまってるので、概要は一旦こちらで確認してもらって 本記事ではもう少し具体的な例に落とし込んで紹介したいと思います。 インデックスシーク インデックスシークは最も効率の良い検索方法になります。 クエリエンジンが、指定されたフィールド値との完全一致したもののみを検索します。 先程挙げた例となりますが 以下のようなクエリの場合はnameが うどん と完全一致するものだけを検索すればよいので、インデックスシークが行われます。 select * from c where c.name = "うどん" また、検索するものが2つ以上ある場合でもインデックスシークが行われます。 これは うどん , パスタ それぞれの値に対する完全一致のみを検索しているためです。 select * from c where c.name IN ("うどん", "パスタ") 検索する際に、 完全一致か否か が判断のポイントかと思います。 インデックススキャン インデックススキャンは、クエリエンジンが対象となフィールドに対して、可能性のある全ての値を見つけるよう検索します。 先程のインデックスと比較して 完全一致 のものだけを探すのではなく、可能性があるものを操作することがポイントです。 また、インデックススキャンに関してもは、更に3つに細かく分類されるため、それぞれの値を見ていきたいと思います。 正確なインデックス スキャン 以下のようなクエリが対象です。 select * from c where c.price >= 1000 この場合、priceというフィールドの値に対して比較を行います。 この比較の処理を、ドキュメントでは バイナリ検索 と定義しています。 このバイナリ検索によって、複雑さが増し、インデックス シークから正確なインデックス スキャンへと変化しました。 そしてここでポイントなのですが、検索時に用いられる逆インデックスにおいて、一部の値に関しては昇順に並び替えられています。 パス 値 id /price 500 2 /price 1000 3 /price 2000 1 上記した表から抜粋 つまり、今回であれば 1000 という値を見つけた後は、逆インデックス表を昇っていくだけで値を取得することが可能です。 一方でこういったクエリも正確なインデックススキャンの対象となります。 select * from c where startswith(c.name, "うど")   ここからは公式ドキュメントに明言されてなかった部分なので、考察になるのですが 文字列に関しても、数値と同様に逆インデックス上においては昇順に並び替えられるのだと思います。 (そのため、上記に示した逆インデックスももしかしたら並び順は正確ではないかもしれません) そのため、今回であれば うど で検索されたポイントから昇順で検索していくだけでよいので、正確なインデックススキャンが使用されると思います。 なお、これに関しては後述する 拡張インデックススキャン の例と比較すると分かりやすいかと思います。 逆インデックスに関する並び順 逆インデックスにおいては値が昇順に並んでいるという言及をしましたが、公式ドキュメントに以下の記載がありました。 逆インデックスには、2 つの重要な属性があります。 ・特定のパスでは、値は昇順に並べ替えられます。 そのため、クエリ エンジンでインデックスから簡単に ORDER BY を提供できます。 ・特定のパスについて、クエリ エンジンで可能な値の個別のセットをスキャンして、結果が存在するインデックス ページを識別できます。 「特定のパスでは」という表現があるので、全てではないと思うのですが、数値・文字列・日付などは昇順に並び替えられ これらに関しては正確なインデックススキャンが利用されるのではないかと予想しています。 拡張インデックススキャン 拡張インデックススキャンに関しても、正確インデックススキャンと同じで特定のフィールドに対してバイナリ検索を行うものになります。 具体的なクエリを見てみたいと思います。 select * from c where startswith(c.name, "うど", true) 先程の正確なインデックススキャンの例のstartwithに true の引数が追加されました。 これは大文字・小文字を区別するかしないかを表すパラメータです。 そのため、正直日本語の検索ワードに対しては意味ないのですが、そこは雰囲気で感じ取ってください…。 大文字小文字を区別しないことで、「正確なインデックスキャン」から「拡張インデックススキャン」になるわけですが これが、先程言及した逆インデックス上の文字列の並び順に影響していると考えています。 逆インデックス上で文字列が昇順に並び替えられるわけですが、この時恐らく大文字と小文字は別物として並び替えられます。 つまり、大文字・小文字を区別せずに検索する場合、昇順に上がっていくだけではなく、降っていく範囲の検索も必要になると予想されます。 そのため、検索範囲が「拡張」され、拡張インデックススキャンとして検索されるのだと思われます。 フルインデックススキャン フルインデックススキャンはこれまで述べてきたものよりも、更に検索範囲が広いものになります。 以下のようなクエリのケースがフルインデックススキャンにあたります。 select * from c where endswith(c.name, "どん") この場合、 name のお尻の文字でフィルタリングをかけようとしているため、 逆インデックスの並び順は役立ちません。 結局、 name のプロパティを持つアイテムを全て検索することになります。 そのため、拡張インデックススキャンと比べても更に検索範囲が広がることが分かります。 これらの点から分かることとして、フィルタリングに使う句は必要最低限のものを採用するべきであることが分かります。 たとえば、 startswith 句でのフィルタリングで要件を満たすはずなのに、 contains 句を採用してしまうことで、 正確なインデックススキャンで済んでいたものが、フルインデックススキャンとして実行され、検索速度が劣化し、余計なRUも発生します。 クエリを書く際は果たしてそれが最適なフィルタリングになっているかどうかをよく考える必要がありそうです。 フルスキャン 最後にフルスキャンについてです。 これはそもそもインデックスを利用できない場合の評価方法になります。 フルインデックススキャンの例の場合は、 name のプロパティを持つアイテムだけを全てスキャンしていましたが フルスキャンの場合は name のプロパティを持たないアイテムも含め、全てのアイテムをスキャンするような形となります。 検証 インデックスによる検索によって、検索速度やRU量にどの程度影響が出ているかはCosmosDBのデータエクスプローラ空も確認することができます。 クエリを実行した後に Query Stats を確認すると、Request Chargeとindex lookup timeという値が確認できます。 今回は入れているデータが少なすぎたため、検索方法を切り替えてもあまり差異は見られませんでした。 データが膨大である場合はこのあたりの数値に変化がみられると思うので、是非一度自分の環境でも試してみてください。 まとめ 今回はCosmosDBにおけるインデックスの概念と、インデックスを利用した検索方法の内容についてご紹介しました。 逆インデックスの性質を把握し、正しいフィルター句を選択することで検索速度の向上や、コストの抑制が行えることが分かりました。 あとはインデックスに関しては、他にもインデックスポリシーという概念があり、インデックスを作成するプロパティなどを切り替え、より最適化を行うことができます。 このインデックスポリシーに関しては、また別途記事にしたいと思います。 ではまた! 参考 https://learn.microsoft.com/ja-jp/azure/cosmos-db/index-overview https://learn.microsoft.com/ja-jp/training/modules/define-indexes-azure-cosmos-db-sql-api/2-understand-indexes ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【Azure】CosmosDBにおけるインデックス入門ガイド【初心者向け】 first appeared on SIOS Tech. Lab .
はじめに サイオステクノロジーの塚田です。Rancher入門ブログシリーズとして、 前回 はRancherを使って複数のクラスターを管理する方法について解説しました。本記事では、Rancherを用いてKubernetesクラスターの監視を行う方法について解説します。具体的には、Rancher標準のモニタリング機能を有効化し、PrometheusやGrafanaと連携することでRancherのダッシュボードからクラスターのリソース消費状況をモニタリングしたり、アラート通知を実現する手順を紹介します。これにより、複数のクラスターを効率的に監視・管理できる仕組みを構築することができます。 概要 前提条件 Rancher Serverが構築済みであること Rancher Serverにログインできること Rancherから管理対象クラスターを連携済みであること 構築イメージ RancherのダッシュボードからHelmを利用して、rancher-monitoringアプリケーションをインストールします。これにより、管理対象クラスター内にPrometheusやGrafanaなどのモニタリングツールを導入することができます。 rancher-monitoringアプリケーションは、主要なオープンソースの監視およびアラート機能をクラスタに迅速に導入するためのツールです。 Prometheusは、システム監視や時系列データの収集を目的としたオープンソースのモニタリングツールです。Prometheusを利用することで、CPU使用率やメモリ使用量などのリソースデータを効率的に収集し、システムの状況を可視化することができます。 導入後のイメージは以下の通りです。 バージョン情報 Rancher Monitoring: 105.1.0+up61.3.2 ※ ※本記事執筆時点における最新バージョン 導入手順 モニタリングのインストール まずはCluster Management画面上で対象クラスターのExploreを押下してクラスターのダッシュボードに遷移します。 Apps内のChartsからMonitoringを選択します。 Monitoringを選択し、Installを押下します。 インストール設定を以下のように入力し、Installを実行します。 Project: System 他はデフォルト     インストール完了後、サイドバーからWorkloadsを選択し、Installed Appsページにrancher-monitoringが存在することを確認します。 Monitoringアプリケーションをインストールすると、クラスターダッシュボードのメニューにMonitoringが追加されます。 この画面から、インストールしたPrometheus、Grafana、Alertmanagerの詳細な設定画面に遷移することができます。 クラスターのモニタリング rancher-monitoringアプリケーションを導入することで、RancherのUI画面に各種ダッシュボードが追加されます。これを利用して、クラスターのモニタリングを行います。 メニューからClusterを選択し、画面を下にスクロールすると、クラスターのリソース消費状況を表示するダッシュボードが追加されています。 ここではクラスター内の各NodeのCPU利用率、メモリ利用率、ディスク利用率などを確認することができます。 Summaryの横にある、Grafanaへのリンクを押下するとクラスター内で稼働しているGrafanaの画面に遷移することができます。 Grafanaへ遷移した直後は未ログイン状態です。 この状態でもダッシュボードの閲覧は可能ですが、Data Sourceの追加などができません。 Grafanaにadminユーザーとしてログインすると、Data Sourceの追加やダッシュボードの編集が実行できるようになります。 デフォルトのGrafanaのログイン情報は以下の通りです。 ユーザー:admin パスワード:prom-operator ワークロードのモニタリング クラスター単位だけではなく、クラスター内部のリソースも監視することができます。手順は以下の通りです。 サイドバーからWorkloadsに遷移します。 DeploymentsやPodsに移動し、Metricsタブを押下するとPodのリソース消費状況のダッシュボードが表示されます。 アラート設定 Rancherのダッシュボード上でAlertmanagerのルールを設定し、各クラスターから設定した通知先にアラート通知を送信することができます。 今回は、nginxのPodからアラートを発報する設定を作成するデモを行います。Rancher上でPodを作成する方法は 前回の記事 にて紹介しておりますので、参考になれば幸いです。 前提条件 nginxのPodが起動していること SlackのIncoming Webhookを設定し、Slcak API用のURLを発行していること Slack Webhook URLをキーとするSecretをnginx namespaceに作成します。 Key: slack_url Value: <SLACK_WEBHOOK_URL> Monitoring→AlartmanagerConfigへ遷移します。 Createを押下してAlartmanagerConfigを新規作成します。 Add Receiverを押下してReciever設定画面へ遷移します。 Add Slackを選択します。 Target情報を入力します。 作成したSecretを選択 defaultチャンネル欄に作成した検証用チャンネルを入力 Routeを設定します プルダウンからAlartmanagerConfigを選択 MatcherでSecretと同じnamespaceを指定 サイドバーのMonitoringからPrometheus Ruleに遷移し、Createを押下してアラートルールを作成します。 以下のように設定します。 namespace: アラートを発報したいリソースと同じnamespaceを指定 name: 任意の名称 Rule Group 1の設定 Group Name: 任意の名称 Add Alertを選択し、アラートルールを入力 Alert Name: 任意の名称 PromQL Expression: container_memory_working_set_bytes{pod=~”nginx.*”} > 1000000 Severity: critical Annotations: Messageを有効化し、任意のメッセージを入力   指定したSlackチャンネルにアラートが送信されたことを確認します。 このように、Rancherのダッシュボード画面上からAlertmanagerの通知ルールを設定し、アラートをSlackに送信することができます。これにより、複数のクラスターが稼働している環境下でも、アラート設定をRancher上で一元管理することができます。 まとめ 本記事では、RancherのKubernetesクラスター監視機能を利用して管理対象クラスターをモニタリングする方法を解説しました。 一般的に、PrometheusやGrafanaはHelmを用いてインストールされることが多いですが、この方法ではインストール後に設定やツール間の連携を手動で行う必要があり、セットアップに時間と手間がかかる場合があります。さらに、管理するクラスターが増えるほど、それぞれのクラスターでモニタリング環境を構築・管理する工数も比例して増加し、運用の負担が大きくなる傾向があります。一方で、rancher-monitoringアプリケーションを利用することで、PrometheusやGrafanaのインストールと設定をRancherのUIから簡単に一括管理でき、手動設定の手間を大幅に削減できます。特に、複数クラスターを管理している環境では、Rancherの一元化されたダッシュボードを活用することで、効率的にモニタリング環境を構築できる点が大きなメリットです。 次回の記事では、RancherとLonghornを組み合わせた分散ストレージの管理方法を紹介します。ぜひご期待ください。 参考 Rancher公式ドキュメント: Monitoring and Alerting ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Rancher入門:Rancherを用いたKubernetesクラスターの監視 first appeared on SIOS Tech. Lab .
はじめに こんにちはサイオステクノロジーの小野です。私は今年入社したばかりの新卒社員なので今年一年は新しいことしか学んできませんでした。その学んできた中でもOpenShift AIは一番インフラエンジニアとして学びになったと感じました。(あと単純にAIが好きだったので一番楽しかったです。)今まで、様々なソフトウェアに対してアプリケーション目線のことしか考えてきませんでしたが、OpenShift AIの勉強を通じて、そのソフトウェアがどのようにして動いているのか、内部のアプリケーションがどのようにして実行されているのかインフラ目線で見る意識が養われた気がします。 今回はそんなOpenShift AIを利用して機械学習を行う方法について解説します。 前回 はOpenShift AIを導入してワークベンチのJupyterNotebookを起動するところまで解説したので、まだ見ていない方は先にそちらをご覧ください。 Openshift AIでの機械学習 今回はOpenShift AIのワークベンチ機能とデータ接続機能を用いて実際に機械学習を行います。 ワークベンチは機械学習のモデルを作成、操作するために隔離された作業環境です。MLOpsにおけるデータの分析やモデルの学習、評価、検証を行うために用いられます。 データ接続はOpenShift AIの各種機能を外部のS3オブジェクトストレージに接続するための機能です。 今回構築する機械学習モデル 機械学習におけるモデルとは、あるデータを入力するとそのデータに応じた出力をする数学的関数のことを言います。 今回はMNISTという数字の画像を入力して、その画像が何の数字かを出力するモデルを構築します。 今回構築する機械学習モデル 機械学習をやってみる 全体的な作業流れ 最初にOpenShiftAIでプログラムを実行するための環境を設定します。そのために、OpenShiftAIのデータサイエンスプロジェクト、データ接続、ワークベンチをそれぞれ設定します。その次にサンプルプログラムをJupyterLabにアップロードします。最後にプログラムを実行すると、簡単な機械学習を行うことができます。 本環境の条件 OpenShift情報 OpenShift:4.17 OpenShift AI:2.13 ストレージ情報 AWS(S3) S3を操作するためのIAMと作業用バケットを事前に作成してください。 プログラムソース 0_dataupload.ipynb 1_dataprocessed.ipynb 2_training.ipynb 環境構築手順 データサイエンスプロジェクト作成 最初にデータサイエンスプロジェクトを作成します。この作業は前回の記事の「 Data Science Projects作成 」を参考にして設定してください。 データ接続作成 次にデータ接続設定を行います。データサイエンスプロジェクトの詳細画面からData connectionsに移動します。Add data connectionを押下して、設定は以下のようにします: Name test-connection Access key S3へのアクセス権限があるIAMのアクセスキー Secret key S3へのアクセス権限があるIAMのシークレットキー Endpoint https://s3.<S3のリージョン>.amazonaws.com Region S3のリージョン Bucket S3に作成したバケット名 データ接続設定 ワークベンチ作成 次にワークベンチを作成します。詳細は前回の記事の「 ワークベンチ作成 」を参考にしてください。データサイエンスプロジェクトの詳細画面からWorkbenchesに移動します。Create workbenchを押下して設定は以下のようにします: Name:test-workbench Notebook image Image selection:PyTorch Version selection:2024.1 Deployment size Container size:Small Accelerator:NVIDIA GPU(GPUがない場合None) Number of accelerators:1(GPUがある場合設定する) Cluster storage Create new persistent storage Name:test-workbench Persistent storage size:20Gi Data connections Use existing data connection Data connection:test-connection ワークベンチへのプログラムアップロード このリンクからプログラムをダウンロードしてください。 MLcode ダウンロードしたプログラムをJupyterLabにドラッグ&ドロップするとワークベンチにプログラムをアップロードできます。 プログラム動作 データの収集 0_dataupload.ipynbを実行します。データソースからMNISTの画像をダウンロードし、S3の/test-demo/dataディレクトリにアップロードします。 実行後、S3の/test-demo/dataディレクトリを確認すると、データがzipにまとめられて保存されているのが確認できます。 0_dataupload実行後のS3 データの準備 1_dataprocessed.ipynbを実行します。S3にあるMNISTの画像をダウンロードして、画像を学習に使える形に前処理します。その後、S3の/test-demo/processed_dataディレクトリにアップロードします。 実行後、S3の/test-demo/processed_dataディレクトリを確認すると、前処理済みデータがzipにまとめられて保存されているのが確認できます。 1_dataprocessed実行後のS3 モデルの学習 2_training.ipynbを実行します。S3にある前処理済みの学習データをダウンロードし、モデルの学習・推論を行い、学習後のモデルをS3の/test-demo/modelsディレクトリにアップロードします。その構成図を以下に示します: モデルの学習構成図 実行するとMNIST画像とその画像に対しての推論結果とAccuracy(正解率)が表示されます。表示されているMNIST画像は学習後のモデルに入力する推論用のデータです。推論結果は入力されたMNIST画像がどんな数字であるかモデルが推論した回答になります。Accuracy(正解率)は10000枚のMNIST画像をモデルが推論を行い、その推論した結果とMNISTの画像の数字が一致した確率を示しています。 モデルの推論・評価の結果 実行後、S3の/test-demo/modelsディレクトリを確認すると、モデルデータがONNX形式として保存されているのが確認できます。 2_training実行後のS3 最後に 以上の手順によりOpenShift AI内で実際に機械学習を行うことができました。このようにワークベンチ内のJupyterLab環境で自由にJupyterNotebookを実行することが可能です。さらにデータ接続機能を利用すると外部のストレージにアクセスも可能になります。ぜひOpenShift AIを利用してモデル開発に役立ててみてください。 参考 ワークベンチ設定: https://docs.redhat.com/ja/documentation/red_hat_openshift_ai_self-managed/2.13/html/working_on_data_science_projects/using-project-workbenches_projects#creating-a-workbench-select-ide_projects データ接続設定: https://docs.redhat.com/ja/documentation/red_hat_openshift_ai_self-managed/2.13/html/working_with_data_in_an_s3-compatible_object_store/index OpenShift AIチュートリアル不正検出の例: https://docs.redhat.com/ja/documentation/red_hat_openshift_ai_self-managed/2.13/html/openshift_ai_tutorial_-_fraud_detection_example/index 前回: OpenShift AIを導入してみた ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post OpenShift AIで機械学習をやってみた first appeared on SIOS Tech. Lab .
挨拶 ども!すごく良い調子で弊社開催の「 #2024アドベントカレンダー 」が進んでいます。内容としても様々な内容が投稿されていて、弊社の特徴が出ていて素晴らしいですね。 今期は、【Streamlit】【Qumcum】【AIエージェント】の3つを掛け合わせて、ロボットを操作するAIエージェントを作成しました。 2024-12-11 AIエージェントでロボットを制御する【langchain・Streamlit】 このデモの過程で、今回の内容がすごく面白いと感じたので注目して書いていきたいと思います。今回の内容は以下の通りです。 日本人が感覚で理解している「表現」を数値化する 生成AIでニュアンスを数値化する これまで、「文章から特定の評価に従って数値化」には時間と手間がかかっていました。生成AIを活用することで、プロンプトのみで数値化することができるようになっています。今回はサンプルとして検証した内容を公開していきます。 シンプルな数値化 とても単純な方法は、以下のようなプロンプトを入力すればよいです。 文章に含まれる、喜びの感情を1~100で数値化してください。 {{input}} 例えば、「とてもうれしい」という入力をChatGPTに投げかけてみます。 「とてもうれしい」に含まれる喜びの感情を1~100で数値化すると、98と評価できます。 理由: 「とても」という強調表現が、喜びの度合いを極めて高めているため、ほぼ最大値に近い値を割り当てます。 最大値である100を絶対的なピークとすると、「とてもうれしい」はそれに非常に近い表現と考えられます。 単純な数値のみでなく理由も返答されてきました。数値化した内容の利用用途に寄りますが、プロンプトで出力を制限することができます。 文章に含まれる、喜びの感情を1~100で数値化してください。 - 出力結果は数字のみにしてください。 {{input}} プロンプトに一行追加するだけで出力を数字のみに限定することができます。また、数値の範囲も範囲を変更することで判断して出力してくれます。 指標を追加する シンプルな方法で「喜び」の感情を数値化しました。ここでは、もう少し深堀していきたいと思います。シンプルな実装方法の場合だと、「とても」や「めっちゃ」などの表現が入っていれば、最大点となります。それを制限する方法は、以下のような手段が挙げられます。 例を与えて最大点を引き下げる:Few-Shot One-Shot 制限を追加する 例を与えて最大点を引き下げる方法 シンプルな実装では、「とても」や「めっちゃ」で最大点になります。プロンプト内でサンプルとして、採点した情報を与えることで最大点をずらすことができます。 文章に含まれる、喜びの感情を1~100で数値化してください。 - 出力結果は数字のみ 例は以下になります。 - とてもうれしい:20 {{input}} サンプルの数値を下げることで、判別の閾値を下げることができます。よく使われる表現などをまとめてサンプルとして与えてあげることで、よりサンプルの感覚に近い数値をはじき出せるようになります。 値を散らす方法に関しては、後輩が検証している記事があったので紹介しておきます。 2024-08-07 プロンプトでいかに5の倍数を出させないか 制限を追加する こちらの方法では、追加の制限を設けることで点数を散らす方法について紹介します。制限については以下のような内容から選択すると良いと思います。 よく使われる表現の場合は減点してください 面白い表現の場合は加点してください 古風な表現を用いた場合は加点してください 比喩表現は良いですね~加点しましょう 加点や減点の指標が衝突する可能性もあるので、制限をすべて追加するわけにはいきません。利用目的に即した制限を追加する必要があります。 個人的には「よく使われる表現の場合は減点してください」を追加するだけで評価指標が大きく変わるのが面白いですね。 文章に含まれる、喜びの感情を1~100で数値化してください。 - 出力結果は数字のみ - よく使われる表現の場合は減点してください {{input}} ニュアンス数値化を使ってみた 今回紹介した、数値化を行っているデモは二つ作成していました。軽ーく紹介しておきますね。 泳げ!進め!カツオくん このゲームでは、「音声認識」と「生成AI」をベースに考えたゲームになります。ゲーム内では、「感情」を数値化して活用しています。 文字列の長さで魚の位置を決定して障害物をよけて進みます。音声入力されたテキストを数値化し、スコアとして加点していくことで競うゲームですね。 ロボットを操作する:AIエージェント こちらは、「AIエージェント」「ロボット」をベースに考えたデモになります。デモでは、「表現」を数値化して活用しています。 こちらのデモでは、ユーザーの入力から内容をAIエージェントに処理してもらい、ロボットの出力として動作してもらいます。ダンスの項目では、生成AIの実行の結果として実行回数と実行スピードを受け取ることができます。 サンプルでは「日本舞踊のようなスピード」と「最高のスピード」とで実行してみました。結果としては、日本舞踊は「ゆっくり」と最高のスピードは「あらぶり」という結果になりました。 絶妙なニュアンスに関しても生成AIは拾うことができるので面白いです。 デモは、こちらにまとまっています。 終わり 今回は生成AIを使って、テキストからニュアンスを数値化する方法を紹介しました。プロンプトの工夫次第で、より精度の高い数値化が可能になることが分かりました。この技術を活用することで、様々な面白いアプリケーションが作れそうですね。これまでなかなか数値化しにくい業界にも入り込みやすくなりました。 ではまた! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post ChatGPTでニュアンスを数値化する first appeared on SIOS Tech. Lab .
はじめに 皆さんこんにちは。エンジニアの細川です。 今回はアドベントカレンダーで記事を書いてみたいと思います! テーマは「サイオス社員が今年一年で新たに学んだ技術」です! 今回はTypeScript界隈で注目されている!?Biomeについて紹介したいと思います! Biomeとは BiomeはTypeScriptやJavaScriptなどの言語のLinterとFormatterが一つになったようなツールです。ESLintやprettierなどは皆さん使われているかと思いますが、それらの代わりにBiome一つで、コードの静的解析を行ったり、成形をしてくれたりします。 BiomeはRustで動作しており、既存のESLintやprettierなどと比べてかなり高速に動作するみたいです。 導入方法 早速導入方法について紹介します。 まず、Biomeを以下のコマンドでインストールします。 npm install --save-dev --save-exact @biomejs/biome その後、以下のコマンドを叩くことで、Biomeの設定ファイルである biome.json が作成されます。 npx @biomejs/biome init デフォルトの設定で良い場合は作成不要とのことですが、作成しておくことをお勧めします。 これで基本的には導入完了です。 使い方 導入が完了すれば以下のコマンドでlinterやformatterを実行できます。 formatコマンドでファイルやディレクトリなどをformatできます。 npx biome format --write <files> lintコマンドを実行すると、コードの静的解析が行えます。 npx biome lint --write <files> また、writeオプションを利用すると、安全に修正可能な問題に対しては修正をしてくれます。詳細は こちら をご確認ください。 checkコマンドを利用すればlintとformat両方を実行できます。 npx biome check --write <files> それぞれ package.json に以下のように設定しておくと便利かと思います。 "scripts": { "lint": "biome lint src", "format": "biome format src", "check": "biome check src" }, 拡張機能 また、BiomeはVSCodeの拡張機能も存在しており、導入しておくことで、ルールにそぐわない場合にエラー表示を出してくれたり、保存時にformatをかけてくれたりするので、ぜひ導入しておくことをお勧めします。 こちら からインストールすることができます。 導入した後は Ctrl + Shift + P でコマンドパレットを開き、「format」と入力して表示される Format Document をクリックしてください。 その後既定のフォーマッターを構成からBiomeを選択しておくことで、その言語のデフォルトのフォーマッターでBiomeが使われるようになります。 また、VSCodeの設定を開き、saveで検索して出てくる Format On Save をONにしておけば、save時に自動でフォーマットしてくれるようになります。 運用 linterを導入しても、手でいちいちコマンドを叩くのがめんどくさいこともあるのではないでしょうか?また、叩き忘れがあったりなども多いため、自動でlinterが走るようにしたいこともあると思います。 僕のプロジェクトでは、lefthookと併用し、commit時に自動でlintコマンドを走らせることで叩き忘れ等を防止しています。 lefthookとはgitコマンドが実行される前後に自動で走るスクリプトを管理できるツールです。詳しくは公式の ドキュメント をご確認ください。 まず、以下のコマンドでlefthookをインストールします。 npm install @evilmartians/lefthook --save-dev その後、 .git が存在するディレクトリで以下のコマンドを叩きます。 lefthook install このコマンドを叩くことで、そのディレクトリにてlefthookが利用できるようになります。 lefthook.yml が生成されるはずなので、 pre-commit 部分に以下を追記します。 pre-commit: commands: glob: "*.{js,ts,jsx,tsx}" biome: run: npm run check <- biome checkなど実行したいコマンド これでcommit時に自動で biome check が走るようになります。 Biomeは動作も高速なので、そこまでストレスには感じずにチェックを行えるかと思います。 モノレポ設定について 一つのリポジトリでフロントとバックを両方管理するような場合もあるかと思います。 その場合、フロントとバックで共通のルールもあれば、このルールはバックエンドだけに適用したいなんて言うこともあるかと思います。 そのような場合、フロントとバックでそれぞれ biome.json を用意することで別々のルールを適用することができます( 参考 )。 ただし、この方法には一つ問題があります。それはVSCodeの拡張機能では現在開いているディレクトリに存在する biome.json しか認識してくれないという点です。 具体的には、例えば以下のような構成があったとします。 - root | - biome.json <- 共通の設定 | - front/ | - biome.json <- フロントのみの設定 | - src/ | - back/ | - biome.json <- バックのみの設定 | - src/ このときrootを開いて作業すると、フロントやバックに指定しているルールは拡張機能でエラー表示してくれず、クイックフィックスなども利用できません。 都度都度ディレクトリを開きなおせばいいのですが、フロントとバック横断して開発する場合などはいちいち開きなおすのが面倒なこともあると思います。 このような場合は、以下のように overrides を利用することで、フロントとバックのルールを一つにまとめることができます。 { "$schema": "https://biomejs.dev/schemas/1.8.0/schema.json", "formatter": { "indentStyle": "space", "indentWidth": 2 }, "organizeImports": { "enabled": true }, "linter": { "enabled": true, "rules": { "recommended": true // <- 全体に適用するルール } }, "overrides": [ { "include": ["backend/**"], "ignore": [ "backend/node_modules/**", "backend/dist/**", ], "linter": { "enabled": true, "rules": { // <- バックエンドのみに適用するルール "style": { "useImportType": "off" }, } }, "javascript": { "parser": { "unsafeParameterDecoratorsEnabled": true } } }, { "include": ["frontend/**"], "ignore": [ "frontend/node_modules", "frontend/dist", ], "linter": { "enabled": true, "rules": { // <- フロントエンドのみに適用するルール "nursery": { "noConsole": "error" } } } }, ] } デメリットとして設定ファイルが巨大化して少し読みづらくなるという点はありますが、僕のプロジェクトでは拡張機能の利便性の方を優先し、このような設定にしています。 Biomeのデメリット これまでBiomeのメリットや使い方等をお話ししてきましたが、Biomeには一つかなり大きな問題点があるかなと思います。 それはカスタムルールが設定できないという点です(このブログ執筆時点では方法を見つけられませんでした)。カスタムルールのためのプラグイン開発は進行中のようです( 参考 )。 そこで、Biomeで対応できないルールのみESLintでチェックを行うというような構成をお勧めします。 ESlintは以下のコマンドでインストールすることができます。 npm install --save-dev eslint そのあと eslinrc.js を作成します。(ymlやjsonでも設定ファイルを記述することができます。 こちら の記事で分かりやすく書いてくれていました。) module.exports = { parser: "@typescript-eslint/parser", parserOptions: { project: "tsconfig.json", tsconfigRootDir: __dirname, sourceType: "module", }, plugins: ["@typescript-eslint/eslint-plugin"], extends: ["plugin:@typescript-eslint/recommended"], root: true, env: { node: true, jest: true, }, ignorePatterns: [".eslintrc.js", "src/generated/*"], rules: { "@typescript-eslint/interface-name-prefix": "off", "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/explicit-module-boundary-types": "off", "@typescript-eslint/no-explicit-any": "off", //biomeがカバーしているルールを無効化 semi: "off", quotes: ["error", "double"], // ----------------↓Biomeで対応できないルールを追加----------------------- "no-restricted-syntax": [ "error", { // letを禁止 selector: "VariableDeclaration[kind='let']", message: "'let'は禁止です。代わりに'const'を使用してください。", }, ], }, }; 注意点としては、Biomeで設定しているルールとバッティングする内容についてはoffにしておくことです。 基本的なチェックはBiomeで行うので、pluginなどが無い方が簡潔になるかもしれません。 今回は例として、 let を禁止するルールを追加してみています。 後は、以下のコマンドを package.json に追加しておけばeslintも叩けるようになります。 "scripts": { "lint:es": "eslint --ext .ts src", ... } ESLintはBiomeに比べると実行に時間がかかるので、僕のプロジェクトではcommit時のチェックはせずに、PR作成時にCIで回るようにしています。 このあたりは皆さんのプロジェクトに合わせて調整してください。 まとめ Biomeはlinterとformatterが一つになったツール lint npx biome lint --write <files> format npx biome format --write <files> lint + format npx biome check --write <files> VSCodeの拡張機能を導入すればエラー表示&自動フォーマット可能 lefthookと併用することでcommit時に自動チェック フロント、バックなどでルールを分けたい場合は overrides を利用 overrides を利用することでVSCodeの拡張機能も問題なく利用できる! Biomeで設定できないルールはESLintでチェック おわりに 今回は、Biomeについて紹介しました。基本的には設定も簡単で動作も早く、かなりお勧めなツールになります。ただ、カスタムルールを設定できないという弱点もあるので、その場合はぜひESLintと併用するという方法も試していただければと思います! 今後もお勧めの構成などがあれば紹介していきたいと思います! 他にも今月は アドベントカレンダー で様々な記事が投稿されると思うのでぜひチェックしてみてください。 今回参考にさせていただいた記事 https://biomejs.dev/ja/guides/getting-started/ https://qiita.com/howdy39/items/6e2c75861bc5a14b2acf https://blog.solunita.net/posts/change-lefthook-instead-of-lintstaged-with-husky/ ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post linterとformatterが一つに!?Biome使ってみた first appeared on SIOS Tech. Lab .
こんにちはアプリチームの織田です  先日、12月7日に開催された OSC福岡 で、初めてセミナーに登壇するという貴重な経験をしてきました。今回の私の発表テーマは「生成AI」です。生成AIの基礎知識を中心に、これからこの分野に触れる方々にもわかりやすく、その魅力や可能性をお伝えすることを目指しました。このブログではセミナーの内容や登壇しての感想を少し詳しくまとめたいと思います。セミナーで用いた資料は コチラ から閲覧できます。また、今回のOSCでの展示は別の ブログ記事 にて紹介していますので、是非そちらもご覧ください。   セミナーの目的 発表の目的は、生成AIについてあまり詳しくない方にも、その魅力や利便性をわかりやすく伝えることでした。生成AIがどんなことができるのか、具体的なイメージを持ってもらうことで、興味を持ってもらい、理解を深めてもらいたいと考えていました。 また、私の発表の後には、武井さんや山崎さんによるAIエージェント、AIロボットに関する発表がありました。これらの発表は、生成AIの知識を前提とした、より発展的な内容でした。そのため、私の発表では、これらの発表を理解するために必要な基礎知識を、わかりやすく提供することも目的の一つでした。   セミナーの概要 セミナーは、デモセッションからスタートしました。細かな説明の前に様々な生成AIツールの動きを実際に見てもらい、この後の話が聞きやすくなることを狙いました。デモの内容としては、ChatGPTを使ったアイデア出し、Geminiによる誤字検出、AIイラストメーカーによるイラスト生成など、生成AIツールの具体的な活用事例を、実際に動かしながら紹介しました。生成AIがどんなことができるのか、その可能性を直感的に理解してもらえたのではないかと思います。  次に、生成AIの概要を説明しました。ここでは、まず従来のAIと生成AIの違いを明確にし、それぞれの得意分野や活用例を挙げながら、生成AIが持つ「創造性」という新たな可能性を強調しました。続いて、生成AIの強みとして、コンテンツ制作の効率化や、新しいアイデアの創出などを紹介しました。 しかし、その一方で、生成AIを利用する上での注意点も詳しく解説しました。特に、生成AIが生成するコンテンツは、必ずしも正確であるとは限らないという点について、具体的な例を挙げて説明しました。また、生成AIが生成したコンテンツの著作権や、倫理的な問題についても言及し、利用者自身が責任を持ってこれらの問題に対処する必要があることを強調しました。 最後に、「生成AIはあくまでツールである」という点を強調し、その出力結果を鵜呑みにせず、常に自身の知識や判断力を働かせることの重要性を伝えました。生成AIの持つ可能性を最大限に活かしつつ、その限界やリスクも理解した上で、適切に利用していくことの重要性を訴えました。 最後に大規模言語モデル(LLM)の説明を行いました。LLMの説明を行う際には、生成AIとLLMの関係性が伝わりづらくなるだろうと思い、図解を用いて整理しました。また、LLMでできること、LLM単体ではできないことについての説明も実施しました。例えば、LLMは最新の情報や非公開の情報にはアクセスできないという限界があります。このような点を理解した上で、LLMを活用していくことが重要であることを伝えました。また、これらの課題を克服するためには、LLMを他の技術やシステムと組み合わせることが必要であり、それが次のセッションで紹介される「AIエージェント」へとつながることを示唆しました。このように、LLMの解説を通じて、生成AIの理解を深めると同時に、AIエージェントへのスムーズな橋渡しとなるように配慮しました。   感想 今回でOSCへの参加は2回目となりましたが、今回は初めて登壇という形で参加させていただきました。初めての登壇のため非常に緊張していましたが、参加者の皆さんの熱心な様子を見て、私も楽しく発表することができました。質疑応答の時間には、多くの質問が寄せられ、生成AIに対する関心の高さを改めて実感しました。私自身も、参加者の皆さんから多くの刺激を受け、大変有意義な経験となりました。 発表後には自社のブースの宣伝を行ったところ、聴講してくださった方がブースにも足を運んでくださったようで、嬉しかったです。また、企業の方から「社内向けの生成AIセミナーの参考になった」という嬉しいお言葉をいただきました。 初めての登壇ということもあり、反省点もいくつかあります。例えば、もう少しイラストや図解を多用することで、視覚的な理解を促すことができたかもしれません。また、クイズ形式の時間を設けるなど、参加型の要素を取り入れることで、より楽しく、記憶に残る発表にすることができたのではないかと感じています。 今回の経験を活かし、今後も技術に関する知識や情報を積極的に発信していきたいと考えています。また、次回登壇する機会があれば、さらにわかりやすく、興味深い発表ができるよう工夫していきたいと思います。 それでは、最後までお読みいただきありがとうございました。 当日のセミナーの様子。学生さんが大変多く聴講に来てくださいました。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 2024年OCS福岡_生成AIに関するセミナー登壇の感想 first appeared on SIOS Tech. Lab .
こんにちは、伊藤です。 今回は、Apache HTTPとApache Tomcatを連携するWebサーバの構築手順について紹介します。 連携Webサーバの利点 Apache HTTPはHTTPの処理(リクエストとレスポンス)に優れており、Apache TomcatではJAVAの実行処理(動的処理)が可能です。これらを組み合わせることで応答性を担保した動的Webアプリケーションを構築することができます。 Apache HTTPでは複数のドメインで別々のWebサイトを提供することができます。利用者と管理者それぞれにWebサイトを提供したい場面があったため、今回はその設定をApache Tomcatのサンプルページを利用して紹介します。 使用環境 構築時に利用した環境は以下です。 Rocky Linux 9.2 また、クライアントPCからWebサーバに対してhttp, https通信ができるようにしておく必要がありますが、今回は割愛します。 ソフトウェアインストール 以下のソフトウェアをインストールします。 Apache HTTP Apache HTTP SSLモジュール Apache Tomcat OpenJDK Apache HTTPのインストール Apache HTTPをインストールし、バージョンを確認します。 $ sudo dnf -y install httpd $ httpd -v Server version: Apache/2.4.62 (Rocky Linux) Server built: Aug 3 2024 00:00:00 Apache HTTP SSLモジュールのインストール Apache HTTP SSLモジュールをインストールし、バージョンを確認します。 $ sudo dnf -y install mod_ssl $ rpm -aq | grep mod_ssl mod_ssl-2.4.62-1.el9.x86_64 Apache Tomcatのインストール Apache Tomcatをインストールし、バージョンを確認します。 $ sudo dnf -y install tomcat $ tomcat version Server version: Apache Tomcat/9.0.87 Server built: Jan 10 1970 04:21:54 UTC Server number: 9.0.87.0 OS Name: Linux OS Version: 5.14.0-284.11.1.el9_2.x86_64 Architecture: amd64 JVM Version: 11.0.25+9-LTS JVM Vendor: Red Hat, Inc. OpenJDKをインストール OpenJDKをインストールし、バージョンを確認します。 $ sudo dnf -y install java-17-openjdk $ java -version openjdk version "17.0.13" 2024-10-15 LTS OpenJDK Runtime Environment (Red_Hat-17.0.13.0.11-1) (build 17.0.13+11-LTS) OpenJDK 64-Bit Server VM (Red_Hat-17.0.13.0.11-1) (build 17.0.13+11-LTS, mixed mode, sharing) Webアプリケーションのダウンロード dnfでインストールした場合Apache TomcatのWebアプリはダウンロードされないため、Tomcatが提供するWebアプリ(ドキュメント集や管理者用Webアプリ)をダウンロードサイトからダウンロードします。ダウンロード対象フォルダはwebapps配下のフォルダです。ダウンロードしたフォルダはWebサーバのtomcat/webapps配下に配置します。 「ROOT」ディレクトリはドキュメントルート「/」のwebページの配置場所となりますが、今回は使用しないため、ディレクトリ名を「ROOT」から「home」に変更します。 ダウンロードサイト: https://tomcat.apache.org/download-90.cgi Apache Tomcatのサンプルwebアプリ用ファイル(sample.war)もダウンロードします。sample.warファイルをtomcat/webapps配下に配置します。配置するとsampleディレクトリが自動生成されます。 ダウンロードサイト: https://tomcat.apache.org/tomcat-7.0-doc/appdev/sample/ Webアプリの配置を確認します。 $ ls /usr/share/tomcat/webapps/ docs examples home host-manager manager sample sample.war 自己署名証明書の作成 検証用の自己署名証明書を作成します。自己署名証明書は信頼されていないため、本番環境での使用は推奨されていません。本番環境では認証局(CA)から発行された証明書を使用してください。今回はSAN付き自己署名証明書の作成方法 1 を参考にして、複数のWebサイトに対応するSubject Alternative Name (SAN) 付き証明書を作成します。 秘密鍵の作成 秘密鍵を(server.key)作成します(RSA4096ビット長)。 $ sudo openssl genpkey -algorithm RSA -out /etc/pki/tls/private/server.key -pkeyopt rsa_keygen_bits:4096 署名リクエストの作成 署名リクエスト(server.csr)を作成します。 $ sudo openssl req -new -key /etc/pki/tls/private/server.key -out /etc/pki/tls/certs/server.csr 署名リクエストで以下の質問に回答します。 Country Name (2 letter code) [XX]:JP State or Province Name (full name) []:Tokyo Locality Name (eg, city) [Default City]:Minato-ku Organization Name (eg, company) [Default Company Ltd]:Example Inc. Organizational Unit Name (eg, section) []:Example section Common Name (eg, your name or your server's hostname) []:example.com Email Address []:admin@example.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: 署名リクエストを確認します。 $ openssl req -text -in /etc/pki/tls/certs/server.csr -noout Certificate Request: Data: Version: 1 (0x0) Subject: C = JP, ST = Tokyo, L = Minato-ku, O = Example Inc., OU = Example section, CN = example.com, emailAddress = admin@example.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (4096 bit) …<省略>… 証明書の作成 SANを記述したファイル san.txtを作成します。 $ vim san.txt subjectAltName = DNS:example.com, DNS:manager.example.com, DNS:user.example.com 証明書(server.crt)を作成します(有効期限約10年間)。 $ sudo openssl x509 -in /etc/pki/tls/certs/server.csr -out /etc/pki/tls/certs/server.crt -req -signkey /etc/pki/tls/private/server.key -days 3650 -extfile san.txt 証明書を確認します。 $ openssl x509 -text -in /etc/pki/tls/certs/server.crt -noout Certificate: Data: Version: 3 (0x2) Serial Number: 17:76:19:47:c7:0f:0b:fe:ff:b9:33:ec:21:3e:1f:83:e0:1b:8a:9a Signature Algorithm: sha256WithRSAEncryption Issuer: C = JP, ST = Tokyo, L = Minato-ku, O = Example Inc., OU = Example section, CN = example.com, emailAddress = admin@example.com Validity Not Before: Dec 6 02:42:24 2024 GMT Not After : Dec 4 02:42:24 2034 GMT Subject: C = JP, ST = Tokyo, L = Minato-ku, O = Example Inc., OU = Example section, CN = example.com, emailAddress = admin@example.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (4096 bit) …<省略>… X509v3 extensions: X509v3 Subject Alternative Name: DNS:example.com, DNS:manager.example.com, DNS:user.example.com …<省略>… Apache HTTPの設定 HTTPの設定 HTTPの設定(/etc/httpd/conf/httpd.conf)です。下記の設定を行います。各種設定は、Virtual Hostの設定 2 、SSLモジュールの設定 3 、Mozilla SSL Configuration Generator 4 を参考にしました。 ディレクトリ一覧表示を禁止する設定 Virtual Hostの設定 Tomcatへの転送設定 SSLの設定 httpからhttpsへのリダイレクト設定 $ sudo vim /etc/httpd/conf/httpd.conf Listen 80 Listen 443 …<省略>… ServerName example.com:443 …<省略>… Options FollowSymLinks # Indexesを削除してディレクトリ一覧表示を禁止する …<省略>… # manager.example.com <VirtualHost *:443> # Webサーバ名 ServerName manager.example.com # SSL設定 SSLEngine on SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH SSLHonorCipherOrder on SSLCertificateFile /etc/pki/tls/certs/server.crt SSLCertificateKeyFile /etc/pki/tls/private/server.key SSLCompression off SSLSessionTickets off # リクエスト転送設定 <Location "/home"> ProxyPass ajp://127.0.0.1:8009/home </Location> <Location "/manager"> ProxyPass ajp://127.0.0.1:8009/manager </Location> <Location "/host-manager"> ProxyPass ajp://127.0.0.1:8009/host-manager </Location> <Location "/docs"> ProxyPass ajp://127.0.0.1:8009/docs </Location> <Location "/examples"> ProxyPass ajp://127.0.0.1:8009/examples </Location> </VirtualHost> # user.example.com <VirtualHost *:443> # Webサーバ名 ServerName user.example.com # SSL設定 SSLEngine on SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH SSLHonorCipherOrder on SSLCertificateFile /etc/pki/tls/certs/server.crt SSLCertificateKeyFile /etc/pki/tls/private/server.key SSLCompression off SSLSessionTickets off # リクエスト転送設定 <Location "/sample"> ProxyPass ajp://127.0.0.1:8009/sample </Location> </VirtualHost> <VirtualHost *:80> # httpでアクセスした場合はhttpsに書き換える RewriteEngine On RewriteCond %{REQUEST_URI} !^/\.well\-known/acme\-challenge/ RewriteRule ^.*$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,QSA,L] </VirtualHost> SSLの設定 SSLを設定します(/etc/httpd/conf.d/ssl.conf)。 $ sudo vim /etc/httpd/conf.d/ssl.conf #Listen 443 …<省略>… # SSL設定 SSLCertificateKeyFile /etc/pki/tls/private/server.key SSLCertificateFile /etc/pki/tls/private/server.crt テストページの無効化 Apache HTTPのテストページ(/etc/httpd/conf.d/welcome.conf)をコメントアウトして無効化します。 $ sudo vim /etc/httpd/conf.d/welcome.conf # # This configuration file enables the default "Welcome" page if there # is no default index page present for the root URL. To disable the # Welcome page, comment out all the lines below. # # NOTE: if this file is removed, it will be restored on upgrades. # #<LocationMatch "^/+$"> # Options -Indexes # ErrorDocument 403 /.noindex.html #</LocationMatch> …<省略>… Apache Tomcatの設定 サーバ設定 Apache Tomcatサーバを設定します(/usr/share/tomcat/conf/server.xml)。http1.1通信無効化とlocalhostの8009番ポートからの※AJP1.3 通信を受け付けています。 …<省略>… <!-- <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" maxParameterCount="1000" /> --> …<省略>… <Connector protocol="AJP/1.3" address="127.0.0.1" port="8009" redirectPort="8443" maxParameterCount="1000" secretRequired="false" /> ※AJP (Apache JServ Protocol):Apache tomcat 通信プロトコル 参考:ApacheとTomcatの連携 5 環境設定 Apache Tomcatの環境を設定します(/usr/share/tomcat/conf/tomcat.conf)。 Apache TomcatとJavaのディレクトリがデフォルトから異なる場合は設定の変更が必要です。 以下はデフォルト設定となります。 # Where your java installation lives JAVA_HOME="/usr/lib/jvm/jre" # Where your tomcat installation lives CATALINA_HOME="/usr/share/tomcat" 管理者用Webアプリの設定 管理者用Webアプリを設定します(/usr/share/tomcat/conf/tomcat-users.xml)。 ここでは、管理者用Webアプリのログイン情報を設定します。 managerを含むロール名はmanagerアプリに、adminを含むロール名はhost-managerアプリに対応します。 以下の例ではadminユーザはmanagerアプリとhost-managerアプリに、managerユーザはmanagerアプリにログインできます。 $ sudo vim /usr/share/tomcat/conf/tomcat-users.xml <role rolename="admin"/> <role rolename="admin-gui"/> <role rolename="admin-script"/> <role rolename="manager"/> <role rolename="manager-gui"/> <role rolename="manager-script"/> <role rolename="manager-jmx"/> <role rolename="manager-status"/> <user name="admin" password="admin_password" roles="admin,manager,admin-gui,admin-script,manager-gui,manager-script,manager-jmx,manager-status" /> <user name="manager" password="manager_password" roles="manager,manager-gui,manager-script,manager-jmx,manager-status" /> </tomcat-users> 名前解決設定 FQDNでWebサーバにアクセスできるようにするために名前解決を設定します。今回はクライアントPC(Windows)のhostsファイルを編集します。 C:\Windows\System32\drivers\etc\hosts <WebサーバのIPアドレス> user.example.com <WebサーバのIPアドレス> manager.example.com サービス起動・自動起動有効化 Apache HTTPとApache Tomcatのサービス起動および自動起動を有効化します。 $ sudo systemctl start httpd $ sudo systemctl enable httpd $ sudo systemctl start tomcat $ sudo systemctl enable tomcat Webサイト確認 FirefoxでWebページにアクセスします。 アクセスする際には自己署名証明書のために警告が発生しますが、このまま使用します。 管理者側Webサイト 管理者側Webサイトにアクセスできることを確認します。 https://manager.example.com/home ここで「Manager App」を選択し、管理者用Webアプリ設定(tomcat-users.xml)のユーザー名とパスワードを入力します。 https://manager.example.com/manager にアクセスできることを確認します。 https://manager.example.com/home で「Host Manager」を選択し、管理者用Webアプリ設定(tomcat-users.xml)のユーザー名とパスワードを入力した後に「Host Manager」にアクセスできることを確認します。 https://manager.example.com/home で「Documentation」を選択し、ドキュメントページにアクセスできることを確認します。 利用者側Webサイト 利用者側Webサイトにアクセスできることを確認します。 https://user.example.com/sample/ さいごに 今回は、Apache HTTPとApache Tomcatを連携するWebサーバの構築手順について紹介しました。 サーバの構築において少しでも参考になれば幸いです。 参考 SAN付き自己署名証明書: https://qiita.com/nis_d1ce1984/items/b8f87d41ea108d47af61 ︎ Virtual Hostの設定: http://httpd.apache.org/docs/2.4/en/vhosts/name-based.html ︎ SSLモジュールの設定: https://httpd.apache.org/docs/2.4/ja/mod/mod_ssl.html ︎ Mozilla SSL Configuration Generator: https://ssl-config.mozilla.org/ ︎ ApacheとTomcatの連携: https://qiita.com/xyz666/items/387251d0aee41a25fec1 ︎ ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Apache HTTPとApache Tomcatを連携するWebサーバを構築してみた first appeared on SIOS Tech. Lab .
こんにちはアプリチームの織田です 12月7日に開催された OSC福岡 に参加してきました。前回の広島に続き面白かった展示の紹介を行いたいと思います。前回のブログは コチラ から閲覧できます。   Japanese Raspberry Pi Users Group Japanese Raspberry Pi Users Group さんは、Raspberry Piを駆使した様々なプロジェクトを展開しているコミュニティです。こちらの展示では、リアルタイム物体検出機能を備えた革新的な小型カメラに興味をひかれました。 このカメラの最大の特徴は、動画撮影と物体検出のプロセスを同時に行える点にあります。従来の物体検出システムでは、撮影した動画をRaspberry Pi本体やクラウド上で処理する必要がありました。しかし、この小型カメラは検出処理をカメラ側で完結させることで、Raspberry Piへの負荷を大幅に軽減し、リアルタイムでの物体認識を可能にしています。結果として、遅延の少ないスムーズな物体検出を実現しています。 この技術の応用範囲は幅広く、特にドローンやロボットといった、瞬時の判断と動作が求められる分野での活躍が期待できるかと感じました。例えば、ドローンによる空撮中にリアルタイムで障害物を検知し、自動で回避するといった機能の実装が可能になります。 Japanese Raspberry Pi Users Groupさんの展示は、Raspberry Piの可能性をさらに広げる、革新的な技術の一端を垣間見せてくれるものでした。 ラズベリーパイと物体検出を行うカメラ(ソニーIMAX500)   さくらインターネット さくらインターネット さんは、サーバーレンタル事業を展開している企業で、特に学生や研究者にとって馴染み深い存在です。今回のOSC福岡では、新しいレンタルGPUサーバープランの紹介をされていました。 従来のプランは月額課金制で、その費用は200万円から300万円程度と高額でした。これは主に企業や団体をターゲットにしたもので、個人や研究室にとっては利用のハードルが高いものでした。しかし、今回発表された新プランは、実際にGPUを使用した時間単位での課金となるため、大幅なコスト削減が可能となりました。具体的には、モデルの種類によって価格は変動しますが、1秒あたり0.06円や0.28円といった低価格での利用が可能となっています。この従量課金制により、必要な時に必要な分だけGPUを利用できるため、「ちょっとGPUサーバー触ってみたいな~」というライトユーザーからヘビーユーザーまで、幅広い層にとって魅力的な選択肢となっています。 私自身、大学時代には研究室でGPUサーバーを利用していましたが、他のユーザーが高負荷な処理を実行すると、自分の作業に支障が出るという問題がありました。しかし、このレンタルGPUサーバーを利用すれば、そのような問題を解消し、より快適な研究環境を実現できるのではないかと期待しています。 さくらインターネットさんの新プランは、GPUを利用したいと考えている個人や研究者にとって、非常に魅力的な選択肢となるのではと感じました。これにより、GPUを使った研究や開発がより身近なものとなり、新たなイノベーションが生まれる可能性も広がると期待されます。 さくらインターネットさんの展示ブースの様子 Divers Project  Divers Projectさんは、移動困難者が安心して街を歩けるよう、バリアフリールートを共有するアプリを開発している学生団体です。OSC福岡の展示では、開発中のアプリの詳細について紹介されていました。 このアプリの最大の特徴は、ユーザーが実際に歩いたバリアフリーな道の情報を共有できる点にあります。一般的な地図アプリでは、段差や狭い通路などの情報は表示されず、バリアフリーマークがあっても、実際に車椅子で通行できるかは分かりません。このアプリは、そうした課題を解決するために、ユーザーが実際に体験した情報を共有することで、本当にバリアフリーなルートを見つけ出すことを目指しています。 展示では、アプリのデモ画面や機能の説明があり、実際にどのようにルートを共有し、検索できるのかを体験することができました。また、開発チームのメンバーが、アプリに込めた思いや今後の展望について熱心に語っていました。彼らの「移動困難者がもっと自由に街を歩けるようにしたい」という強い思いが伝わってくる展示でした。 このアプリが普及すれば、移動困難者が安心して外出できるようになり、社会全体のバリアフリー化が進むことが期待されます。Divers Projectさんの活動は、まさに「多様な人々が共に生きる社会」を実現するための重要な一歩だと感じました。また、学生団体さんが積極的にこうした課題解決を行っている様子から非常に活力をもらいました。 Divers Mapの説明用ポスター 南島原市DX推進コンソーシアム 南島原市DX推進コンソーシアムさんの展示は、アスパラガスの等級判定を自動化するシステムの紹介でした。アスパラガスの等級は、その先端部分の形によって決まるのですが、従来はこの選別作業を手作業で行っていたため、多くの時間と労力を要していました。 このシステムでは、アスパラガスの画像を撮影し、画像処理技術を用いて先端部分の形を分析することで、等級を自動的に判定します。具体的には、撮影された画像を白黒に変換し、アスパラガスの輪郭を抽出します。そして、その輪郭情報をもとに、アスパラガスの先端部分の形を数値化し、あらかじめ設定された基準と照らし合わせることで、等級を判定します。 展示では、実際にアスパラガスをカメラにかざして、等級を判定するデモが行われていました。このシステムの導入により、選別作業の効率化だけでなく、判定の精度向上も期待できるため、アスパラガス農家の生産性向上に大きく貢献することが期待されます。 このシステムを見た感想としては、アスパラガスだけでなく、他の農作物の等級判定にも応用できるのではないかと感じました。 余談ですが、展示に足を運んだ際に、南島原市特産のそうめんをいただきました。大変美味しいそうめんでした、ありがとうございました。 ブースで実際にアスパラガスの等級判断をしている様子 TOPPERSプロジェクト TOPPERSプロジェクトさんの展示では、耕運機の自動運転技術の開発に焦点を当てていました。プロジェクトの目的は、中山間地における耕作放棄地の増加という深刻な問題に対処することです。中山間地では、狭くて段差のある土地が多く、大型のトラクターでの耕作が困難なケースが頻繁に見られます。一方、耕運機はそうした悪条件下でも作業が可能ですが、農業従事者の高齢化と人手不足が深刻化しているため、手動での耕運機の操作も困難になってきています。そこで、TOPPERSプロジェクトさんは耕運機の自動運転技術を開発することで、この問題の解決を目指しています。 展示では、実際に自動運転のテストを行っている様子を撮影した動画が紹介されていました。動画を見る限り、耕運機は左右の方向転換を含めて自律的に走行しており、実用化に向けて着実に進展している印象を受けました。TOPPERSプロジェクトさんの取り組みは、耕作放棄地の再生だけでなく、農業における労働力不足の解消にも大きく貢献することが期待されます。今回提案された技術が、中山間地の農業を活性化し、持続可能な農業を実現するための鍵となるかもと感じました。 プロジェクト内容をまとめたポスター   感想 今回のOSC福岡も、様々な団体や企業による興味深い展示が多く、非常に刺激的なイベントでした。特に、Raspberry Piを使ったリアルタイム物体検出カメラや、さくらインターネットの従量課金制GPUサーバー、そしてバリアフリー情報共有アプリやアスパラガス等級判定システムなど、社会の課題解決に貢献するような展示が多く見られました。 これらの展示を見て、テクノロジーの進化が私たちの生活をより便利に、そして豊かにする可能性を改めて感じました。同時に、学生団体が積極的に技術を活用し、社会課題の解決に取り組んでいる姿に感銘を受けました。 今後もOSCのようなイベントを通じて、最新の技術動向に触れ、多くの人々と交流を深めていきたいと考えています。そして、私自身も技術者として、社会に貢献できるようなサービスやプロダクトの開発に携わっていきたいと改めて感じました。 最後に、OSC福岡の関係者の皆様、そして展示に参加された皆様、本当にありがとうございました。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 2024年OSC福岡_展示内容紹介 first appeared on SIOS Tech. Lab .
はじめに 前回の記事では、Terraformを使用してAWS上にEC2インスタンスを構築し、RKE2を用いてKubernetesクラスターとRancher Serverをセットアップする手順を解説しました。 今回の記事では、前回構築したRancherを活用して、複数のKubernetesクラスターを管理する方法を紹介します。 本記事の内容 RancherからEKSクラスターを作成する方法 既存のKubernetesクラスターをRancherにインポートする方法 RancherでNode数を管理する方法 RancherからKubernetesクラスターをアップグレードする方法 RancherのGUIからnginxをデプロイする方法 概要 本記事では、Rancherのダッシュボードを活用して、複数クラスターの構築・管理を行う手順を説明します。 前提条件 Rancher Serverが構築済みであること Rancherのダッシュボードにログインできていること 構築イメージ 複数クラスターの構築イメージは以下のようになります。管理対象クラスターのセットアップ方法は後ほど解説します。 管理対象クラスターの追加 RancherからEKSクラスターを作成 Rancher Serverにログインし、ホーム画面のサイドバーからクラスター管理画面( Cluster Management )に移動します。 まずはRancherからAWS環境にアクセスできるよう、AWSの認証情報を登録します。 Cloud Credentialsを選択して、クラウドの認証情報を管理する画面に遷移します。 Createを選択し、クラウドプロバイダーの選択画面に遷移します。 Amazonを選択し、AWSのクレデンシャル情報を入力します。なお、今回使用するAWSのIAMユーザーにはAdministrator Access権限をアタッチしています。 Credential Name: 任意の名称 Access Key: アクセスキー Sercret Key: シークレットキー AWSの認証情報を保存します。これでRancherからAWSアカウント上のリソースを操作できるようになりました。 続いて、クラスター作成メニュー画面でAmazon EKSを選択します。 クラスター初期設定画面で必要な項目を入力し、Createを押下します。 クラスター名 リージョン:us-east-1を選択 Kubernetes Version: 1.30 ※1 Instance Type: t3.medium スケール設定 Desired ASG Size: 2 Minimum ASG Size: 2 Maximum ASG Size: 2 ※1: あとでRancherのダッシュボードからクラスターのアップグレードをするため、最新よりひとつ前のバージョンを選択しています。 クラスターの作成が完了したら、サイドバーからEKSクラスターのダッシュボードに遷移します。 Nodeを選択すると、クラスター内のNodeの情報を閲覧できます。 これでEKSクラスターの構築が完了しました。このように、Rancherのダッシュボードから簡単にEKSクラスターを構築することができます。また、構築後もRancherの画面UIからNodeを操作することができます。 既存のKubernetesクラスターをRancherにインポートする クラスターの概要 今回は、以下の構成でKubernetesクラスターを構築し、Rancherにインポートします: Control Plane:3台 Worker Node:2台 既存のKubernetesクラスターをRancherにインポートすることで、Rancherの管理下で監視・操作が可能になります。 前提条件 Terraformを利用して、以下の設定を含むEC2インスタンスを5台デプロイします: OS:Ubuntu 24.04 各インスタンスのセキュリティグループ設定が完了していること(ポート443, 9345などが開放済み) Terraformのコードは こちら を使用します。 Kubernetesディストリビューションは前回同様RKE2を使用します。 Terraformを実行し、AWS上にリソースを作成します: $ terraform init $ terraform apply 1. Control Planeの構築 Control Planeの構築手順は前回の記事で詳しく説明しています。 以下をご参照ください: RKE2でControl Planeを構築する方法 2. Worker Nodeの構築 ここでは、Worker Nodeを追加する手順を解説します。 参考: 公式ドキュメント(Linux Agent (Worker) Node Installation) Worker Node用にデプロイしたEC2インスタンスにSSHでログインします: IPアドレスはTerraformのoutput「worker_node_public_ips」に出力されます。 $ ssh -i <YOUR_INSTANCE_KEY> ubuntu@<WORKER_NODE_PUBIC_IP> RKE2エージェントのインストール 以下のコマンドを実行して、RKE2エージェントをインストールします: $ curl -sfL https://get.rke2.io | sudo INSTALL_RKE2_TYPE="agent" sh - $ sudo systemctl enable rke2-agent.service RKE2エージェントの設定 設定ファイルを作成し、Control Planeと接続するための情報を記述します: $ sudo mkdir -p /etc/rancher/rke2/ $ sudo vi /etc/rancher/rke2/config.yaml 設定内容(例): server: https://<NLB_DNS_NAME>:9345 token: <TOKEN_FROM_SERVER> ※TOKEN_FROM_SERVERはControl Planeで設定したtokenと同じ Worker Nodeを起動します。 $ sudo systemctl start rke2-agent.service ノードの状態確認 Control Plane用のインスタンスにSSHでログインし、ノードの状態を確認します。 $ kubectl get nodes Worker Nodeが正常に表示されれば、クラスターの構築は完了です。 3. Rancherにクラスターをインポートする 構築したKubernetesクラスターをRancherにインポートします。 Rancher UIにアクセスし、サイドバーからクラスター管理画面に遷移します。 Import Existingを選択します。 Cluster Import画面で「Generic」を選択します。 クラスター名を入力し、Createボタンを押下します。 クラスターを構築したEC2インスタンスにSSHでログインし、RancherのUI画面に表示されたkubectl applyコマンドを実行してください。 $ kubectl apply -f <AUTO_GENERATED_MANIFEST> Rancherは管理対象クラスターを識別するために、cluster-agentというエージェントを利用します。このエージェントは、RancherのUIで自動生成されるマニフェストを対象クラスターに適用することで起動します。 cluster-agentが正常に起動すると、Rancherはcluster-agentを通じてクラスターを認識します。Rancherのサイドバーからクラスターの詳細画面に遷移できるようになります。 Nodesを選択すると、事前に作成した通り、Control Planeが3台、Worker Nodeが2台稼働していることを確認できます。これで、KubernetesクラスターをRancherにインポートして、クラスターを管理できるようになりました。 Rancherを使ったクラスター管理 Node数の調整 連携したKubernetesクラスターをRancherの画面上から操作してみます。 サイドバーからクラスター管理画面に遷移し、先ほど作成したEKSクラスターを選択します。 Edit Configを選択してクラスター設定の編集画面に遷移します。 Node Groupsのgroup1でAutoScalingGroupのスケール数を引き上げて保存します。すると、クラスターの更新が開始されます。 Desired ASG Size: 5 Maximum ASG Size: 5 クラスター更新完了後、全てのNodeがActive状態になったことを確認します。 これで、Rancherの操作画面からクラスターのNode数を増やすことができました。 続いて、増やしたNode数を減らしてみます。 先ほどと同じ手順でEKSクラスターのクラスター設定編集画面に遷移し、今度はASGのスケール数を引き下げます。 Desired ASG Size: 3 クラスター更新完了後、指定したDesired Sizeの数までNode数が減少したことを確認します。 このように、Rancherからクラスター内で稼働するNode数を調整することが可能です。 ※Node数の調整はRancherのUIから作成したクラスターのみ利用可能です。インポートしたクラスターはRancherから操作できないため、Node数を増減させることができません。 公式ドキュメント: Node Options Available for Each Cluster Creation Option クラスターのアップグレード EKSクラスターのアップグレード RancherからKubernetesクラスターのバージョンをアップグレードすることができます。 サイドバーからクラスター管理画面に遷移し、EKSクラスターのEdit Configを選択します。 編集画面内のプルダウンからKubernetesの新しいバージョンを指定して保存します。 クラスターの更新が開始されます。バージョンアップ完了までおよそ10分ほどかかります。 AWSのマネジメントコンソールでEKSの画面に遷移すると、EKSクラスターが更新状態になっていることを確認できます。 クラスターの更新が完了すると、EKSクラスターのバージョンが1.31に更新されていることが確認できます。 インポートしたクラスターのアップグレード 続いて、先ほどインポートしたクラスターもアップグレードしてみます。 EKSクラスターの時と同じ手順で、クラスター管理画面のEdit Configからクラスター設定情報の編集画面に遷移します。 編集画面でKubernetesの新しいバージョン(今回は1.31)を選択して保存します。 クラスターの更新が完了すると、Kubernetes Versionの表示が指定したバージョンに更新されていることが確認できます。これで、インポートしたクラスターのアップグレードは完了です。 このように、Rancherを利用すれば、Kubernetesクラスターのバージョンアップを簡単かつ効率的に実施できます。また、クラスター一覧画面で各クラスターのバージョンが一目で確認できるため、どのクラスターに更新が必要かを即座に把握することができます。これにより、複数クラスターのバージョン管理がシンプルになり、運用負荷を軽減することができます。 ワークロード管理 RancherのWeb UIから管理対象クラスター内にPodをデプロイしてみます。 サイドバーからインポートしたクラスターのダッシュボードに遷移します。 Workloads内のDeploymentsを選択し、Deployments画面内でCreateを選択します。 Deploymentの設定画面でnginxのPodを6つ起動する設定を入力します。 Createボタンを押下し、しばらくするとnginxのPodが6つ起動します。 今度はnginxのPodのレプリカ数を減らしてみましょう。 Deployment一覧画面で先ほど作成したnginx-demo-deploymentを選択し、Edit Configで設定編集画面に遷移します。 編集画面でreplicasを3に変更して保存します。 Deploymentの更新が完了すると、nginxのPod数が指定した数まで減少します。 RancherのGUIを活用すれば、Kubernetesクラスター内のリソース設定を直感的に管理できます。マニフェストファイルを一から作成する必要がなく、UI画面上で簡単にリソースの作成や編集が可能です。また、GUIでの操作に加え、必要に応じてYAMLファイルを直接編集して詳細な設定を行うこともできます。 まとめ Rancherを導入することで、ブラウザ上から複数のKubernetesクラスターを効率的に管理できます。特にマルチクラスター環境の運用を効率化するため、Rancherは強力なツールとなります。 次回の記事では、Rancherのモニタリング機能について詳しく解説しますので、ご期待ください。 参考 Rancher公式ドキュメント ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Rancher入門:Rancherを用いたKubernetesクラスター管理 first appeared on SIOS Tech. Lab .
挨拶 ども!過去のデモを執筆する元気を奮い立たせている龍ちゃんです。今季は、【生成AI】という大きなキーワードで取り組みを行ってきました。その過程で【Streamlit】【Qumcum】【AIエージェント】の3つを掛け合わせて、ロボットをAIエージェントで操作するデモをいろいろなところで使用してきたので技術的な内容について解説していきます。 システムの概要については、 こちらでラフ に紹介しています。 2024-10-03 「Qumcum×生成AI」ロボットで試すAIエージェント:Python システム概要 内容としては、「人間の入力をAIエージェントが解釈してロボット制御」を行います。 エージェントをロボット制御に活用することで、以下のようなメリットが存在します。 ユーザの入力がロボットの複合的な動作も判断して処理 ユーザのあいまいな表現に関してもロボットの制御として処理 それでは、作成の話に入っていこうと思います。 設計 システムはすべてPython上で動作しています。ロボットは、 CRETARIA社 が発売している Qumcum を使用しています。こちらもPythonで制御することができるAPIが出ています。 コア 使用しているサービスについては、以下の内容です。 サービス・製品名 説明 Qumcum PRO Bluetoothで接続することで、API経由で遠隔でロボット制御を実現できる モーターの角度を調整することができれば様々な表現をが可能 Azure OpenAI Service Azureが提供しているAIサービス エージェントの作成には、langchainを使用しています。langchainはバージョンが非常に大切になるので、ライブラリはバージョンを含めて記載しておきます。 langchain==0.2.16 langchain-community==0.2.16 langchain-core==0.2.39 langchain-openai==0.1.23 streamlit==1.38.0 Streamlit上での処理フロー Streamlit上でデモアプリを管理するために、Qumcumとの接続処理やLangchainを用いたエージェントの処理フローをしっかり構成しました。 流れとしては、大きく分けて二つです。 Streamlit上でQumcumとの接続処理(エージェントページへのアクセス許可) StreamlitからLangchainを介してAzure OpenAI Serviceへのアクセス LangchainからQumcumの動作を制御するため、エージェントへアクセスする際にはQumcumとの接続を確約している必要があります。そのため、Streamlit上の制御でQumcumとの接続処理が実行されるまでエージェントのページにはアクセスできないように構成します。 ページ構成としては、トップページとエージェント処理ページの二つ作成します。 ページ名 説明 トップページ:/ Qumcumとの接続を管理する エージェントページ:/agent Langchain(エージェント)のアクセスを管理する Qumcumとの接続が確約されるまでアクセスできない 実装 今回の実装は、ロボットの動作作成からエージェントの実装まで多岐にわたります。また、デモとしてまとめるためにStremlitからアクセスできるように作成しています。分割して解説を書いていきます。 Qumcum処理 ここでは、ロボットとの接続処理と立ち姿リセット処理をまとめています。QumcumとのAPI接続には、 公式が提供しているAPI をダウンロードして構成する必要があります。 環境変数として ROBOT_ID を取得して接続を処理しています。 import os from dotenv import load_dotenv import qumcum_ble as qumcum load_dotenv() def robot_connection(): ROBOT_ID = os.getenv("ROBOT_ID") [err, _] = qumcum.get_info() if err == -1: qumcum.connect(ROBOT_ID) [err, _] = qumcum.get_info() if err == -1: return False else: robot_reset() return True else: return True def robot_disconnect(): qumcum.motor_power_off() qumcum.end() def robot_reset(): qumcum.motor_power_on(500) qumcum.motor_angle_multi_time(0, 90, 90, 90, 90, 90, 180, 600) qumcum.motor_start(True) qumcum.motor_power_off() Qumcumはサーボモータを調整すればいろんな動作を作成することができます。Qumcumをポージングさせるなんてこともできたりします。Qumcumの動作は結構長くなるので「こんな感じで書くよ~」ってイメージのために、気を付けの姿勢制御のみ記載しています。 こちらは、別の機会に「 Qumcum動き集 」として執筆していきたいと思います。 Langcahin:エージェント処理 ここでは、langchain v0.2でのtool callingの書き方について説明しています。デコレーターとして @tool を付けることでエージェントに受け渡すことができます。 import os from langchain_openai import AzureChatOpenAI from langchain.agents import tool from langchain_core.prompts import MessagesPlaceholder, ChatPromptTemplate from langchain.agents import create_tool_calling_agent, AgentExecutor from langchain.memory import ConversationBufferWindowMemory from dotenv import load_dotenv load_dotenv(verbose=True) # Azure OpenAI Serviceの設定 AOAI_ENDPOINT = os.environ.get("AOAI_ENDPOINT") # Azure OpenAI Serviceのエンドポイント AOAI_API_VERSION = os.environ.get("AOAI_API_VERSION") # Azure OpenAI ServiceのAPIバージョン AOAI_API_KEY = os.environ.get("AOAI_API_KEY") # Azure OpenAI ServiceのAPIキー AOAI_CHAT_MODEL_NAME = os.environ.get("AOAI_CHAT_MODEL_NAME") # Azure OpenAI Serviceのデプロイモデル名 CUSTOM_SYSTEM_PROMPT = """ あなたは、指定された指示に従って、クムクムを操作するアシスタントです。 操作するためのツールは、以下の通りです。 以下のツールを呼び出す回数は、最大20回までです。 - banzai: クムクムが両腕を上げます。 - all_up_dance_tool: クムクムが両手足を上げ下げするダンスを踊ります。引数には、踊る回数とスピード(デフォルトで1000)を入れてください。 - walk_right: クムクムが右に曲がって一歩歩きます。 - walk_left: クムクムが左に曲がって一歩歩きます。 - walk_forward: クムクムがまっすぐ前に一歩歩きます。 - denied: クムクムが拒否動作をします。 - talk: クムクムが引数に入れた言葉を喋ります。 上記のどれにも当てはまらない場合は、以下のツールを使ってその旨を伝えてください。 - impossible_move: クムクムが不可能な動きを指示された時に断るためのツールです。引数にその旨を入れてください。 """ # LLMの初期化 llm = AzureChatOpenAI( azure_endpoint=AOAI_ENDPOINT, api_key=AOAI_API_KEY, api_version=AOAI_API_VERSION, openai_api_type="azure", azure_deployment=AOAI_CHAT_MODEL_NAME, ) @tool def banzai(): """ クムクムが両腕を上げるためのツールです。 """ # クムクムに両腕を上げる指示を記述 return "バンザイ" @tool def all_up_dance_tool(num, speed): """ クムクムが両手足を上げ下げするダンスを踊るためのツールです。 """ # クムクムにダンスを踊る指示を記述 return "ダンスを踊りました。" @tool def walk_right(): """ クムクムが右に90度曲がるためのツールです。 """ # クムクムの右に曲がる処理を記述 return "一歩右に曲がりました。" @tool def walk_left(): """ クムクムが左に90度曲がるためのツールです。 """ # クムクムの左に曲がる処理を記述 return "一歩左に曲がりました。" @tool def walk_forward(): """ クムクムがまっすぐ前に一歩進むためのツールです。 """ # クムクムが一歩進む処理を記述 return "一歩進みました。" @tool def denied(): """ クムクムが動作拒否をするツールです。 """ # クムクムの拒否動作を記述 return "首を振りました。" @tool def talk(word): """ クムクムに喋らせるためのツールです。 """ # クムクムに喋らせる指示を記述 return "「" + word + "」" @tool def impossible_move(message): """ クムクムが不可能な動きを指示された時に断るためのツールです。 """ # クムクムの不可能であることを動作または音声で通知 return message tools = [ banzai, all_up_dance_tool, walk_right, walk_left, walk_forward, denied, talk, impossible_move, ] prompt = ChatPromptTemplate.from_messages( [ ("system", CUSTOM_SYSTEM_PROMPT), MessagesPlaceholder(variable_name="chat_history"), ("user", "{input}"), MessagesPlaceholder(variable_name="agent_scratchpad"), ] ) agent = create_tool_calling_agent(llm, tools, prompt) exucutor = AgentExecutor( agent=agent, tools=tools, verbose=True, memory=ConversationBufferWindowMemory( return_messages=True, memory_key="chat_history", k=0 ), ) all_up_dance_tool ・ talk ・ impossible_move では、引数を受け取っています。こちらに関しての説明もプロンプト内で行うことでエージェントが判断して代入した状態で実行をしてくれます。 Streamlit:ページ制御 まずはディレクトリ構成について記載しておきます。Streamlitでマルチページを作成する方法は二つあります。今回は状態によって利用制御を行いたいので、プログラムでページを管理する方法を採用しています。 ./ ├── contents # Streamlit ページ用ディレクトリ ├── utils # Python処理をまとめる ├── main.py # Streamlit起点ページ ├── qumcum_ble.py # Qumcum APIライブラリ └── requirements.txt contents の内部には、 top_page.py (ロボットの接続処理)と robot_move_agent_page.py (ロボットのエージェント制御)の2つ用意します。 main.py でページとメニューバーの制御を行います。 import streamlit as st def main(): # 各Stateの初期化 if "robot_connection" not in st.session_state: st.session_state.robot_connection = False # ページの設定 top_page = st.Page( page="contents/top_page.py", title="ロボットとの接続", icon=":material/home:", default=True ) robot_move_page = st.Page( page="contents/robot_move_agent_page.py", title="ロボットを動かす", icon=":material/apps:", ) # 接続が成功している場合は全てのページを表示 if st.session_state.robot_connection: pg = st.navigation( { "INFO": [top_page], "AIエージェント": [robot_move_page], } ) # 接続が失敗している場合はTopページのみ表示 else: pg = st.navigation( { "INFO": [top_page], } ) pg.run() if __name__ == "__main__": main() StreamlitのSession State を利用して状態の管理を行います。ロボットの接続状態によって表示されるメニューが変更されます。引数として default を渡すことで、特定のページをトップページにすることができます。 top_page.py:Streamlit・Qumcum接続処理 ここでは、ボタンを押したらロボットとの接続を管理することができるページとなっています。ロボットの接続は session state の robot_connection で管理しています。接続に成功するとTrueを代入します。 import streamlit as st from utils.robot_connection import robot_connection, robot_disconnect from dotenv import load_dotenv load_dotenv() st.title("ロボットとの接続の確立") if st.session_state.robot_connection: st.success("Connected to the robot") if st.button("Disconnect"): robot_disconnect() st.session_state.robot_connection = False st.success("Disconnected from the robot") st.rerun() else: st.error("ロボットと接続されていません。") if st.button("Try to connect"): connection = robot_connection() if not connection: st.error("やはり接続が確立することができません。実機の確認をしてください。") else: st.success("接続が確立されました。") st.session_state.robot_connection = True st.rerun() robot_move_agent_page.py:Streamlit・Langchain接続処理 こちらでは、単純な入力フォームとチャット形式で入出力を表示しています。ユーザーの入力を起点にlangchainのエージェントを実行しています。 # chatbot.py import streamlit as st from langchain.schema import HumanMessage, AIMessage from dotenv import load_dotenv import utils.aiagent_qumcum_control as agent load_dotenv() # ページの設定 st.set_page_config(page_title="ロボットを動かす", page_icon="😆") st.header("ロボットを動かす") # チャット履歴の初期化 robot_messages = [] # ユーザーの入力を監視 if user_input := st.chat_input("聞きたいことを入力してね!"): robot_messages.append(HumanMessage(content=user_input)) with st.spinner("GPT is typing ..."): response = agent.exucutor.invoke({"input": user_input, "chat_history": []}) output = response["output"] robot_messages.append(AIMessage(content=output)) # チャット履歴の表示 for message in robot_messages: if isinstance(message, AIMessage): with st.chat_message("assistant"): st.markdown(message.content) elif isinstance(message, HumanMessage): with st.chat_message("user"): st.markdown(message.content) デモ 課題 今回の実装における問題点についてまとめていきます。 Streamlitでの動作が同期処理 Streamlitの表現はすべて同期処理になっています。そのため、Langchainの処理が完了するまで結果を取得することができていません。長い処理をエージェントが実行している場合は、事項中は画面がフリーズします。デモとしては気まずい時間が流れますね。 デモ画面がチャットだけだと味気ない 現行のデモの場合だと、実行結果のテキスト表示と入力フォームしかありません。口頭で一から説明するのもなかなか大変だと感じています。ここは見せ方をもっと工夫する必要がありそうです。 この問題を解決するために、LangchainとStremlitについてもっと深堀していく必要がありそうです。 終わり 今回は、LangchainとQumcumを組み合わせてAIエージェントでロボットを制御するデモの実装について解説しました。Streamlitを使用することで、ユーザーフレンドリーなインターフェースを実現することができました。 課題として挙げた同期処理の問題や、UIの改善点については今後も継続的に取り組んでいく予定です。このデモを通じて、AIエージェントとロボットの組み合わせの可能性を示すことができたと思います。 今後も新しい技術を積極的に取り入れながら、より良いデモの開発に取り組んでいきたいと思います。最後までお読みいただき、ありがとうございました! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post AIエージェントでロボットを制御する【langchain・Streamlit】 first appeared on SIOS Tech. Lab .
構築したRAGの性能を評価はどうしたらよいでしょうか。RAGを使ったシステムを改善のサイクルを回すには評価が重要になります。RAGの評価はRAGAsをはじめとして複数の方法が提案されています。それらの方法を整理して包括的で体系的に理解できるような説明を試みました。読んでいただいた方の理解の助けになれば幸いです。 自然言語生成 (NLG) の評価の難しさ 自然言語生成 (NLG) の評価は従来のシステムのテストとは大きく異なるものです。自然言語の表現は多様で同じ内容であっても表現方法が複数あります。当然、LLMの性能評価はプログラムの関数をユニットテストするようにはできません。 例えば、「世界一高い山は?」という質問を考えます。例えば、次のような回答のパターンが考えられます。 「世界一番でエベレストで。」 という回答はエベレストであることは正解ですが日本語がおかしいため、適切な回答とはいえません。 「世界で一番高い山はエベレストの可能性があります。」 答えは正しいものの曖昧な回答となっており、これも適切な回答ではありません。 「世界で一番高い山はエベレストで、標高は3,776mです。」 答えは正解ですが、補足情報が間違っています。 「世界で一番高い山は富士山です。」 これは完全に誤答です。このような誤答をあたかも正解のように回答することは特にハルシネーションと呼ばれています。正解ではあるものの不適切な表現を含む有害な回答が混ざる可能性もあります。 当然このようなモデルの生成した文章に対して評価するのは、従来の単純な文字列のようなテストではうまくいきません。回答の文章を認識して判断する必要があります。また、このような文章での回答は正解か不正解かに単純に分類できず、悪い回答から良い回答までグラデーションがあるともいえます。簡潔に回答して欲しい時もあれば、補足情報をたくさん含んで欲しいこともあります。 評価者はNLGについて再現性があり納得のいく方法で評価し提示しなくてはなりません。 NLGの評価方法 この章では、RAGに限らずLLMの自然言語生成 (NLG) をどう評価するのかについて説明します。 評価のアプローチ NLGの評価のアプローチは大きく分けて3つあります。 人手評価 模範解答ありの自動評価 模範解答なしの自動評価 (LLM as a judge) 人手評価 人手評価は文字通り人がモデルの回答を評価する方法です。人間が直接テキストをみて判断するため、適切な回答であるかを直感的に判断できます。その一方で評価は人間が行うためテストの作業規模が増大します。主に小規模なシステムで実施するのがよいといえます。 模範回答(注釈)ありの自動評価 人間が用意した模範回答とLLMの回答の一致度を測定して評価する方法です。テキスト中の単語の一致度を計算するなどの方法で評価されます。この方法ではLLMがある程度決まった回答をしてくれるかどうかを比較的確実に評価することができ、再現性が高い評価が可能です。しかし、模範解答のデータセットを準備するコストが高かったり、回答の自由度が高いようなバラつきが大きくなる質問ではスコアが低くなってしまい適切に評価できないという課題があります。 模範回答(注釈)なしの自動評価 (LLM as a judge) 模範解答を用意せず、LLMに回答の評価を評価する方法もあります。このような方法はLLM as a judge [ 1 ] と呼ばれています。LLMによる評価は人手評価に近い評価ができると言われています。一方で、実行ごとに評価が変わってしまうなど再現性がやや低いといった課題もあります。 評価アプローチの比較 上記の評価指標を表1で比較しました。 (表1: 評価アプローチの比較) 評価アプローチ テスト実施コスト テスト実装コスト テストの再現性 回答のバラつきの許容度 人手評価 大きい なし 低い 高い 模範回答ありの自動評価 小さい 大きい 高い 低い 模範解答なしの自動評価 小さい 中程度 中程度 高い 模範回答ありの自動評価では、汎用的なモデルに対しては既存のデータセットが存在するため、評価指標を用いた自動評価が可能ですが、RAGの場合は独自のデータを用いた回答が期待されるため、データセットの準備にはコストがかかります。一方で、模範解答なしの自動評価は注釈(模範解答)をつける労力はかからないもののテストの再現性がやや低かったり、本当に人が期待している回答とは比較しないので乖離が発生する可能性があるというトレードオフがあります。現在、主流のRAGの評価では模範回答ありの自動評価のアプローチが提案されています。詳しくは後述しますが、RAGではコンテキスト(検索された文書)が利用できるため、なるべく注釈をつけないで評価できるような方法も提案されています。 評価のタイミング 評価方法は評価タイミングによっても2つに分けることができます。 オンライン評価 オフライン評価 オフライン評価 予め用意されたテストデータを使ってモデルの性能をテストする方法です。単体テストや結合テストにあたる本番運用前にテストします。今回はこのオフライン評価について主に説明します。 オンライン評価 本番運用段階で実際のユーザの入力やフィードバックを使った評価です。例えば、OpenAIのChatGPTでユーザに対しLLMの回答に や を付けるように促しているのもその一例です。 RAGの評価手法 ここではRAGの評価はNLGの評価に加えて、検索された文章 (コンテキスト) を使うことでより多角的な評価が可能となります。RAGの評価手法ではこのコンテキストも含めて、総合的に評価する手法が提案されています。 RAG評価に必要なパラメータ RAGの評価では次の4つのをパラメータ用いて評価が行われます。 質問 (ユーザの質問。クエリ。) コンテキスト (検索された文書。チャンク。) 回答 (モデルの回答。実際の回答。レスポンス。) Ground Truth (模範回答。注釈。リファレンス。期待する回答。GT。) 質問はユーザがRAGに対して質問する文章のことです。 コンテキストはLLMが検索ツールでクエリを実行した結果得られた文章(チャンクとして分割された文書の断片)のことです。コンテキストは通常は複数取得され、それらのコンテキスト全てが評価に利用されます。 回答はコンテキストをもとにLLMが生成した回答の文章です。 Ground TruthはRAGに期待する回答で、質問に対して回答すべき内容を正確に記述した文章です。Ground Truthは人が作成したり、LLMにより自動生成する方法があります。 RAGAsによる質問・文書・評価を使った評価 現在、RAGの評価として最も有名なのがRAGAs (Retrieval Augmented Generation Assessment) [ 2 ] です。現在のRAGの評価手法の基本的な考え方となっています。RAGAsの評価指標をベースとして改善や派生の指標が提案されています。この章ではRAGAsを説明します。 RAGAsの考え方 RAGAsは3つの指標を使うことでGround Truth不要で評価できるように設計されています。まずは、その核となる次の3つ指標を用いて説明します。 Context Relevance (文脈の関連性) Faithfulness (忠実性) Answer Relevance (回答の関連性) Context Relevance (文脈の関連性) は質問とコンテキストの間にどれだけが関連性があるか確認する指標です。RAGでは質問に対して関連性が高いコンテキストが取得できれば、LLMが適切に回答できる可能性が高まります。 Faithfulness (忠実性) はコンテキストに基づいて回答が生成されているかどうかを確認する指標です。これはコンテキストが回答に役立つものが取得できているかやコンテキストに基づかない回答をしてハルシネーションしていないかを判断に有効な指標です。 Answer Relevance (回答の関連性) は最終的な質問と回答が関連しているかについて確認する指標です。質問に対して回答の情報が不足していたり、逆に不必要な情報を含んでいないかを確認することができます。 図1に各指標とRAGの入出力(質問・文書・回答)との関連を示します。 図1: RAGAsの3つの指標の関係。RAGへの入出力に対して互いに関連を評価する。[ 3 ]より引用・改変。 このように入出力を互いに評価することでGround Truthなしで評価できる方法となっています。このような評価では人手評価と近い評価が実現できると報告されています [ 2 ] 。 RAGAsの指標 RAGAsの指標について説明します。ここの指標には論文に説明されている指標以外にも Ragas として公開されているOSSで実装されているもの説明します。Ground Truthを使った評価も含まれており、そのような指標を用いてより精緻に評価することができます。Ragasの指標はかなり頻繁に見直しされており、指標は今後も変更がある可能性があります。 Context Relevance (コンテキストの関連性) Context Relevance (Context Relevancy) は RAGAsの考え方 で説明した通り、RAGAsにより最初に提案された基本的な指標の1つです。Context Relevanceは検索により取得されたコンテキストが質問とどの程度関連するかを測る指標です。取得したコンテキストを文単位に分割し、各文が質問と関連しているかをLLMに判定させ、その中で関連すると判断された文章の割合です。従って、Context Relevanceは0から1の値をとり、0は関連のある回答が存在せず、1が全ての文において質問と関連があると判定されたことになります。1に近いほど良好です。 ただし、現在、この指標はRagasから削除され、Context Precision (文脈の精度) に置き換えられました。 Context Precision (コンテキストの精度) Context Precision はコンテキストが質問とどの程度適合するかを測る指標です。質問と関連性が高いコンテキストが取得できていれば、この指標は1に近くなります。一方で、関連性が低いコンテキストばかりの場合は指標は0に近くなります。 Context Relevanceと似ていますが、少し評価方法が異なります。Context Relevanceはどの文も均して評価されますが、Context Precisionは検索されたチャンクごとに精度を一度計算し、最後にチャンクごとの精度の平均をとります。Context Relevanceは削除されContext Precision (文脈の精度) に置き換えられました。おそらくContext Precisionの方が適切に評価できると判断されたことが理由だと思われます。 【補足1】精度99%の判別器で陽性である場合に「本当に」陽性であるのは99%でしょうか?実はこれだけの情報では簡単に答えられません。データが概ね陽性と陰性が半分ずつに別れている場合はそのようになりますが、データがどちらかに偏っている場合は全く異なります。ウイルス感染を調べる検査を無作為に行った場合に「陽性判断を受け本当に陽性である」確率は数学的に相当に低いことが知られています (参考: 精度99%の検査で陽性だったら、その病気である確率は99%?? →大間違い! ) 。例えば、100万人の病気でない人と100人の病気の人という偏りがあった場合は、陽性判定を受けた人のうち実際に病気である人はたった6%にすぎません。これを「検査陽性のパラドックス」といいます。RAGでもテストデータとして、質問と関連性の高い情報をたくさん取り込んでテストした場合と関連性の低い情報をたくさん取り込んだ場合では結果が異なることがあるでしょう。このようにテストデータの偏りも精度をどう捉えるかという判断にとても重要です。数字に騙されず多くの指標を取り入れて多角的に判断するようにしましょう。 Context Recall (コンテキストの再現率) Context Recall は回答に必要な情報(クレーム)がコンテキストに「もれなく」含まれているかを測る指標です。Context RecallではGround Truthに含まれる情報のうちがどれだけコンテキストに含まれるかの割合を算出します。包括的に取得できているほど1に近く、取得できていないほど0に近い値となります。1であればLLMはGround Truthと同等の内容を回答できるだけの情報を取得できたことになります。逆に0に近ければ回答に必要な情報が不足しているということになり、LLMが期待している回答をできる可能性が低くなります。 【補足2】精度 (Precision) と再現率 (Recall) についての補足説明です。これらの言葉は陽性 (Positive) と陰性 (Negative) を判定するシステムの良し悪しを判定するために使う言葉です。例えば、検査による病気の判定や異常検知システムなどが代表的な例です。このようなシステムの出力と本来の結果については4つのパターンが考えられます。 1. 検査結果が陽性で本当に陽性 (True Positive、TP、真陽性)。 2. 検査結果が陽性で本当は陰性 (False Positive、FP、偽陽性)。 3. 検査結果が陰性で本当に陰性 (True Negative、TN、真陰性)。 4. 検査結果が陰性で本当は陽性 (False Negative、FN、偽陰性)。 このとき、精度は陽性と判定され本当に陽性である割合を表します。つまり、誤って陰性のものを拾ってきてしまっていないかが分かります。精度は適合率ということもあります。 再現率は本当に陽性であるもののうち、陽性と判断されたものの割合を表します。つまり、陽性を取りこぼさずに拾ってこれたかが分かる指標です。 日常で「精度」という言葉は比較的ラフに使われがちですが、機械学習やAIの領域ではきちんとした定義があり、よく出てくる言葉なので覚えておくと役立ちます。 Context Entities Recall (コンテキストのキーワードの再現率) Context Entities Recall は回答に必要な「エンティティ」がコンテキストにもれなく含まれているかを測る指標です。エンティティとは文章におけるキーワードのことです。例えば、「日本で一番高い山は富士山で、標高は3,776mです。」という文章では、「日本」「富士山」「3,776m」などがキーワードとなります。Context Entities RecallではGround Truthに出現するキーワードのうち、コンテキストに出現するキーワードがどれだけあったかの割合を算出します。1に近いほど、Ground Truthに出現するキーワードがコンテキストにも出現していることになり、Ground Truthに近い回答ができる可能性が高まります。逆に0に近いとGround Truthに出現するキーワードが存在せず、LLMへ与える情報が不足していることになります。 Context Recallは「情報(クレーム)」をベースとした再現率を計算しますが、Context Entities Recallは「キーワード (エンティティ) 」をベースとした再現率を計算するという違いがあります。観光案内デスクや歴史的な質問応答などの固有名詞の扱いが重要なユースケースでの評価で有効とされています。 Noise Sensitivity (ノイズへの敏感性) Noise Sensitivity はコンテキストに含まれる誤った情報 (クレーム) を取り込んでしまっているかを測る指標です。コンテキストに含まれているが、Ground Truthに含まれていない情報を回答には必要がない情報なので「ノイズ」と定義します。その上で、回答に含まれる情報のうち、ノイズの割合を算出します。0に近いほどLLMはノイズをひろっていないので良好と言えます。逆に1に近いほど、回答にノイズを取り込んでしまっているということになります。 Answer Relevance (回答の関連性) Answer Relevance (Response Relevancy) は RAGAsの考え方 で説明した通り、RAGAsにより最初に提案された基本的な指標の1つです。質問に対する回答として関連が見られるかを測る指標です。この指標により最終的にきちんと質問に対して回答したかを確認することができます。 Answer Relevanceの計算は少し特殊です。例えば、「日本の最高峰は?」と質問をし「日本で一番高い山は富士山で、標高は3,776mです。」という回答を得られた状況を考えます。評価は、まず、LLMにこの回答に対する質問は何かを逆に生成させます。その結果、「日本で一番高い山は?」と「日本で標高が最も高い山は?」などが得られます。これらを疑似質問といいます。これらの疑似質問を本来の質問とコサイン類似度を計算します。それぞれ類似度を計算すると類似度(「日本の最高峰は?」,「日本で一番高い山は?」 ) = 0.9、類似度(「日本の最高峰は?」,「日本で標高が最も高い山は?」 ) = 0.7(値は例です)となったときその平均の0.8が回答の関連性となります。 Answer Faithfulness (回答の忠実性) Answer Faithfulness (Faithfulness) は RAGAsの考え方 で説明した通り、RAGAsにより最初に提案された基本的な指標の1つです。Answer FaithfulnessはLLMがコンテキストに忠実に回答を生成したかどうかを表す0から1をとる指標です。単にFaithfulnessとも呼ばれることがあります。回答をシンプルな情報を含む複数の文章に分割します。この分割された文章のそれぞれがコンテキストから回答可能なのか判定します。コンテキストから回答可能であると判定された文章の割合がAnswer Faithfulnessの値となります。 コンテキストからだけ導かれた回答であるほど1に近い値となり、コンテキスト以外の情報が回答に含まれるほど0に近い値となります。そのため、この値が低いとハルシネーションを起こしている可能性があると判断できます。ただし、モデルが事前に学習している知識で正しく回答している可能性もあるため、結果の吟味には注意が必要です。 RAGAsによるテスト実装 基本的には Ragas を用いることでテストを実装することができます。さらに、RagasはRAGの評価で広く使われているため、多くのフレームワークにも取り入れられています。例えば、LangChain社によるLangSmithや Confident AI社の DeepEvalでも指標が実装されており実装にあたっては複数のアプローチがとれます。 RAGCheckerによるクレームベースの評価 Amazon AWS AI、上海交通大学、西湖大学のグループにより提案された RAGChecker はクレームと呼ばれる単一の情報のレベルで分解して算出することができる評価指標です [ 4 ] 。クレームレベルに分解することでより複雑な文書、回答であってもより正しく評価できることを目指しています。 RAGCheckerではRAGAs等の既存の評価手法に比べて、人間の評価とより高い相関が見られると報告されています [ 4 ] 。比較的新しい手法ですが、注目を集めつつあります。 RAGCheckerの考え方 図2のように模範解答、モデルの回答、チャンクに含まれる正しい/誤った/喪失した/関連のないクレームの数をベースとして指標が算出されます。RAGCheckerの指標は体系的に整理され、粒度が揃っているという特徴があります。また、RAGCheckerではこれらの指標の傾向から どのように改善すべきかの方針 も示しており参考になります。 RAGAsとRAGChekcerは類似点も多いですが、考え方の点では次が異なります。 RAGAsでは質問を評価に使うが、RAGCheckerでは質問は評価に使わない。 RAGAsでは文章/文/キーワード/クレーム単位の評価方法が混在するが、RAGCheckerではクレーム単位で統一されている。 RAGAsではGround Truthなしでも評価できるよう設計されているが、RAGCheckerでは模範解答をベースに評価を行う。 RAGCheckerの指標 RAGCheckerの指標には図2のようなものがあります。 Overall Metricsは最終的な回答を評価する指標です。RAGシステムとして最終的な結果がどうかという観点を確認します。 Retriever Metricsは検索ツールの検索結果を評価する指標です。うまく検索できているかという観点を確認します。 Generator MetricsはLLMの回答を評価する指標です。LLMがうまく回答を生成できているかという観点を確認します。 これらの指標をそれぞれ説明していきます。 図2: RAGCheckerの指標一覧。すべての文章はクレームレベルに分解され、クレームの数をベースに指標を組み立てる。 RAGChecker より引用。 Precision (精度) モデルからの回答にGround Truthのクレーム「だけ」を含むか測る指標です。モデルの回答にGround Truthに含まれないクレームが少ないほど良好な数値となります。数値が高いほど良好です。 Recall (再現率) モデルからの回答にGround Truthのクレームを「網羅的に」含むか測る指標です。モデルの回答にGround Truthのクレームが含まれているほど良好な数値となります。数値が高いほど良好です。 Context precision  (文書の精度) 全てのチャンクのうち、文書にGround Truthのクレームを含むチャンクがどれだけあるかを測る指標です。この指標に関してはクレームではなくチャンクの数が使われます。数値が高いほど良好です。1つでも関連のあるクレームが含まれていれば、関連のあるチャンクとみなされます。 RAGAsのContext precisionはチャンクごとに集約された精度を平均しますが、RAGCheckerはチャンクの数で割合を計算するという点で異なります。 Claim Recall (クレームの再現率) モデルからの回答にGround Truthのクレームを「網羅的に」含むか測る指標です。RAGAsのContext Recallと同等の指標です。 Context utilization (文脈の利用率) コンテキストとして取得できている必要なクレームのうちどれだけが利用されたかを測る指標です。この割合が高いとLLMはコンテキストを活用できていることがわかります。 Noise Sensitivity (ノイズへの敏感性) Noise SensitivityはRagasのものと同じ評価指標です。RagasのドキュメントにはRAGCheckerにNoise Sensitivityが導入されたと記載があり、持ち込まれた指標ということのようです。 Credits: Noise senstivity was introduced in  RAGChecker ( https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/noise_sensitivity/ より引用) Hallucination (ハルシネーション) モデルの回答のクレームのうちで、コンテキストに含まれない誤ったクレームの割合です。つまり、モデルが勝手に誤った情報を回答に出力した割合を表します。0に近いほど良好で、0を超える値で何らかのハルシネーションを起こしていることを表します。 Self-knowledge (自己知識) モデルの回答のクレームのうちで、コンテキストに含まれない正しいクレームの割合です。つまり、モデルがコンテキストにない情報を補った割合を表します。0から1の値をとりますが、どの値が良好かはユーザ次第です。根拠がある回答のみを求めている場合はこの値は低い方がよく、根拠がなくとも正しい情報であれば提示して欲しければ高い値がよいということになります。 Faithfulness (忠実性) モデルの回答のうちで、コンテキストに含まれるクレームが利用された割合です。Context utilizationと異なり、誤ったクレームも割合に含まれます。1に近いほどコンテキストに忠実に回答したことになり良好です。 RAGCheckerによるテスト実装 RAGChecker を用いることでテストを実装することができます。現在のところ普及度はあまり高くないので、公式以外のツールにはサポートされていないようです。今後の動きとして、AWSの標準的なRAG評価機能として、取り入れられる可能性は考えられます。 RAGの構成要素としてのLLMの評価 (RGB) RGBの考え方 RAGの全体的で外部的な挙動についての評価以外にもRAGを構成するコンポーネントごとの性能を評価するという考え方も存在します。RAGは検索ツールやLLMといった複数のコンポーネントからできているシステムであり、そのコンポーネントの単体を評価するという考え方です。 とりわけその中でもLLMの存在は中核となります。RGB (Retrieval-Augmented Generation Benchmark) [ 5 ] では「RAGの構成要素として」のLLMの能力を測る4つの指標を提案しています。その指標をご紹介します。 【補足3】これらの指標のうち、既存のLLMはNoise Robustnessはある程度能力を備えていますが、それ以外の3つの指標については改善の余地が大きいことが報告されています [ 5 ] 。 これらの能力はプロンプトエンジニアリングやファインチューニングで多少改善の余地があると思われますが、本質的にはLLMの根本の性能の改善される必要でしょう。一部の企業を除けば、LLMを一から学習させることは大きなコストがかかるため、LLMそのものの性能を向上させようと考えるのは現時点で得策ではありません。一方で、これらの課題を外付けのソリューションで解決する方法がよく検討されています。例えば、反事実への頑健性についてはGoogleによって提案されているファクトチェックツールの DataGemma や Retrieval Interleaved Generation ( RIG) [ 8 ] などの方法が提案されています。 RGBの指標 RGBでは図3の4つの指標を提案しています。これらについて説明します。 図3: RGBのLLM能力評価の観点4つ。[ 5 ]より引用。 Noise Robustness (ノイズへの頑健性) Noise Robustnessはコンテキストの中に回答に不必要な情報(ノイズ)が含まれている場合に、回答に必要な文書のみを参考に回答を生成できるかの能力を測ります。検索ツールは通常チューニングしても一定のノイズが含まれるため、LLMが情報を取捨選択する能力が必要となります。例えば、次のような関係のないコンテキストが検索結果に含まれていても適切に回答できる能力です。 ★質問 Who was awarded the 2022 Nobel prize in literature? (和訳: 2022 年のノーベル文学賞の受賞者は誰ですか?) ★コンテキスト 【関連するコンテキスト】The Novel Prize in Literature for 2022 is awarded to the Franch author Annie Ernaux, … (和訳: 2022年のノーベル文学賞はフランスの作家アニー・エルノーに授与される、・・・ ) 【関連しないコンテキスト】The Novel Prize in Literature for 2021 is awarded to the Franch author Abdulrazak Gurnah, … (和訳: 2021年のノーベル文学賞はフランスの作家アブドゥルラザク・グルナに授与される、・・・ ) ★回答 Annie Ernaux ([ 5 ]より引用、改変。) 類似の指標として既に紹介しているRagasやRAGCheckerもNoise Sensitivity (ノイズへの敏感性) という同様の指標を持っています。Noise SensitivityとNoise Robustnessは逆の指標となっていて、Noise Sensitivityは低く、Noise Robustnessは高い方が良好です。 Negative Rejection (回答不能な質問の却下) Negative Rejectionは検索された文書の中に回答に必要な情報が含まれていない場合に、回答を拒否する能力を測ります。通常、検索ツールは回答に無関係なコンテキストしか取得できない場合やそもそもコンテキストを取得できない場合があり、そのような場合にハルシネーションを起こすことなく回答を拒否できる必要があります。例えば、次のようなコンテキストにノイズのみが含まれている場合は回答できないと出力する能力のことです。 ★質問 Who was awarded the 2022 Nobel prize in literature? (和訳: 2022 年のノーベル文学賞の受賞者は誰ですか?) ★コンテキスト 【ノイス】The Novel Prize in Literature for 2022 is awarded to the Franch author Annie Ernaux, … (和訳: 2022年のノーベル文学賞はフランスの作家アニー・エルノーに授与される、・・・ ) 【ノイズ】The 2020 Nobel Laureate in Literature, poet Louise Gluck, … (和訳: 2020年ノーベル文学賞受賞者、詩人ルイーズ・グラック氏 、・・・ ) ★回答 I can not answer the question because of the insufficient information in documents (和訳: 資料の情報が不足しているため、質問にはお答えできません ) ([ 5 ]より引用、改変。) Information Integration (情報の統合) Information Integrationは回答に必要なコンテキストが複数ある場合にそれらの回答を統合して回答する能力を測ります。複数の情報を加味した上で回答しなくてならない複雑な質問では重要は指標となります。例えば、次のようにそれぞれのコンテキストに回答に必要な情報が含まれている場合にそれらを統合する能力です。 ★質問 When were the ChatGPT app for iOS and ChatGPT api launched? (和訳: iOS 用 ChatGPT アプリと ChatGPT API はいつリリースされましたか?) ★コンテキスト On May 18th, 2023, OpenAI introduced its own ChatGPT app for iOS… (和訳: 2023 年 5 月 18 日、OpenAI は iOS 用の独自の ChatGPT アプリを導入しました ・・・ ) That changed on March 1, when OpenAI announced the release of API access to ChatGPT and Whisper, … (和訳: OpenAI が ChatGPT と Whisper への API アクセスのリリースを発表した 3 月 1 日に状況は変わりました 、・・・ ) ★回答 May 18 and March 1. (和訳: 5月18日と3月1日。) ([ 5 ]より引用、改変。) Counterfactual Robustness (反事実への頑健性) Counterfactual Robustnessは検索されたコンテキストに事実と反する情報が含まれていた場合に、LLMがそのことを検知し提示する能力を測ります。情報源となる文書の品質が悪い場合には特に重要な指標となります。例えば、次のようにコンテキストの内容が事実誤認がある旨を報告できる能力のことです。 ★質問 Which city hosted the Olympic games in 2004? (和訳: 2004 年にオリンピックを開催した都市はどこですか? ) ★コンテキスト 【反事実】The 2004 Olympic Games returned home to New York, birthplace of the … (和訳: 2004 年のオリンピックは、ニューヨークに戻ってきました、・・・ ) 【反事実】After leading all voting rounds, New York easily defeated Rome in the fifth and vote … (和訳: すべての投票ラウンドでリードした後、ニューヨークは5位でローマを簡単に破り、投票しました… 、・・・ ) ★回答 There are factual errors in the provided documents. The answer should be Athens. (和訳: 提供された文書には事実誤認があります。答えはアテネでしょう。 ) ([ 5 ]より引用、改変。) G-EvalによるCoTを用いた評価 G-Eval [ 6 ] はCoT (Chain-of-Thoughts) を用いた評価手法で、NLGの評価全体に使える手法です。多くのユースケースに適用できる汎用性が高さが特徴です。RAG限定ではないですが、RAGの文脈でもよく登場します。G-Evalでは評価のステップについてLLMに指示し指標を定義します。LLMはその指示に従って、質問、コンテキスト、回答、Ground Truthなどのを使って評価をすることができます。RAGの評価においてもしばしば使われます。評価の自由度が高いため、RAGAs等に含まれていない指標をチェックしたいときに、独自にチェックしたい指標を追加することができます。 例えば、G-Evalによる評価指標の定義は次のようになります。Correctness(正確さ)という指標を定義しています。 (コード: DeepEvalによるG-Evalの実装例。 https://docs.confident-ai.com/docs/metrics-llm-evals より引用) from deepeval.metrics import GEval from deepeval.test_case import LLMTestCaseParams correctness_metric = GEval( name="Correctness", criteria="Determine whether the actual output is factually correct based on the expected output.", # NOTE: you can only provide either criteria or evaluation_steps, and not both evaluation_steps=[ "Check whether the facts in 'actual output' contradicts any facts in 'expected output'", "You should also heavily penalize omission of detail", "Vague language, or contradicting OPINIONS, are OK" ], evaluation_params=[LLMTestCaseParams.INPUT, LLMTestCaseParams.ACTUAL_OUTPUT, LLMTestCaseParams.EXPECTED_OUTPUT], ) 【補足4】CoTとはプロンプトエンジニアリングの一種で、LLMに複雑な推論をする際に複数のステップに分けて実行させることで、推論能力を向上させるテクニックです。予め、推論のステップについて、プロンプトで指示しておくことで実現します。 RAGのテストデータ生成手法 質問やGround Truthを人手で用意するには非常に手間がかかるため、自動生成したり、少数の注釈のみで評価が可能となるような手法も提案されています。例えば、Ragasでは コーパスを使ったテストデータの生成機能 を提供しています。 ARES (An Automated Evaluation Framework for Retrieval-Augmented Generation Systems) は少数の注釈のみでRAGを評価できる方法を提案しています [ 7 ] 。 LLMのテストフレームワーク RAGAs、RAGChecker、RGB、G-Evalなどの手法はそれぞれ論文と共に実装も提供されているので、個別のツールを使うことも可能ですが、テストフレームワークも使うことができます。サポーツされている指標には制約がありますが、テストツールとしてテストの管理がしやすいというメリットがあります。 LangSmith LangChain社が提供するLLMOpsのためのツールであり、有料(無料プランあり)のWebサービスとして提供されています。無料の場合は1ユーザのみでの利用が可能です。一部の機能に制約がありますが、ほとんどの機能は利用可能です。チーム開発では複数人での利用が前提となるので、ライセンスを購入して利用する必要があります。LangChainとの統合が容易であるという特徴があります。 DeepEval DeepEvalはConfident AI社が提供するLLMのテスト用のOSSのフレームワークです。Pytestと同じようなユニットテスト風にテスト実装ができ、テストケースの管理、データセットの生成、モデルの評価のLLMにおけるテスト全般をカバーしているのが特徴です。幅広い評価指標を取り込んでおり、Ragasを中心としてRAGの評価指標も実装されています。本番環境におけるオンライン評価も可能です。 SaaSとして提供されているLLM評価プラットフォームであるConfident AIとの統合によって評価や回帰テスト、監視が可能になります。 まとめ 今回は次のような内容をご紹介しました。 NLGの評価のアプローチ 人手評価 模範解答ありの自動評価 模範解答なしの自動評価 (LLM as a judge) NLGの評価のタイミング オフライン評価 オンライン評価 RAGの評価手法 RAGAs RAGChecker RGB G-Eval LLMのテストフレームワーク LangSmith DeepEval 現在までにRAGの評価では多くの手法が提案されており、RAGAsなどある程度の信頼がおける手法も出てきており、それらの手法を用いてRAGの評価を定量的にできるようになってきました。一方で、既存手法は少なくない課題が指摘されており、現時点で高いレベルで信用できる手法が存在しないのも事実です。評価の課題を解決するために頻繁に手法の提案や改善がされている状況であり、今後成熟していくことが期待される領域です。 最後までお読みいただきありがとうございました。このブログがお役に立てば幸いです。 RAGの改善手法については⇩のブログにご紹介していますので、こちらもぜひご覧になってください。 RAGはどのように進化しているのか?RAGのパラダイムと改善手法を体系的にご紹介! 【宣伝】生成AI ネクストテックソリューションのご紹介 弊社サイオステクノロジーでは生成AIを用いたトレーニング、コンサルティング、アプリケーション開発のソリューションを提供しています。ご興味のある方はぜひお問い合わせください! https://nextech-solutions.sios.jp/genai/ 参考文献 Lianmin Zheng ,  Wei-Lin Chiang ,  Ying Sheng ,  Siyuan Zhuang ,  Zhanghao Wu ,  Yonghao Zhuang ,  Zi Lin ,  Zhuohan Li ,  Dacheng Li ,  Eric P. Xing ,  Hao Zhang ,  Joseph E. Gonzalez ,  Ion Stoica, Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena , 2023. Shahul Es, Jithin James, Luis Espinosa-Anke, Steven Schockaert, RAGAS: Automated Evaluation of Retrieval Augmented Generation , 2023. 山田 育矢, 鈴木 正敏, 西川 荘介, 藤井 一喜, 山田 康輔, 李 凌寒, 大規模言語モデル入門Ⅱ 生成型LLMの実装と評価 , 技術評論社, 2024. Dongyu Ru, Lin Qiu, Xiangkun Hu, Tianhang Zhang, Peng Shi, Shuaichen Chang, Jiayang Cheng, Cunxiang Wang, Shichao Sun, Huanyu Li, Zizhao Zhang, Binjie Wang, Jiarong Jiang, Tong He, Zhiguo Wang, Pengfei Liu, Yue Zhang, Zheng Zhang, RAGChecker: A Fine-grained Framework for Diagnosing Retrieval-Augmented Generation , 2024. Jiawei Chen, Hongyu Lin, Xianpei Han, Le Sun, Benchmarking Large Language Models in Retrieval-Augmented Generation , 2023. Yang Liu, Dan Iter, Yichong Xu, Shuohang Wang, Ruochen Xu, Chenguang Zhu, G-Eval: NLG Evaluation using GPT-4 with Better Human Alignment , 2023. Jon Saad-Falcon, Omar Khattab, Christopher Potts, Matei Zaharia, ARES: An Automated Evaluation Framework for Retrieval-Augmented Generation Systems , 2024. Sirui Xia, Xintao Wang, Jiaqing Liang, Yifei Zhang, Weikang Zhou, Jiaji Deng, Fei Yu, Yanghua Xiao, Ground Every Sentence: Improving Retrieval-Augmented LLMs with Interleaved Reference-Claim Generation , 2024. ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【RAG評価手法】評価できないものは改善できない!?体系的に評価指標をご紹介! first appeared on SIOS Tech. Lab .
OpenShift GitOps (ArgoCD) は、OpenShift 上で GitOps を実現するためのツールです。前回の記事では CI/CD における CI 部分の OpenShift Pipelines (Tekton) のエラー通知機能を構築しました。同様に CD 部分である OpenShift GitOps にもエラー通知機能を実装したいと思います。OpenShift GitOps には ArgoCD Notifications という通知機能が用意されているため、 こちら を参考に実装してみました。 ArgoCD Notifications について ArgoCD Notifications  は ArgoCD アプリケーションを監視し、状態の変更についての通知を管理するカスタムリソース(CR)です。下記のようなテンプレート、トリガー、サービス、サブスクリプションといったリソースを設定します。 テンプレート 通知テンプレートメッセージを定義します。 トリガー ユーザーに通知が送信される条件と、メッセージを生成するために必要なテンプレートのリストを定義します。 サービス メッセージをどこに配信するなどの設定を定義します。 サブスクリプション   通知送信先などの設定をします。例えば Slack だと、どのチャンネルにどのトリガーを適用させるといった設定を定義します。Argo CD のアプリケーションの Annotations に定義します。 OpenShift GitOps では、通知を有効にして Red Hat OpenShift GitOps でクラスターを作成すると、デフォルトで default-notifications-configuration という名前の NotificationsConfiguration CR が作成されます。Argo CD では argocd-notifications-cm ConfigMap にリソースを定義しますが、OpenShift GitOps では default-notifications-configuration にカスタムリソース設定を記入します。ここに加えられた設定は Argo CD の Config Map に反映されますが、直接 Argo CD の Config Map を変更しても default-notifications-configuration で上書きされてしまう点に注意が必要です。 前提条件 OpenShift 4 クラスターが構築済みであること OpenShift GitOps Operator がインストールされていること oc CLI がインストール済みであること Slack に通知を送信するワークスペース、チャンネルが用意されていること 事前準備 Gitリポジトリの用意 下記構成のプライベートなマニフェスト用 Git リポジトリを用意します。アプリケーションをデプロイするためのマニフェストファイルが格納されています。 app ├── deployment.yaml ├── kustomization.yaml ├── route.yaml └── service.yaml deployment .yaml apiVersion: apps/v1 kind: Deployment metadata:   name: busybox-deployment spec:   replicas: 1   selector:     matchLabels:       app: busybox   template:     metadata:       labels:         app: busybox     spec:       containers:       - name: busybox         image: busybox         args:         - /bin/sh         - -c         - "while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; echo 'Hello from BusyBox'; } | nc -l -p 8080; done"         ports:         - containerPort: 8080 kustomization .yaml resources: - deployment.yaml - service.yaml - route.yaml route.yaml apiVersion: route.openshift.io/v1 kind: Route metadata:   name: busybox-route   labels:     app: busybox spec:   to:     kind: Service     name: busybox-service   port:     targetPort: 80 service.yaml apiVersion: v1 kind: Service metadata:   name: busybox-service spec:   selector:     app: busybox   ports:     - protocol: TCP       port: 8080       targetPort: 8080   type: LoadBalancer ArgoCD のデプロイ設定 OpenShift GitOps を構築してみた を参考にして下記手順を実施します。 OpenShift GitOps のログイン Argo CD へのデプロイ権限の付与 プライベートリポジトリの登録 Slack Web App の準備 通知をSlack に送信するためには、Slack App を作成し、適切な権限を付与する必要があります。 前回の記事 で Slack App を作成している場合は使いまわすことが出来るので、作成パートは飛ばしてもらって問題ありません。ややこしいのですが、OpenShift Pipelines (Tekton) では Webhook を使用しましたが、OpenShift GitOps ではSlack の OAuth Token を使用します。 Slack App のページから Create New App をクリックします。 From scratch をクリックします。 App Name を入力して、Slack App を追加するワークスペースを選択します。  Basic Information が表示されれば完了です。OAuth & PermissionsをクリックしてScopesを追加します。 Add an OAuth Scope をクリックして chat:write を追加します。 Install to ワークスペースをクリックしてワークスペースにアクセスする権限を許可します。 Slack に移動して通知を送信したいチャンネル名をクリックして、インテグレーションタブからアプリを追加します。 アプリ名を検索してアプリを追加します。 Slack のチャンネルにアプリが追加された旨のメッセージが表示されていることを確認して完了です。 OpenShift GitOps 通知設定 Argo CD インスタンスの通知を有効化 下記コマンドを実行して通知を有効化します。  $ oc patch argocd openshift-gitops -n openshift-gitops --type merge --patch '{"spec": {"notifications": {"enabled": true}}}' argocd.argoproj.io/openshift-gitops patched Slack App のトークンを持つシークレットを作成します。 $ oc apply -f secret.yaml Bot User OAuth Token は Slack App の OAuth & Permissions から確認できます。 secret.yaml apiVersion: v1 kind: Secret metadata:   name: argocd-notifications-secret   namespace: openshift-gitops stringData:   slack-token: <Bot User OAuth Token> 下記コマンドを実行して spec.notifications.enabled フィールドの値が true になっていることを確認します。 $ oc get argocd openshift-gitops -n openshift-gitops -o yaml apiVersion: argoproj.io/v1beta1 kind: ArgoCD metadata:   creationTimestamp: "2024-11-21T01:26:00Z"   finalizers:   - argoproj.io/finalizer   generation: 2   name: openshift-gitops   namespace: openshift-gitops ︙ spec: ︙   notifications:     enabled: true ︙ Argo CD インスタンスの通知設定の追加 下記コマンドを実行してArgo CD インスタンスの通知設定の追加を行います。 $ oc edit notificationsconfiguration default-notifications-configuration -n openshift-gitops テキストエディタが開いたら、spec以下に下記のようなservicesを追記します。templates,triggersはデフォルトのままで大丈夫です。 ︙ spec:   services:     service.slack: |       token: $slack-token   templates:  ︙ アプリケーションの作成 プロジェクトの作成 $ oc new-project sample-app 下記コマンドを実行してArgoCDの通知先が設定されたアプリケーションを作成します。 $ oc apply -f application.yaml application .yaml apiVersion: argoproj.io/v1alpha1 kind: Application metadata:   name: sample-app   namespace: openshift-gitops   annotations:     notifications.argoproj.io/subscribe.on-deployed.slack: webhook_test     notifications.argoproj.io/subscribe.on-sync-failed.slack: webhook_test     notifications.argoproj.io/subscribe.on-sync-succeeded.slack: webhook_test     notifications.argoproj.io/subscribe.on-health-degraded.slack: webhook_test     notifications.argoproj.io/subscribe.on-created.slack: webhook_test     notifications.argoproj.io/subscribe.on-sync-running.slack: webhook_test     notifications.argoproj.io/subscribe.on-deleted.slack: webhook_test spec:   project: default   source:     repoURL: < マニフェスト用 Git リポジトリ (.gitで終わるURL)>     path: app     targetRevision: main   destination:     server: https://kubernetes.default.svc     namespace: sample-app   syncPolicy:     automated:       prune: true       selfHeal: true アプリケーションがデプロイされていることを確認します。 動作確認 Slack の指定したチャンネルに通知が届いていることを確認して完了です。 まとめ OpenShift GitOps のエラー通知を Slack に送信する機能を構築し、その手順をまとめました。O penShift GitOps では、 ArgoCD Notifications  という既存の機能を有効にして通知を送信してみました。 ArgoCD Notifications のハンズオンとしても参考になれば幸いです。 参考文献 https://argo-cd.readthedocs.io/en/stable/operator-manual/notifications/#notifications-overview https://docs.redhat.com/ja/documentation/red_hat_openshift_gitops/1.13/html/argo_cd_instance/notifications-configuration-custom-resource-properties_argo-cd-cr-component-properties#notifications-configuration-custom-resource-properties_argo-cd-cr-component-properties ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post OpenShift GitOps のエラー通知を Slack に送信してみた first appeared on SIOS Tech. Lab .
こんにちは、サイオステクノロジーの佐藤 陽です。 アドベントカレンダー4回目の登場です。 今日はAzure FunctionsでNo HTTP triggers foundのエラーが発生した時の調査方法のお話です。 根本的な解決策ではないのですが、エラー解消の手がかりになればいいなと思い 備忘録の意味も込めて、記事を書いていこうと思います。 はじめに pythonの実行環境でAzureFunctionsにアプリをデプロイした際に 「デプロイが失敗しているわけでもないのに、何故か関数が表示されない!!」 といったことが結構起こります。 具体的には以下のようなケースです。 ・デプロイ時にエラーメッセージは発生しない(がエンドポイントのURLは表示されない) デプロイ実行 func azure functionapp publish func-hogehoge --python 結果 Resetting all workers for func-hogehoge.azurewebsites.net Deployment successful. deployer = Push-Deployer deploymentPath = Functions App ZipDeploy. Extract zip. Remote build. Remote build succeeded! [2024-12-02T04:03:16.963Z] Syncing triggers... Functions in func-hogehoge: //ここで本当はデプロイされるURLが表示されるはず C:\hogehoge ・VSCodeの拡張機能のデプロイ機能からやってみるとNo HTTP triggers found.と表示される 12:05:49 func-hogehoge: Removing existing manifest file 12:05:49 func-hogehoge: Running pip install... 12:06:01 func-hogehoge: Syncing triggers... 12:06:02 func-hogehoge: Querying triggers... 12:06:06 func-hogehoge: No HTTP triggers found. ・Azure Portalから見た時に関数が表示されない ・ソースコードのファイル自体はアップロードされているように見える こんな問題が起きた際の調査方法を今日は書き記していこうと思います。 調査方法 まずは皆が通る道として以下のような感じでググるかと思います。 Azure Functions No HTTP trigger Azure Functions 関数 表示されない そうすると結構な数がヒットするので、困っている人は多そうです。 例えばこちらの stackoverflow なんかを見てみると、まさに同じような現象が起きている人も見受けられます。 そして、このエラーに対する回答として多種多様な回答が来ています。 つまり、様々な要因によってこのエラーは引き起こされているようです。 自分と同じ現象の人にたどり着くのはなかなか難しそうで、しらみつぶしに試していくのは骨が折れます。 ちなみに色々ググって見つけた解決方法としては 環境変数の値が正しく設定されていない 環境変数に余計な値が登録されている インストールしているパッケージに依存して起きるもの といった内容が多かった気がします。 話は戻り やみくもに試すのではなく、自分の環境に基づいて調査を行う場合にどこを見ればいいかというと 今回の場合はAzure Portal上の、該当するFunctions Appの「問題の診断と解決」でした。 そして今回は、その中でも Python関数 という指標を選択します。 すると以下のような形で、例外一覧が表示されています。 やたらめったらデプロイしていたので、例外がたくさん発生しています。 いくつか例外が発生している中で、今回原因となっていたのは以下の例外でした。 Timestamp : 12/2/2024 7:15:18 AM Inner Exception Type: Microsoft.Azure.WebJobs.Script.Workers.Rpc.RpcException Total Occurrences: 44 Latest Exception Message: Worker failed to index functions Result: Failure Exception: TypeError: Client.__init__() got an unexpected keyword argument 'proxies' Stack: File '/azure-functions-host/workers/python/3.11/LINUX/X64/azure_functions_worker/dispatcher.py', line 469, in _handle__functions_metadata_request self.load_function_metadata( File '/azure-functions-host/workers/python/3.11/LINUX/X64/azure_functions_worker/dispatcher.py', line 449, in load_function_metadata self.index_functions(function_path, function_app_directory)) \ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File '/azure-functions-host/workers/python/3.11/LINUX/X64/azure_functions_worker/dispatcher.py', line 822, in index_functions indexed_functions = loader.index_function_app(function_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File '/azure-functions-host/workers/python/3.11/LINUX/X64/azure_functions_worker/utils/wrappers.py', line 44, in call return func(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^ File '/azure-functions-host/workers/python/3.11/LINUX/X64/azure_functions_worker/loader.py', line 244, in index_function_app imported_module = importlib.import_module(module_name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File '/usr/local/lib/python3.11/importlib/__init__.py', line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File '', line 1204, in _gcd_import File '', line 1176, in _find_and_load File '', line 1147, in _find_and_load_unlocked File '', line 690, in _load_unlocked File '', line 940, in exec_module File '', line 241, in _call_with_frames_removed File '/home/site/wwwroot/function_app.py', line 47, in openai_client = AzureOpenAI( ^^^^^^^^^^^^ File '/home/site/wwwroot/.python_packages/lib/site-packages/openai/lib/azure.py', line 205, in __init__ super().__init__( File '/home/site/wwwroot/.python_packages/lib/site-packages/openai/_client.py', line 112, in __init__ super().__init__( File '/home/site/wwwroot/.python_packages/lib/site-packages/openai/_base_client.py', line 793, in __init__ self._client = http_client or SyncHttpxClientWrapper( ^^^^^^^^^^^^^^^^^^^^^^^ どうやらAzureOpenAIを呼び出すクライアントに余分な引数が渡されているようです。 このエラーを解消し、再度デプロイしたところ正常にアプリがデプロイされ、関数も表示されました。 めでたし! 正直これまでAzure Portalの「問題の診断と解決」についてはあまり見てこなかったのですが、 今後はこちらの内容もしっかり押さえて、エラー解消などに役立てたいところです。 Application Insightsとの違いは? ちなみに「Application Insightsでは分からないの?」と思われる方もいると思うのですが あれはどちらかというとアプリが正常に起動した後のフェーズの監視ツールのイメージです。 実際、今回のエラーに関してはApplication Insightsの方には何も表示されていませんでした。 今回はそもそもアプリ起動時の処理でコケてしまっていたため、Application Insightsの監視範囲外だったのではないかと思います。 redditに こんな 回答もあり、自分としても同じ認識を持っています。 診断設定は、リソース自体からログ/メトリックを取得します。また、診断設定を通じてサービス/OS 自体からどのログ/メトリックが公開されるかは、MS のリソースによって決定されます。 Application Insightsは、Azureリソース上で実行されるコードを通じてこのタイプのデータを取得します。これは、独自の診断コードを挿入することによって行われます。 (日本語訳) そして今回も「Azure Functions」といった リソース の起動エラーであったため、「問題の診断と解決」の方に記録されたのではないかと思いました。 (もしApplication Insightsの方でも確認する方法などありましたら是非コメントなどで教えてください。) 「問題の診断と解決」の機能に関しては他にも色々と機能があるようなので 必要に応じてしっかり使い分けていきたいところです。 参考: Azure App Service 診断の概要 まとめ 今回はAzure Functionsの関数が正しくデプロイされない場合のケースについての調査方法の備忘録でした。 このようなケースにおいては、Azure Portalの「問題の診断と解決」にエラー内容が記載されている ことがある 、ということが分かりました 必ずしも記載があるわけではないと思うのですが、一度目を向けてみるとエラー解消の手がかりがあるかもしれません。 ではまた! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【Azure Functions】No HTTP triggers found発生時の調査方法 first appeared on SIOS Tech. Lab .