TECH PLAY

株式会社RevComm

株式会社RevComm の技術ブログ

171

Works Applicationsに所属しており、業務委託としてRevCommで働いている勝田です。8月末に開催されたNLP若手の会 (YANS)に参加し、発表を行いました。今回のブログ記事ではその報告をします。 著者 YANSの概要について 名称:NLP若手の会 (YANS) 第18回シンポジウム (2023) 開催日:2023年8月29日(火) - 31日(木) 29日はハッカソンのみ、シンポジウムは30日と31日の2日間で開催 会場:浅草橋ヒューリックホール リンク: https://yans.anlp.jp/entry/yans2023 2020年からオンラインでの開催が続いたため今回は4年ぶりの現地開催であり、対面での交流や議論はオンラインの時とは違った盛り上がりでした。参加者は300人、発表数は140件と去年よりも多く、特に発表数は去年の倍近い件数となっており、チケットの獲得時点から今年は雰囲気が違うと感じました。ChatGPTやLLM関連の発表が多く、サービスに近い業務にNLPを応用するハードルが下がってきたのではと思いました。 発表について タイトル: [S1-P09] オンライン会議の議事録自動作成に向けた前処理手法の検討 概要: ChatGPTや事前学習済みLLMを使うことで高品質な要約文を容易に生成できますが、テキスト長が大きくなれば、推論に時間がかかり計算コストが大きくなります。ここでは、オンライン会議の会話の文字起こしテキストを要約し、議事録を出力するシステムを作ることを目標にコストと精度の観点から前処理+要約のシステムを評価しました。特に会話の文字起こしテキストには、フィラーや定型的なやり取りなど、議事録に不要な表現が多く出現します。そのため、要約の前処理として不要な文を取り除くことで、計算コストを下げることが期待できます。そこで、実際のオンライン会議の会話の文字起こしテキストに、ルールベースや機械学習ベースの前処理を適用し、前処理の有効性について調査を行いました。 ポスター資料: ポスター資料 頂いた質問 オラクルの評価も行って、ある程度の上限値を見ると参考になるのではないか YANSまでに準備は間に合わなかったが、圧縮率に対するROUGEスコアが最大となる組み合わせを抽出した結果を見てみたいとは考えている。 名詞の抽出方法はどうしたか 形態素解析にはspaCy( ja_core_news_sm )を使った。 系列ラベリング的な手法は取らないのか システムに導入する上でコストや処理時間を考慮してできるだけシンプルな手法にしたいので文単位での2値分類で解くことにした。 アライメントを取るうえでコンテキストを考慮した方が精度が良いのではないか 上記と同様な理由で今回は試せていない ルールベースの前処理をしたうえで機械学習で解いた方がよいのではないか ルールベースと機械学習の手法を組み合わせることはできるが、機械学習が現状のデータセットに対してどの程度対処できるかを見たかった。 2値分類の精度はどれくらい出ているか 教師ありで学習させた場合は76%程度の精度となった。 まとめ 8月末に開催されたNLP若手の会 (YANS)の参加報告を行いました。私の発表に聴講や議論をしてくださった方に感謝申し上げます。オフラインでの交流ということもあり、ポスターを挟んでの直接の議論は得るものも多かったように感じます。 今後の研究方針としてどう精度を上げるかという問題もありますが、コストを無視することはできずコストパフォーマンスの良い手法を模索する必要があります。 例えば、FrugalGPT[1]では簡単なタスクは小さくコストが安いモデルに解かせ、難しいタスクになるほどコストをかけて大きいモデルに切り替えるといった戦略を取ることで精度を下げずに98%のコスト削減を行っています。 今回はChatGPTを使って要約を行うことを想定しており、そこではChatGPTが一番コストになるためその役割をどれだけ減らせるかという観点で”コスト≒圧縮率”として計算を簡略化しています。しかし、実際は前処理にもコストは発生しますし、それはどの手法を使うかによっても変わってきます。最終的にはシステム全体でのコストを見積りつつ、コストと精度の観点から最適な組み合わせを見つけたいと考えています。 謝辞 本研究にあたり、NTTPCコミュニケーションズが提供するInnovation LabのAI共創パートナープログラムにおいてサーバ環境を無償でご準備いただきました(補足:RevCommはこのプログラムのパートナーとして採択されています)。NTTPCコミュニケーションズに感謝を申し上げます。 引用 [1] Lingjiao Chen, Matei Zaharia, James Zou, “FrugalGPT: How to Use Large Language Models While Reducing Cost and Improving Performance”, paper
アバター
RevCommのフロントエンドエンジニア兼イベントモデレーターの小山です! RevCommは7/5(水)に「世界に認められたAIスタートアップが、Djangoを使って感じる良さとは? 」というイベントを開催しました。今回はそのイベントで公開したスライドや動画を公開しながら、イベント中に時間の都合で答えられなかった質問にも答えていきます。 今回のイベントは私が企画からモデレーターまで務めさせていただきました。登壇した小門さんと近藤さんは、RevCommの中でも技術についてのプレゼンやディスカッションが得意な2人です。期待以上に良いプレゼンをしてくれて、参加者の方々にも深い質問をいただくことができた会になりました。 フレームワークの使い方はドキュメントでも学ぶことができますが、状況に応じた選定や判断は使い手次第。今回はその点にも触れていますので、ぜひともご閲覧いただけるとありがたいです! speakerdeck.com speakerdeck.com youtu.be Q and Aへの回答 イベントではたくさんの質問をいただくことができました。時間の関係上、全てに答えることができなかったので、この場で共有をさせていただきます。 — Q: Djangoのバージョンアップ計画とかどうされていますか? 直近だとDjango4.2でMySQL5.7とPostgreSQL11のサポートが切れるので、そのあたりでどのように適用されたか、またはどのように適用しようとしてるなどあれば教えてください。 A: 社内ではマイクロサービス単位にアプリケーションが分かれていて、プロジェクトとして独立しています。 スケジュールや方式など含めた計画はプロジェクト毎に策定しています。 Django 3.2 LTS は 2024年4月にはメインストリームから外れるため、なるべくそれまでに更新することを社内の共通認識としています。 またDBは PostgreSQL バージョン12以上を使用してるため、その影響はありませんでした。 DBやRedisなど、周辺のサービスもこまめにバージョンアップすることも重要だと思います。 Q: 40個もアプリが分かれてると大変そうですが、どういう基準でアプリを分割してるのでしょうか。 A: 機能の責務や依存関係を考慮します。 例えばユーザー認証の機能とログイン後に利用する機能とでDjangoアプリケーションは分割します。 責務ごとにアプリケーションを分割することで改修範囲を小さくできたり、コードベース全体の見通しを高く保つことができます。 Q: 一部でDjango4.2を利用されているとのことですが、アップデートしてよかったところや、注意が必要だったところはありますか? A: 前述の通り、Django 3.2 LTS はいずれメインストリームから外れて開発も停止するため、最新の LTS に追従することはほぼ必須と考えて対応しています。 また、細かい機能改善も多数あり便利になっていっています。 アップデート時の注意点として、初めにリリースノートから大きな変更や影響が無いか確認しました。 Django 4.2 release notes 他の質問にもある、MySQL5.7/PostgreSQL 11 のサポート切れについても書かれています。 既に社内でアップデート済みの対応については別のブログ記事でも説明しています。 tech.revcomm.co.jp Q: 2019年の途中からDjangoに切り替えたということですが、移行時にはどのように実施したのでしょうか?全部書き換えるとすると実装もテストすごく大変そうだなと思い気になりました。 A: 当時Djangoへの移行を担当した方にヒアリングしたところ、下記のような返答をいただきました。 Node.jsからDjangoへ切り替えた当時は機能・コードともに少なかったので、テストも実装もあまり時間かからず移行できました。振り返ると、早い段階で移行する判断ができたので良かったと思います。 また、当時は品質よりスピードが求められていたこともあり、ユニットテストはまだなく、手作業によるシステムテストだけ実施し、品質を担保していました。このためテストケースはそのまま流用できたため、移行のネックになることはありませんでした(現在はユニットテスト、システムテスト、QAプロセスまで整備しています)。 Q: Djangoはディレクトリ構成を統一しやすいというお話があったかと思いますが、それはstartappコマンドで作られるDjangoアプリケーションの構成はほぼそのままで使われることが多いから似たような構成になりやすい、という意味でしょうか? A: 必ずしもそのまま使う必要は無いと思います。 例えば、django-admin startapp コマンドで作成されるファイルに models.py や views.py などがあります。 我々のプロジェクトでは models/xxx.py, views/xxx.py など、ディレクトリ配下にモジュールを分割して配置しています。 ファイルか ( models.py ) ディレクトリか ( models/ ) という違いはありますが、命名と役割をDjangoのプロジェクト雛形に準拠しています。 Q: RevCommの開発もTDDで行われているのでしょうか A: TDDかどうかは個人に任されております。ただ機能追加したい際や既存の処理を変更した際には合わせてユニットテストを書くという共通認識はあります。 Q: フロントがTS、バックエンドがDjangoという構成なら、最近だとDjangoのかわりにFastAPIを使う選択肢もあるかと思いますが、仮に新規で開発することになった際に、どちらを採用したいと思っていますか? または全く別の選択肢を考えているなら、それについて教えていただけると幸いです。 A: 個人的には TypeScript のライブラリも選択肢に挙げたいところですが、技術者の確保を考えると Python のライブラリになるかと思います。 また、新規サービスの種類にもよりますが FastAPI も選択肢に上がると思います。実際に直近立ち上がったプロジェクトではマイクロサービスとして切り出す API を FastAPI で作ってます。また、3年ほど前に BFF に FastAPI を採用した際には、「asyncio対応、型ヒントへの対応、OpenAPIドキュメントの自動生成、Django ほど多機能ではなくていい」などが決め手になったようです。 Q: 多数のDjangoAppを含むコードベースを運用する上で、DjangoApp同士の依存関係に関して規約や工夫されていることはありますか? A: 規約は特に入れていないです。 複数の App で明らかに何度も利用するものは common ディレクトリに処理を寄せていたり、App間に依存が発生する場合(全文検索のAppと検索対象のAppなど)はSSOTを心がけて依存が複雑にならないようにしています。 全体的に特定の技術に固執しすぎずに、実現したいことに合わせて柔軟に技術選定を行っているという回答でした。また個人の自由もある程度認めながらも、チーム全体のことを考えるという感じですね。 終わりに RevCommが急成長する中で、開発者は日々課題に向き合っています。その過程で得た知見やそのときの判断は社内だけでなく、きっと社外の誰かの参考にもなるはずです。これからもイベントを開催してより良い会にしていきたいと考えています。ぜひとも楽しみにしてください!
アバター
はじめに こんにちは!私はRevCommのCorporate Engineeringグループで主にSalesforce Administrator & Developerとして活動している長谷部です。今回はRevCommが提供するクラウドIP電話サービス「MiiTel」をお客様がご利用を開始するために必要なシステムの内の1つ、「MiiTel Signup」の効率化についてお話したいと思います。 「MiiTel Signup」とは、MiiTelを提供するにあたって必要な法人確認、本人確認システムのことを指します。これは、RevCommが電話転送サービス事業者として遵守すべき犯罪収益移転防止法の要件を満たすために必要なシステムです。 旧システムの課題 今までの「MiiTel Signup」では、業務効率の観点でいくつかの課題がありました。 散らばったシステム : 旧「MiiTel Signup」は顧客情報を管理しているSalesforceとは切り離されたシステムとして構築されていました。これにより、各システム間でデータを連携するために一部手作業での紐づけ業務が発生しており、時間と労力が増大していました。顧客データの一元管理が困難であり、その結果として顧客対応の速度と品質に影響を与えていました。 進捗確認の困難さ : データ連携をする必要があるため、常にリアルタイムで進捗ステータスをアップデートすることができず、法人確認、本人確認の進捗ステータスの確認が煩雑で、作業の効率が低下していました。確認作業は、各システムを切り替えながら行う必要があり、そのたびに時間とエネルギーを消費することとなりました。 上記の課題により、確認作業の工数がそもそも多い上、進捗状況や必要なネクストアクションの特定に手間がかかることで、社内の作業負荷が増幅していました。その結果、重要な業務に集中するための時間が奪われ、全体の作業効率に悪影響を及ぼしていました。 旧システムの概要イメージ 新システムの開発 そこでこれらの課題を解消するために、新しい「MiiTel Signup」システムをSalesforce上に構築しました。 まず始めに、新システムの全体的な構成を理解するために以下のシステム構成図をご覧ください。顧客側入力から確認作業まで全てSalesforce上で完結させるため、以前と比較してシンプルな構成となっています。 新システムの概要イメージ この新システムは、以下のキーポイントを中心に構築されています。 進捗確認の効率化 :顧客が情報を入力する画面はSalesforceのExperience Cloudにより構築され、入力された情報はSalesforce上の顧客データと紐付けられます。これにより、法人確認、本人確認の進捗ステータスを一元管理することが可能になり、データの連携に必要な時間と労力が大幅に削減されたため、煩雑だった作業が大幅に効率化されました。 eKYCサービスの見直し : 新しい「MiiTel Signup」では、本人確認に必要な身元確認書類をWebカメラを用いて提出できるようになりました。これにより、顧客が情報を入力する一連の流れで身元確認書類を提出できるようになりました。また、身元確認書類の提出時に顔貌の撮影を行うこともできるようになりました。これにより、身元確認書類と顔貌の比較ができるようになり、間違いなく本人が提出していることを担保することができるようになったため、今まで必要だった郵送による個人宅への住所確認の実施も不要になりました。 操作性の向上 :Salesforceの取引先レコードページ上に、法人確認、本人確認の進捗状況やネクストアクションが確認できる管理画面をLWC(Lightning Web Component)で実装しました。この画面では、顧客の現在の法人・本人確認の進捗ステータスやネクストアクションを確認することができ、確認作業における工数を大幅に削減することに貢献できました。 以下のイメージは、この新しい管理画面の一部抜粋です このようにして、新しい「MiiTel Signup」は、顧客との契約に必要な法人確認、本人確認を効率的に行うためのツールとなりました。次のセクションでは、これらの改修がもたらした具体的な効果について説明します。 改善後の効果 新たな「MiiTel Signup」をSalesforce上に構築したことにより、私達は様々な面で大きな効果を得ることができました。 情報管理の効率化 :旧システムでは情報が分散していましたが、新システムでは全ての顧客情報と確認ステータスがSalesforce上で一元管理されるようになりました。これにより、全て顧客のデータに紐づいてeKYCのデータが紐づくため、情報の探し出しにかかる時間と手間が大幅に減り、全体の業務効率が向上しました。 レポート機能の活用 :Salesforce上で情報が一元管理されるようになったことにより、Salesforceのレポート機能を活用することができるようになったため、作業が必要な取引先のみを瞬時に一覧化することができるようになり、必要な作業の優先順位付けやスケジュール管理が容易になりました。また、Salesforceのレポート機能は非常に柔軟かつ簡単に抽出内容や抽出条件を変更したりできるので、Adminチーム側で必要な情報を抽出するためのレポートを必要に応じて柔軟に作ることができるようになりました。 確認作業の効率化 :取引先レコードページ上に管理画面を構築したことにより、社内での確認工数が大幅に削減されました。この画面では、顧客の法人確認や本人確認の進捗状況をリアルタイムで把握し、必要なネクストアクションを明確にすることができます。これにより、確認作業の精度が向上しただけでなく、無駄な手間を削減し、手作業によるミスを防止することも可能となりました。 これらの改善により、社内の業務効率化が図られ、全体としてMiiTelのサービス提供能力の向上に貢献できました。Adminチームのメンバーからも「以前に比べて使いやすくなり、確認作業の工数も大幅に削減できました」という声をいただきました。 まとめ 本記事では、MiiTelを提供するための法人確認・本人確認プロセスを効率化するためのシステム「MiiTel Signup」の再開発についてお話しました。これは我々が犯罪収益移転防止法を遵守するための重要な取り組みです。 旧システムでは顧客情報の一元管理が難しく、法人確認・本人確認の進捗状況の確認が煩雑な状況にありました。そのため、確実な法令遵守を実施するために多くの工数がかかっておりました。しかし、新システムにより、これらの課題が大幅に解消され、工数削減や法人確認・本人確認のリードタイム短縮など、様々な業務効率化が実現しました。 今後も私達は、更なるサービス改善を目指して、必要な改善を逐次行っていきます。今回の取り組みが、業務効率化やCRMの活用に興味のある方々の一助となれば幸いです。
アバター
※この記事はバックエンドエンジニアRaman Yachiによる記事『 E2E Testing system for Miitel Account 』を翻訳したものです。 はじめに こんにちは、バックエンドエンジニアの谷地ラマンです。 RevCommではマイクロサービスアーキテクチャを採用しており、私はその中で認証/認可の機能を提供するAccountチームに所属しています。 ユーザーのログイン認証を処理する重要な部分であり、ここに障害が発生するとユーザーがサービスにログインできなくなる可能性があるため、可能な限り防ぎたいです。 そのための対策としては、第一に全ての機能に対応する単体テストを実装することです。 私のチームではテストフレームワークであるpytestを使用し、Pull Requestにおいて単体テストが実行されるためコミットごとの機能を保証し、あるいはバグを検出することができます。 単体テストに加えて、実際のユーザーシナリオとしての振る舞いを確認するためのシステムテストを実装しています。これは実環境のAPIエンドポイントに対してPostmanによるテスト (E2Eテスト) を実行し、レスポンスを検証しています。 この記事では私たちのE2Eテスト自動化について紹介します。 課題 テストを自動化する前は、各メンバーがローカルマシン上でE2Eテストを手動実行してデプロイ後のサービスが期待通りの動作をすることを確認していました。 しかし、例えばあるメンバーの環境では成功していたものが別のメンバーは失敗したりと、テストの動作を統一できていないことが課題でした。 結果として、テストの信頼性が低くなってしまいました。 また、開発/ステージング/本番など、環境ごとにPostmanの変数を使い分けることも面倒でした。 そこで、リリース後の不具合を検知するためにより良い方法がないかどうか検討しました。 これまでのことから、私たちの要件は次の通りです。 常に最新のアプリケーション(URL構造やインターフェース)をテストできること 非ローカル環境で実行することで、テスト結果をチーム内で共有できること 最小限の設定内容のみを必要とするシンプルな仕組み 解決策 まず最初に、Postmanによるテストの実行をAWS CodeBuildに移行しました。CodeBuildはAWS CodeDeployによるリリースの後に起動されます。 これによりテストは常に最新のアプリケーションを対象とし、かつ個人のローカル環境に依存しないプラットフォームで実行できます。 The e2e testing pipeline 詳しく説明します。 ソースコードの修正を取り込むと、GitHub Actionsを介してCodeDeployによるデプロイプロセスが起動します。CodeDeployの正常終了をトリガーにして、CodeBuildによるE2Eテストが起動します。 CodeBuildの処理の中で、リリース直後のアプリケーションに対してAPIリクエストを実行します。 この中でPostmanのCLIツールであるNewmanを使っています。 https://learning.postman.com/docs/collections/using-newman-cli/command-line-integration-with-newman/ これによって、PostmanのテストケースをCodeBuildで実行することができます。 テストの実行結果はCodeBuildのレポートとしてアップロードされます。 CodeBuildの処理が終了すると、そのレポートを通知するLambda関数を起動します。Lambda関数はレポートをパースしてテストの結果をSlackチャンネルに送信します。 テスト結果の通知例を示します。テストの成功件数と全体件数、そしてタイムスタンプが分かります。 特定のテストケースが失敗した場合は、該当のテストケース名を添えて通知します。 ここまでで説明してきた仕組みに関するAWSのインフラ環境やテストケースのレシピはGitHubリポジトリで管理しています。 AWS環境の構成管理、変更はTerraformで管理しています。 またCodeBuildはソースプロバイダーの指定によってこのリポジトリからテストレシピを取得できるため、常に最新のテストケースでPostmanによるE2Eテストを実行できます。 これにより、ここまでで述べてきた自動テスト全体の仕組みを1つのリポジトリを管理することで完結させています。 これらのパイプラインによってCI/CDとしてバックエンドをテストできます。 テストが必要になるたびに開発者の生産性を低下させることなく、信頼性の高いテストを実行できます。テストの結果をすぐに確認できて、元となった修正も簡単に追跡できます。 まとめ 最後に、これは私にとってTerraformとCI/CDへの初めての挑戦でしたが、このタスクを任されたことは幸いでした。 自分で問題に取り組む裁量が与えられていたし、分からないことはいつでも同僚からアドバイスしてもらえました。 同じように問題解決に主体的に取り組める人なら、RevCommはあなたにとって最適な環境だと思います! (翻訳・編集: 小門照太 RevComm Technology Dept, Backend Group)
アバター
Intro Hello, my name is Raman Yachi. I am an engineer here at RevComm working on the Accounts team. Our product suite at RevComm follows a microservices architecture and I would like to talk about how we automate testing our Account backend, which is a pivotal part of the backend as it deals predominantly with user authentication. Failures here could lead to users being unable to log into our services, which is something we want to avoid as much as possible. Our first line of defense against that is ensuring all our features have corresponding unit-tests. For the backend we use Pytest as our testing framework and each commit merged to a PR triggers the whole battery of tests so that we can guarantee functionality on a commit-by-commit basis and know exactly where breaking changes were introduced. Unit-tests do not convey the whole story so in addition we run system tests to ensure performance in real-world scenarios. This is done by running Postman tests (E2E Test) against our live server’s API endpoints and validating their responses. Issue Prior to having automated the tests our team used to run manual API tests from local machines using Postman to ensure that the newly deployed service was working as intended. The issue with that was the test suites, while version controlled, were not ensured to be uniform. So someone’s test could fail and another’s could succeed and the only way to tell is by lining up the backend and test versions. This made the testing process unreliable as it becomes hard to tell which machine’s result is correct at first glance. Furthermore co-ordinating variables between the production, staging and development environments could become a hassle for people not used to the Postman product. So we sought for an alternative that served as a single source of truth regarding whether the changes shipped broke any endpoint. From these key requirements we know that we need: A testing framework that tests the backend with correct (most recent) API structure (endpoint URL, body format etc.), and executes on non-local infrastructure so that results are available across the team. A simple enough interface that requires minimal configuration on the user end What we did To accomplish this our first step was simply migrating the Postman test runs to a CodeBuild instance, which ensures that the platform is up-to-date and independent to our machines. Once the tests were set up we still needed a method to trigger them, along with a notification system. This was accomplished using the architecture below. To the left of the CodeBuild testing is our Trigger portion of the pipeline and to the right the Notification mechanism. The e2e testing pipeline Every time we release to our environment a respective deployment is triggered in CodeDeploy via Github Actions. At the successful conclusion of this deployment we can assume that the new release is now available and we initiate our integration tests. We do this in the next step by triggering a CodeBuild build. CodeBuild then tests our new backend instance by testing the API of the backend by mimicking user API calls (engaging with the user-facing endpoints). The tool we use for that is Newman, Postman’s CLI counterpart. https://learning.postman.com/docs/collections/using-newman-cli/command-line-integration-with-newman/ This allows us to craft/debug test-cases in Postman and then have our CodeBuild instance run those tests. These test-case results are uploaded to CodeBuild’s report. The conclusion of this CodeBuild run will then trigger a Lambda function that receives the CodeBuild Report. The Lambda will then parse the report and send a message to a dedicated Slack channel that informs everyone of the test’s conclusion and results . An example result from the E2E tests is shown below, where we get the pass/total count, and timestamp: Should tests fail the team is notified by their name being included in the report: With this we have gained the ability to confidently know whether our service is functional after every merge. And with the Slack integrations any failure can be converged upon much quicker. Thus fixes can be issued faster too. The AWS infrastructure, along with the testing recipes are managed by us in a single repository. The test recipes are handled with Postman, while infra changes are affected via Terraform. This repo also serves as the instruction set for our CodeBuild testing instances. What this means is that our Postman test recipes are version controlled in the same repo, to ensure the tests are always up to date whenever a E2E test run is initiated. Thus the whole testing pipeline is managed in a self-contained manner and allows us to hermetically test our backend. Conclusion With the new pipeline we can test our backend in a CI/CD manner which ensures developer productivity does not take a hit every time testing is required and the tests conducted are reliable, the results readily available and also easily traced back to their respective changes. Parting thoughts for this is that I really enjoyed this task as this was my first foray into Terraform and CI/CD and being tasked with the problem despite that was a blessing in disguise. I was given free reign to tackle the problem on my own, and whenever my lack of experience became apparent my colleague’s were able to provide advice and direction – and if you are someone who similarly enjoys working autonomously on interesting problems I believe RevComm would be a great place for you to contribute and grow!
アバター
2023年4月28日(金)に、【RevCommのエンジニアの開発組織とは】というオンラインイベントを開催しました。この記事ではイベントの内容に触れながら、時間の関係でイベントで触れることのできなかった情報を紹介します。 イベントは3つのテーマに分けて、プロダクトや働き方、カルチャーを紹介しました。 RevCommという会社と開発しているプロダクトについて 開発組織について 現場のリーダーの考えについて イベントの動画も公開しています。 www.youtube.com 急成長しているスタートアップの1つの開発組織のあり方として参考になると思います。ぜひご覧ください! RevCommの開発組織の中心にいる4人の登壇者 今回の登壇者は、RevCommの開発組織の中心にいる4人。執行役員/CTOの平村と、執行役員/Senior Engineering Managerの瀬里、Engineering Managerの川添と、Backend Engineerの大谷です。 役職としてはマネジメントやリーダーのポジションですが、全員がコードも書きます。 RevCommではおおよそ8 〜 9割ほどのリーダーやマネージャーが、マネジメントをしながらも開発をしています。 技術を深く理解し、チームワークを駆使し、コミュニケーションの再発明に向けてプロダクトの改善や、新規プロダクトのリリースに向けて日々向き合っている4人です。 それでは、イベントの内容に踏み込んでいきましょう。 RevCommの会社組織と主要プロダクト まずはCTOの平村からRevCommがどういう企業なのか、そしてどんなプロダクトを作っているのかの説明です。会社概要・ミッション・プロダクトの説明やMiiTelのデモをしました。 平村は、高い技術力を持ちながらもビジネスの企画が得意で、両方についてわかりやすく伝えることができるCTO。ミッションである「コミュニケーションを再発明し、人が人を想う社会を創る」と「なぜその中で音声にフォーカスするのか」という話のあたりから熱が入ります。 「(テキストコミュニケーションと比較して)音声のコミュニケーションはまだ全然データ化もされておらず、検索・分析や、AIが人の代わりに何かをするような試みにまだ繋がっていません。これはビジネスチャンスなんじゃないかと。こういったサービスやプロダクトを作ろうと集まったメンバーが作った会社です」 次にRevCommの主力サービスである、MiiTelの紹介です。 「電話営業のブラックボックス化問題という課題を解決したい」という目的と、1つ1つの機能についての説明をしています。 動画内では デモ も行っています。MiiTelを使ったことのない方も多いと思うので、ぜひ動画のデモもご覧ください。 RevCommのエンジニア部門について 次に、執行役員/Senior Engineering Managerの瀬里からRevCommのエンジニア組織についての説明です。 マトリックス組織という体制をとっていること、アジャイル開発を行っていること、使用している言語やツール、社員間でのコミュニケーションも大切にしていることについて話しました。 「弊社のマトリックス組織とは、個人がテクノロジーチーム(フロントエンドやバックエンドといった職能ごとのチーム)に所属し、それぞれのチームから人が集まってプロジェクト(MiiTel Analyticsや新規プロジェクト)を作り上げるという組織体制です。特徴的な制度として、時間さえあれば自身の配属されたチームとは異なる興味の分野のタスクも、担当していいという制度(15%ルール)があります」 例えば、筆者の知っている範囲でも、フロントエンドエンジニアがモバイルアプリ開発のためFlutterを扱ったり、バックエンドのタスクを担当したりということがあります。 また、瀬里は社員同士のコミュニケーションについても語ります。 「フルリモート、フルフレックスだからこそコミュニケーションは活発です。対面でも、年に4回ほどチームのミーティングなどで会う機会があります。普段の業務ではSlackだけで解決しない問題はすぐにビデオ会議をしたりします。また、社員によっては、休みのときに旅行先にいる社員と会って飲み会をしているということもあります」 その他、何か困ったことがあるときに助けを求めるためSlackにhelpmeチャンネルがあるということなどが話題に上がりました。 プロジェクトとエンジニアの紹介 今までは会社全体やエンジニア組織全体についての説明が中心でした。次に各プロジェクトのメンバーをまとめる2名の紹介です。 規模が小さくスピードが求められるプロダクト群を扱うEngineering Manager まずはEngineering Managerの川添から。川添はCorporate Engineeringというチームのリーダーをしていて、主にセールスやカスタマーサクセスなど社内のメンバーが業務で使うシステムを開発しています。 「スピードが求められるので、プレッシャーを感じることはあります。一方で融通も利くので、バランスをとりながら進めています」とのこと。 「社内のメンバーが使うシステムを扱っているからこそ、自分たちの作ったものの上で、ビジネスを動かしていくことができる」という所にやりがいを感じているそうです。 その他、川添は社内の開発者が自分の専門外の技術を学ぶ機会を作っていることにも触れています。 自分のチームだけではなく、社内のエンジニアの技術向上の機会を作っていただけるのが素晴らしいですね!(実は筆者もお世話になっています。) チームの連携をとりながら全体も俯瞰するBackend Engineer 次はBackend Engineerの大谷です。入社して半年ほどですが、多方面で活躍しています。 プロジェクトマネージャーの補佐もしており、担当しているのは、通話の分析結果を表示するMiiTel Analyticsというプロダクト。MiiTel AnalyticsはMiiTelの中心とも言える存在です。 「MiiTel Analyticsは他のチームと連携する必要がある部分も多く、各チームのタスクの調整を行うこともある」そうです。 また、「プロジェクトマネージャーと連携して、Analyticsチームの役割がこのままで良いのかということや、プロジェクト管理のやり方も見直しを図りながら進めています」とのこと。 大谷はMiiTel Analytics以外にも、組織全体のプロジェクト管理のあり方について改善を図るチームにも、自分で手を上げて参加しています。 入社歴に関わらず、意欲のある方が自分の力を発揮できるところはRevCommの良いところです。 おわりに 上記のような内容が座談会では話されました。 この他にも、モデレーターの小畑がよく聞かれる質問への答えも登壇者から引き出しています。また、応募者の方向けにフォロー体制やキャリアパスなどにも触れています。 少しでも興味が湧いたらぜひ 動画 をご視聴ください! また、RevCommは7月5日(水)の正午にDjangoをテーマにした技術勉強会を開催します。 世界に認められたAIスタートアップが、Djangoを使って感じる良さとは? オンラインでの開催です。是非ともイベントへのご参加をお願いします!
アバター
Research Engineerの大野です。 新しいスライドを公開したのでご紹介します。 speakerdeck.com スライドの概要 ここでは、機械学習モデルの学習の際のメモリ要件を下げることができる、Low-Rank Adaptation (LoRA) の評価を行いました。 言語モデルの大きさが加速度的に増えており、それに伴いハードウェアの要件が大きくなっています。第1回LLM勉強会の資料の図を下記に引用し、近年に作成された言語モデルのパラメータ数を示します。 第1回LLM勉強会の資料の図 評価では、対話要約のデータセットである[Gliwa 19]のSAMSumコーパス(コーパスへのリンク)を使用し、ファインチューニングに必要な時間とGPUメモリを計測しました。また、ROUGEスコアを使用してそのモデルの性能を評価しました。実験では、NVIDIA A10G Tensor Core GPUを持つAWS EC2のg5.xlargeを使用しました。 スライドの結論 評価の結果、LoRAを使用することで、ファインチューニングに必要なメモリが低減することを確認しました。また、同じデータ量を使用した場合には、大きなモデルが小さなモデルと比べて性能が高いことも確認しています。このことは[Kaplan 20]でも示されています。 [Kaplan 20]の図 LoRAの関連研究はこのスライドの中で扱っていません。[Lialin 23]や[Hu 23]が関連研究をまとめていますので、興味がある方がいらっしゃいましたらご確認ください。これらに載っていない関連研究では、[Zhang 23]や[Dettmers 23]が注目を集めています。 引用 [Dettmers 23] Dettmers, T., Pagnoni, A., Holtzman, A., and Zettlemoyer, L.: QLoRA: Efficient Finetuning of Quantized LLMs (2023) [Gliwa 19] Gliwa, B., Mochol, I., Biesek, M., and Wawer, A.: SAMSum Corpus: A Human-annotated Dialogue Dataset for Abstractive Summarization, in Proceedings of the 2nd Workshop on New Frontiers in Summarization, pp. 70–79, Hong Kong, China (2019), Association for Computational Linguistics [Hu 23] Hu, Z., Lan, Y., Wang, L., Xu, W., Lim, E.-P., Lee, R. K.-W., Bing, L., and Poria, S.: LLM-Adapters: An Adapter Family for Parameter-Efficient Fine-Tuning of Large Language Models, arXiv preprint arXiv:2304.01933 (2023) [Kaplan 20] Kaplan, J., McCandlish, S., Henighan, T., Brown, T. B., Chess, B., Child, R., Gray, S., Radford, A., Wu, J., and Amodei, D.: Scaling Laws for Neural Language Models (2020) [Lialin 23] Lialin, V., Deshpande, V., and Rumshisky, A.: Scaling Down to Scale Up: A Guide to Parameter-Efficient Fine-Tuning (2023) [Zhang 23] Zhang, R., Han, J., Zhou, A., Hu, X., Yan, S., Lu, P., Li, H., Gao, P., and Qiao, Y.: LLaMA-Adapter: Efficient Fine-tuning of Language Models with Zero-init At- tention (2023)
アバター
2023年7月5日(水)12:00 より、RevComm主催の技術勉強会を開催します。 revcomm.connpass.com イベント内容 近年、PythonのWebフレームワークとしてFastAPIが注目されています。 一方で、Djangoもバージョンアップを重ね、より使い勝手の良いものに。 そんな2つのWebフレームワークをRevCommは使い分けています。 RevComm はPythonを得意とする開発者が多く在籍するスタートアップ。 AIを活用した音声コミュニケーションのイノベーションに取り組んでおり、 米国の「Forbes AI 50 2023」にもアジアで唯一選出されています。 レブコム、米国の「Forbes AI 50 2023」に選出 アジアで唯一、最も有望なAI活用企業として表彰 今回のイベントでは、RevCommの開発者がDjangoに感じている魅力と今注目して取り組んでいることを題材に、質問をどんどん取り入れながら、フランクにディスカッションしていきます。 日々課題に取り組んで得た知見は、社外の方にもきっと役に立つはずです。 参加登録はこちら 登壇者 近藤 智哉(こんどう もとや)Backend Engineer tech.revcomm.co.jp 小門 照太(こかど しょうた)Backend Engineer tech.revcomm.co.jp モデレーター 小山 功二(こやま こうじ)Frontend Engineer / Dev Relチーム所属 参加登録 参加登録は、connpassにて受け付けております 。奮ってご参加ください。
アバター
はじめに こんにちは。RevCommでCorporate Engineeringチームで活動している川添です。 今回のブログでは、オンライン申し込みからお客様専用の環境構築までの一連の業務プロセスを自動化するテクニックについて解説していきたいと思います。業務効率化や自動化に興味がある方はぜひ参考にしてみてください。 自己紹介 まず自己紹介をしておきますと、私は2020年7月にRevCommに入社して、主にCorporate Engineering領域で活動しつつ、フルスタックチームとしても社内チーム横断プロジェクトの管理などをしております。 これまでの経歴としては、ITコンサルティングの会社で基幹システム導入など、いわゆるSIer業務のようなことを行い、業務プロセスとシステムの整理や設計などをやってきました。今回はそのような経験も活かして、どのようなシステムを構築したかをお話ししたいと思います。 1. プロジェクト背景 これまで、弊社ではオンラインで契約やお客様用のテナント発行までを完結することができるものはありませんでした。そのため、お客様がMiiTelを利用するためには、必ず弊社のメンバーと商談や打ち合わせをする必要があり、気軽に製品を試したいというニーズにお答えすることができていない部分がありました。 そこで、今回 MiiTel Meetings (旧称: MiiTel for Zoom )の名称変更に伴う無償提供キャンペーンに合わせて、顧客満足度向上や作業効率化を目指し、オンライン申し込みのシステムを開発するプロジェクトが発足しました。 2. 業務プロセスを整理する まず、どの部分を自動化すべきかを見極めるために、現行の業務プロセスをしっかりと理解することが重要です。業務プロセスを整理し、それぞれのステップがどのように影響しているかを把握する必要があります。この段階で各チームとの協力が必要となります。各部門の意見を収集し、業務プロセスを再設計することが求められます。 私はこの段階で業務フロー図を必ず作成するようにしています。 言葉でのやり取りは曖昧なもので、同じ会社のメンバーでもそれまでの経験や、所属しているチームによって言葉の定義が違ったり、イメージしているものが異なったりします。そのため、業務フロー図を書いて、認識齟齬をなくし抜け落ちているプロセスがないかを洗い出します。 この部分の整理が甘いと、後の開発のプロセスで手戻りが多くなってしまうので、丁寧に進めることをおすすめします。 イメージ図: オンライン申込み業務フローチャートサンプル 2-1. システム化するポイント・しないポイントの整理 業務フロー図を作成している中で、システム化(自動化)するポイントとしないポイントの整理も行います。オペレーションを自動化しない場合は、社内のどこかの部署にオペレーションを担当していただくことになります。 システム化すべき部分を見極めるのは難しいですが、「実装工数」・「確証性」・「納期」などがポイントになってくると思います。 「実装工数」や「納期」は言葉の通りです。「確証性」は、そのオペレーションが今後変更される可能性(逆に言えば変更されない可能性)がどれだけあるかを意味して書いています。オペレーションのやり方が今後ガラッと変わったり、細かくても何度も変わる可能性があれば、自動化しないほうがいいでしょう。 逆にオペレーションが変わらない可能性が高ければ、自動化してしまったほうがより効率的な仕組みを作ることができます。 3. アジャイル的なプロトタイプ開発 プロセスの整理ができたら、次にプロトタイプを作成しましょう。プロトタイプを作成する目的は、システムの全体像を把握し、各チームとの調整をスムーズに進めることにあります。アジャイル開発手法を取り入れることで、段階的にシステムを改善・拡張しながら、各チームと連携してより良いシステムを目指します。 見落としがないように進めたとしても、作ってみると意外と抜けているポイントがあったり、「実際やってみるとこうしたほうがいい」ということが発生しがちです。そのため、納期ギリギリに初めて動くものができましたというやり方より、小さく作って認識合わせを細かくするほうがいいと思います。 実際に今回のプロジェクトでも、解約のフローに関してのプロセスの見直しが起きました。解約を受け付ける際のデータの流れに各チームでの認識齟齬があり、プロトタイプ実装中に問題が発覚し再検討・再実装が必要となった部分がありました。 業務プロセスに関わるものは、部署やチーム横断的に多くの人が関わることが多いです。そのため、ボールの取りこぼしというのは絶対に発生するもの、くらいの認識で進めるといいかもしれません。 私の場合は、プロセスの見直しがある前提で、見直すべき箇所をいち早く見つけるためにプロトタイプでの実装をよく使います。 4. 全体のシステム構成 前置きが長くなってしまいましたが、ここからが実際のシステムの話です。実際にどのようなものをどのような技術で構成したかをお話したいと思います。 まず具体的な機能を紹介します。当システムではお客様が専用フォームに必要事項を入力するだけで、独自の環境が自動的に構築されるとともに、MiiTel Meetingsを使うためのセットアップも自動的に実行されます。 さらに、お客様が当システムを利用するにあたって、事前に利用規約に同意することが必須となっております。利用規約ページでお客様により同意操作が行われた際に、お客様のアカウント情報が自動的にメールで送信される機能も備えています。 以上により、お客様はオンライン上のフォーム入力だけでMiiTel Meetingsの利用を開始できます。 続いて、上記のシステムを構築するために用いた技術スタックを紹介します。システム全体の俯瞰図は以下のとおりです。 オンライン申込みシステム俯瞰図 4.1 インフラ インフラは全てAWS上で、後述のとおりサーバーレスアーキテクチャとなっています。常時アクセスされるものではないので、必要なときに必要なだけ稼働する仕組みにしています。 IaCはTerraform でベース部分は構築しており、バックエンドのAPIの管理はServerless Framework を活用しています。 4.2 フロントエンド 社内でも広く使われているReactを用いました。(create-react-app でプロジェクト作成しています) オンライン申込みのフォームはWordPressで構築されているプロダクトLPに置くので、最終的にはビルドしたファイルをサーバに置くようにGitHub ActionsでCI/CDを組んでいます。 また、ページがサブディレクトリ配下でも正しく動くように、以下の設定をいれています。 package.json { " name ": " revcomm-online-application-front ", " version ": " 0.1.0 ", " private ": false , " homepage ": " https://miitel.com/jp/cpform/meetings/ ", … } 実装においては、使いやすく、わかりやすいUI/UXを心がけるようにしました。ページのデザインは社内のデザイナーが担当したものになりますが、使いやすさの観点でいくつか工夫をしています。 例えば、入力ミスがあった場合にはわかりやすいメッセージを出したり、メッセージの箇所までスクロールで遷移させたりしてお客様が気づきやすいように作っています。また、登録処理に時間がかかる場合は途中で離脱してしまわないよう、処理の進捗状況を画面に表示させてお客様がどれくらい待てばよいのかを知らせています。 後述しますがバックエンドはAWS Lambdaで実装しています。そのため、立ち上げがスムーズになるように、ページにアクセスされたときにヘルスチェックリクエストを送ってあらかじめバックエンドを立ち上げておく工夫も行っています。 const TopPage = ( props ) => { // コンポーネント初期化時にバックエンドを立ち上げておく useEffect (() => { (async () => { await APIClient. get( "/api/health" ); } )(); } , [] ); } 4.3 バックエンド バックエンドはAWSのサービスを利用しています。API GatewayとAWS Lambda上に、PythonのFast APIというWebフレームワークを用いて構築しています。 データベースは社内の既存システムを利用しているため、このシステム自体に対するデータベースはありません。 そのため、軽量かつバリデーションも簡単でありながらしっかりと行えるFast APIを選択しました。 バックエンドの実装で特に気をつけたポイントは、社内では「Adminエンドポイント」と呼んでいるAPIを実装しておいたことです。 これは、お客様が処理の途中で離脱してしまった場合や、社内オペレーションミスなどで特殊な作業をする必要があった場合に、データの整合性を後で取る運用のためのエンドポイントです。 あらかじめ作っておくことで、安心感も違いますし、柔軟な対応ができています。 4.4 バッチ 申込時に途中離脱が発生したかどうかをチェックしたり、解約の意思があった際に自動的にお客様の環境を停止したりする処理には、AWS Batchを利用しています。 そこまで重たい処理でもないのですが、一部処理に時間がかかる可能性があったり、処理件数が増えてきた場合に備えて初めからAWS Batchを使って実装しています。 4.5 監視 弊社ではDatadogをログやパフォーマンスの監視に用いているので、このサービスにおいてもそれを組み込んでいます。アラートを設定しておいて、何か問題があったときに検知できるようにしています。 お客様はこういった申込みシステムで、何かあったら問い合わせなどはせず離脱して終わってしまうことが多いので、何かあったときにシステムが検知できるかどうかは非常に重要です。 5. 結果と展望 プロセス整理から始まってリリースを行い、問題なくテナント発行がされる仕組みが構築できました。実際にお客様からの申し込みもあり、社内の対応を効率的に行うこともできています。 今回は、MiiTel Meetingsの無償キャンペーンのみの対応ですが、今後はより幅を広げて、より多くのお客様にRevCommのプロダクトを体験してもらうことができる仕組みを作りたいと考えています。
アバター
こんにちは、RevCommでMiiTelの音声解析機能に関する研究開発を担当している石塚です。 石塚賢吉(いしづか けんきち) プリンシパルリサーチエンジニア。筑波大学大学院博士後期課程卒業。博士(工学)。日本HP株式会社にて通信事業者向けのシステム開発、株式会社ドワンゴで全文検索システムの開発などに従事。2019年12月、株式会社RevComm入社。音声認識、音声感情認識、全文検索システムの研究開発を行なっている。 → 過去記事一覧 2023年1月に開催された国際会議 IEEE Workshop on Spoken Language and Technology (SLT) 2022 で発表された E-Branchformer: Branchformer with Enhanced Merging for Speech Recognition (Kim et al., 2023) *1 という論文で、音声認識タスクで高い性能を発揮する E-Branchformer という新しい深層学習モデルが提案されました。論文中では英語の音声コーパスを用いて音声認識精度が評価されていますが、日本語についての評価は行われていません。 End-to-end音声処理ツールキット ESPnet のversion 202301からこのE-Branchformerが利用可能となったので、本記事では日本語の音声コーパスである 日本語話し言葉コーパス (Corpus of Spontaneous Japanese; CSJ) (Maekawa, 2003) *2 でモデル構築および音声認識の精度・スピードの評価を行ってみます。 本記事の内容は以下のとおりです。 E-Branchformerとは 日本語音声コーパスCSJでの利用方法 得られたモデルの音声認識の精度とスピード モデルの学習 音声認識精度の評価 音声認識スピードの評価 まとめ E-Branchformerとは 2020年のINTERSPEECH で発表された Conformer: Convolution-augmented Transformer for Speech Recognition (Gulati et al., 2020) *3 において、Transformerとconvolutional neural network(CNN; 畳み込みニューラルネットワーク)を組み合わせた深層学習モデルである Conformer が提案されました。Conformerでは、TransformerのMulti-head self attentionでグローバルなコンテキスト情報を捉え、CNNでローカルなコンテキスト情報を捉えます。Conformerをエンコーダーに使用した音声認識モデルは、Transformerの音声認識モデルよりも高い音声認識精度を発揮し、発表時点におけるstate of the art(SOTA; 最高性能のモデル)でした。 ConformerのEncoderの構成 このConformerに触発され、 2022年のInternational Conference on Machine Learning (ICML) で発表された Branchformer: Parallel MLP-Attention Architectures to Capture Local and Global Context for Speech Recognition and Understanding (Peng et al., 2022) *4 において、並列に分岐する2つのブランチで情報を捉える Branchformer が提案されました。上記の図のように、ConformerではMulti-head self attentionモジュールの後にCNNで構成されるConvolutionモジュールが続く形となっており、グローバルなコンテキスト情報とローカルなコンテキスト情報を 逐次的に 扱っていました。一方で、Branchformerでは下記の図のように、1つ目のグローバル抽出ブランチでMulti-head self attentionによりグローバルなコンテキスト情報を捉え、もう1つのローカル抽出ブランチでconvolutional spatial gating unitを利用してローカルなコンテキスト情報を捉えます。そして、後段で 各ブランチの出力をマージ することにより、音声認識タスクでConformerと同等の性能を達成しています。なお、Branchformerのマージモジュールでは、 をグローバル抽出ブランチによる出力、 をローカル抽出ブランチによる出力としたとき、 と を連結し、線形射影で次元を削減します。 ここで、 は線形射影の学習可能な重みを表します。 BranchformerのEncoderの構成 そして、 E-Branchformer はBranchformerのマージ処理部分を改良したものとして提案されました (Kim et al., 2023)。Branchformerでは、2つのブランチの出力は点別かつ線形に結合されていました。E-Branchformerでは局所的な情報の統合を強化するために、マージモジュールにdepth-wise convolusionによる深さ方向の畳み込みを導入し、2つのブランチからの情報を結合する際に ローカルな情報とグローバルな情報を逐次的かつ並列的に組み合わせる ことで、Branchformerを強化しています。 をグローバル抽出ブランチによる出力、 をローカル抽出ブランチによる出力としたとき、E-branchformerではこれらを下記のようにマージします。 ここで、 はdepth-wise convolusion、 は線形射影の学習可能な重みを表します。また、E-Branchformerでは、TransformerやConformerにならい、グローバル抽出ブランチ・ローカル抽出ブランチ・マージモジュールを挟み込む形でfeed forward network (FFN) のモジュールが追加されています。E-Branchformerのエンコーダーの構成は、上記Branchformerのエンコーダーの構成の図のBranchformer blockを下記のE-Branchformer blockに差し替えたものになります。 E-Branchformer blockの構成 なお、E-Branchformerの論文中では、 LibriSpeech (Panayotov et al., 2015) *5 という英語の音声コーパスを利用して音声認識モデルを構築し、音声認識精度の確認が行われています。以下では、日本語の音声コーパスCSJでE-Branchformerの音声認識モデルを構築し、音声認識精度とスピードをConformerの音声認識モデルと比較してみます。 日本語音声コーパスCSJでの利用方法 E-Branchformerは ESPNetのv.202301 から利用できる状態になっていますが、日本語の音声コーパスに対応したレシピはまだ存在しない状態です。そこで、 英語の音声コーパスであるLibriSpeechのレシピの中にあるE-Branchformerの設定 を、日本語音声コーパスCSJのレシピにコピーして利用します。 ESPNetのv.202301の学習環境とCSJのセットアップが完了した状態から、E-Branchformerを用いた音声認識モデルを構築する手順は下記のとおりです。 LibriSpeechのレシピの中にあるE-Branchformerの設定ファイル train_asr_e_branchformer.yaml を CSJレシピのconfディレクトリ の配下にコピーする CSJレシピの学習スクリプトの学習設定ファイルの参照先 をasr_config=conf/train_asr_e_branchformer.yaml にする run.sh を実行する 得られたモデルの音声認識の精度とスピード モデルの学習 本実験では、NVIDIA V100を4つ搭載した ABCI のrt_Fノードで音声認識モデルの学習を行います。デフォルトの学習設定のバッチサイズではout of memory (OOM) が発生してしまうので、batch_binsの設定を1/8 (140,000,000 / 8 = 17,500,000) にしました。また、言語モデルは使わないこととします。 CSJの学習データを用いてデフォルトの80エポックまで音声認識モデルの学習を行ったところ、学習曲線は下記のようになりました。なお、音声認識モデルの学習には約130時間かかりました。 音声認識精度の評価 上記で学習したE-Branchformerの音声認識モデルを用いて、言語モデルなしでCSJのテストセットを音声認識したときのCharacter Error Rate(CER; 文字誤り率)と、 学習済のConformerのモデル を用いて、同じく言語モデルなしでCSJのテストセットを音声認識したときのCERを下記の表に示します (%)。表を見ると、 E-BranchformerのほうがConformerよりCERが0.3から0.7ポイント低く、音声認識精度がよい ことがわかります。 テストセット E-Branchformer Conformer eval1 3.8 4.5 eval2 2.9 3.2 eval3 3.2 3.5 音声認識スピードの評価 次に、NVIDIA A10を搭載するAWSのg5.xlargeインスタンスを用いて、CSJのeval1からeval3のテストセットをGPUで音声認識するときのスピードを下記のReal Time Factor (RTF) の指標で確認しました。 なお、batch_sizeは1、beam_sizeは20としました。E-BranchformerとConformerの音声認識モデルでCSJのテストセットを音声認識したときのRTFを下記の表に記載します。表から分かるとおり、 認識スピードはConformerよりE-Branchformerのほうが少し遅い 結果となりました。 E-Branchformer Conformer 0.297 0.268 まとめ 本記事では、E-Branchformerについて簡単に紹介し、日本語の音声コーパスCSJでE-Branchformerの音声認識モデルを構築し、認識精度および認識スピードについてConformerの音声認識モデルと比較しました。結果として、E-Branchformerモデルの方が、Conformerモデルより高い精度で音声認識ができることがわかりました。一方で、今回構築したE-Branchformerの音声認識モデルは、Conformerの音声認識モデルよりも音声認識処理に少し時間がかかりました。 なお、今回の実験では、E-BranchformerをAttentionベースのEncoder-Decoder音声認識モデルのエンコーダーに適用しましたが、E-Branchformerはconnectionist temporal classification (CTC) やTransducerなどのリアルタイム処理に適した高速な音声認識モデルに適用することもできるようです。認識スピードを重視する場合は、CTCやTransducerとの組み合わせを試してみるとよいかもしれません。 *1 : Kim, K., Wu, F., Peng, Y., Pan, J., Sridhar, P., Han, K. J., & Watanabe, S. (2023). E-Branchformer: Branchformer with Enhanced Merging for Speech Recognition. Proc. IEEE Spoken Language Technology Workshop (SLT) , 84–91. *2 : Maekawa, K. (2003). Corpus of Spontaneous Japanese: Its Design and Evaluation. Proc. ISCA/IEEE Workshop on Spontaneous Speech Processing and Recognition (SSPR) , 7–12. *3 : Gulati, A., Qin, J., Chiu, C.-C., Parmar, N., Zhang, Y., Yu, J., Han, W., Wang, S., Zhang, Z., Wu, Y., & Pang, R. (2020). Conformer: Convolution-Augmented Transformer for Speech Recognition. Proc. INTERSPEECH , 5036–5040. *4 : Peng, Y., Dalmia, S., Lane, I., & Watanabe, S. (2022). Branchformer: Parallel MLP-Attention Architectures to Capture Local and Global Context for Speech Recognition and Understanding. Proc. International Conference on Machine Learning (ICML) . *5 : Panayotov, V., Chen, G., Povey, D., & Khudanpur, S. (2015). LibriSpeech: An ASR Corpus Based on Public Domain Audio Books. Proc. IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP) , 5206–5210.
アバター
はじめに こんにちは。RevCommでPBX (電話交換システム) サーバーの開発等を担当している宮崎です。 RevCommは、電話やオンライン通話による営業活動や顧客応対を支援するビジネス向け通話アプリケーションのMiITelを提供しています。PBXはMiiTelの通話機能を担う重要な技術の一つです。 このたび、ソフトウェアPBXとして世界的に広く活用されているオープンソース「Asterisk」の世界最大のカンファレンスであるAstriCon 2023に参加してきました。 本記事では、AstriCon 2023のイベントや発表の概要、イベント参加を通して知ったことを共有します。 AstriConについて AstriConはSangoma Technologies社の主催するオープンソースのPBX製品「Asterisk」に関する世界最大のユーザーカンファレンスです。 2004年の初回開催以来、ほぼ毎年アメリカの都市で開催されており、1000名近くが参加した年もあったようです。 新型コロナウイルスの影響で2020年、2021年はオンライン開催、2022年は中止となっており、今回は4年ぶりに現地での開催となりました。 開催地: Broward County Convention Center, Fort Lauderdale, Florida 開催期間: Feb 14-16, 2023 参加者: 50名程度 参加者は想像していたより少なく、ベテランの方が多い印象でした。 また、我々以外に日本人の参加者はいないようでした。 会場の様子 初日はスポンサー企業限定のレセプションパーティで、我々は2、3日目に行われた講演形式の発表を聴講しました。 発表の中で特に興味深かった内容をピックアップして紹介します。 Asteriskの最新情報について Sangoma Technologies社のAsteriskプロジェクトリーダーであるJoshua C. Colp (JColp) 氏からAsteriskの最新情報に関する紹介がありました。内容をいくつか紹介します。 E911 (緊急通報) 対応 米国では、E911 (Enhanced 911) と呼ばれる緊急通報サービスがあります。 これは、緊急通報時に自動的に発信元の位置情報 (通常は住所) を緊急通報センター (PSAP: Public Safety Answering Point) に提供する機能です。 AsteriskはE911に対応するため、res_geolocation, res_pjsip_geolocationモジュールを実装しました。 これらによりSIP INVITE messageのSDPに含まれる、位置情報を示すPIDF形式 (XML形式) のデータを追加したり読み取ったりすることができるようになりました。また、これらのデータはMulti-partで送信するとUDPのパケットサイズを超える場合があり、TCPかTLSで送る必要があるとのことでした。 参加者から、実際に使えるのか?という質問があがりましたが、現在のところ1キャリアで試したのみで、本格的な活用はこれから広がっていくものと思われます。 音声認識専用プロトコル (res_aeap) これまでAsteriskを外部の音声認識エンジンと連携させる場合は、各サードパーティごとに用意されたモジュールを使用する必要があり、対応していない音声認識エンジンと連携したい場合は、出力される録音データを外部のアプリケーションでキャプチャして送信する方法しかありませんでした。 今回発表されたAEAP (Asterisk External Application Protocol) は、WebSocketを経由して外部アプリケーションに音声情報を簡単に連携することができます。 サンプルコードも公開されており、簡単にリアルタイムの音声文字起こし (Speech To Text) を実装することができたので、今回のAstriCon参加レポートを社内発表する際、res_aeapを用いて実装した簡単なデモを作成して共有しました。その内容については後述します。 その他アップデート そのほかAsteriskに関しては、ソースコード管理をGerritからGitHubに移動予定であることや、Asterisk用のテストツールであるTest SuiteをPython2 から Python3に書き直したことなどが発表されていました。FreePBX (Asteriskに管理画面がついた商用製品) に関するアップデート等も紹介されていました。 最後に、JColp氏から会場の参加者に利用しているAsteriskのバージョンを質問する場がありました。意外にも、サポート外のバージョンを使っている参加者や、サポートされているかわからない人がたくさんいるということが印象的でした。 サポートされているバージョン (v18, v20) を使っている人:数人 Security fix only (v16, v19) を使っている人:数人 サポートされていないバージョンを使っている人:たくさん サポートされているかわからない人:たくさん Asteriskの活用例 Asteriskの各社における活用例を紹介する内容が多く発表されていました。 業務における利用シーンや、利用している機能・アーキテクチャなどを紹介しており、自社サービスに組み込んでいるケースや、社内利用しているケースもありました。 面白いと感じた内容をいくつか紹介します。 社内業務での活用例 大手量販店チェーンのTARGET社では、店舗の従業員が使うモバイルアプリのバックエンドにAsteriskを採用しているとのことです。 以前は顧客から電話が入った際に従業員をWalkie-Talkie (トランシーバー) で呼び出し、事務所の電話を取らせるというオペレーションでしたが、これを内製のモバイルアプリとハードフォン宛に転送するように改善しました。TARGET社は小売業者でありながらTech CompanyとしてもさまざまなOSSの公開などの活動をしているようです。 金融情報サービス大手のBloomberg社も、社内向けに開発したAsteriskのサービスについて紹介していました。Bloombergでは頻繁に電話を使うこともあり、Asteriskベースの電話システムをバージョンアップを繰り返しながら10年くらい運用しているとのことでした。 ターミナルライクなUIが好まれるため、Slackのようなチャットアプリを社内を独自開発し、アプリ内でクリックtoコールもできるようにしているとのことです。電話代の削減のため、UKからUSに国際電話をするようなケースでは、USのAsteriskを経由させる運用をしています。Asteriskを選んでいる理由は安定しており、標準的なSIPを利用できるからとのことでした。 Asterisk - Kubernetes Kubernetes (K8s)によるAsteriskのクラスタ化に関するトピックが2件ありました。 Stratus Talk社の方による発表では、Stratus TalkというクラウドPBXをEC2のK8sで構成して運用しているとのことでした。単一のノードにおける同時通話を負荷テストすると100コールくらいで音声に途切れが出始めたので、100コールを目安にスケールアップしているとのことです。クラスタはRancher で管理し、Prometheusで監視しているとのことでした。Extension (内線番号) を持たせず、個人宛の通話は全てDID (Direct Inward Dialing) によって実現しているという話でした。 引用: https://github.com/voxoco/k8s voxo社のCTOであるJoe氏もK8sによるAsteriskのクラスタ化に関するトピックで発表していました。voxo社ではKamailioをフロントに置いたk8sの構成を組んだプラットフォームをOSSで公開しています。構成上のポイントとして、共通して使う情報をGlobal KVSに置く点、HPA (Horizontal Pod Autoscaler) を使ったスケールダウン、スケールアップのポリシー, サイジングに関してはCPUに気を配る点、4コアのCompute Optimizeのインスタンスをつかっており、200chを目安にオートスケーリングを入れている点を紹介していました。 Natural Language Intent Based IVR localsplash社のCEOであるDavid氏は、IVRで顧客の発話した内容から適切な呼び出し先に接続するサービスを提供しています。 David氏によるとIVRは、ボタン入力のみを受け付けるレガシーなIVRから、単語の音声入力を受け付ける少し賢いIVR、そしてNatural Language Intent Based IVRと言われる顧客の話した内容から意図を汲み取り、適切な呼び出し先に接続する賢いIVRへと変遷してきたといいます。 Localsplash社は顧客ごとにAsteriskかVicidialのPBXサーバーを提供しており、Spreadsheetにインテント(意図)とキーワードを登録すると、Dialplanが自動的に作られる仕組みを開発しているとのことです。 Natural Language Intent Based IVRの導入後に直面した課題として、IVRの自動応答に対して実際に電話をかけてきた人の44%が何も喋らかったということをあげていました。 ”すみません、よく聞こえませんでした” などといった音声をさらに流すことでその後90%の人が喋るようになったそうです。 機械の音声に対して会話するという体験に慣れていないユーザーが多いので、「例えば、”住所変更がしたい” というようにおっしゃってください」など、どのように話せばいいかを例示するなどの工夫が重要であるとおっしゃっていました。 AstriConのイベントについては以上です。 AEAP を活用した ChatGPT 自動応答電話機能 AstriConの参加レポートを社内で発表した際に、Asteriskの新機能として紹介されていた音声認識専用プロトコル (res_aeap) を利用して自動応対ボットを開発し、そのデモを行いました。 デモの概要 このデモでは発信者の音声入力をres_aeapによるWebsocketでの音声データ送信でテキストに変換後、ChatGPTのAPIにリクエストを投げ、レスポンスのテキストを音声に変換して再生することで、ChatGPTと音声で会話する体験を提供します。 下記のような処理をおこなっています。 通話中に受け取った音声データを、AsteriskがWebsocketクライアントとなりサーバー (図中の aeap-speech-to-text) に送信する。 サーバーは、受け取ったデータをGoogle Cloud Speech APIに送信し、音声認識結果のテキストデータを受け取る。 受け取ったテキストを引数にしてpython3で実装したスクリプトchatgpt.pyを実行する chatgpt.py内で引数で受け取ったテキストをChatGPTのAPIに投げ、レスポンスのテキストを受け取る 受け取ったテキストを自社開発のText-To-Speech API (TTS API) に送り、テキストを音声に変換して受け取る 受け取った音声を再生する res_aeapによるSpeech APIへの音声送信 上記のデモにおけるres_aeapを使用した箇所について紹介します。 /etc/asterisk/aeap.conf [my-speech-to-text] type=client codecs=!all,ulaw url=ws://127.0.0.1:9099 protocol=speech_to_text @language=ja-JP Asteriskのaeap.confにmy-speech-to-textというSpeech engineを定義しています。 /etc/asterisk/extensions.conf [speech_to_text] exten=>550,1,log(NOTICE, 'Start IVR' ) same=> n,Wait(1.5) same=> n,SpeechCreate(my-speech-to-text) same=> n,SpeechStart() same=> n,Playback(please-wait) same=> n,Set(SPOKEN_TEXT=${SPEECH_TEXT(0)}) same=> n,log(NOTICE,${SPOKEN_TEXT}) same=> n,System(python3 /root/chatgpt/chatgpt.py /tmp/rec_${UNIQUEID}.wav ${SPOKEN_TEXT}) same=> n,SpeechDestroy() same=> n,Playback(/tmp/rec_${UNIQUEID}) same=> n,Return() extensions.conf の定義では、 Speech Recognition API の SpeechCreate() に先ほど定義したmy-speech-to-textを指定しています。 これにより、WebSocketクライアントはmy-speech-to-textに指定された URL への接続を試行します。 my-speech-to-textに指定した ws://127.0.0.1:9099 をListenするWebSocketサーバを、サンプルコードとして公開されている こちらのアプリケーション を利用して起動します。 このWebSocketサーバを経由してGoogle Cloud Speech APIに音声データを送信し、テキストデータを受け取ります。 実際に社内発表の中でデモを行った様子を公開します。   このように外部アプリケーションへの音声データの連携を簡単に実装することができました。 まとめ 今回はAstriCon2023への参加を通じて得た情報を紹介しました。 現地の肌感としては、思ったより参加人数が少なく、参加者の年齢層が比較的高かった事もありVoIP系の技術者は国内外問わずあまり増えていないのかな?という印象を受けました。現在、音声認識技術や対話型AIなどVoIP技術との相性が良さそうな技術への注目度が高まってきているので、今後VoIP系技術者の需要も高まっていくのではないでしょうか。 参考資料: http://lists.digium.com/pipermail/asterisk-users/2004-April/036295.html https://www.itexpo.com/east/astricon.aspx RevCommでは音声サーバエンジニアを募集しています。興味を持っていただけた方は、ぜひともご応募ください! hrmos.co
アバター
はじめに 対話要約手法の概要 抽出的要約 抽象的要約 その他 近年の研究 Pegasus DialogLM ChatGPT/GPT3 まとめ 引用 はじめに この記事は『 対話要約研究の最前線 前編 〜データセットと評価指標の紹介〜 』の続きです。 RevCommは電話営業や顧客応対の通話を支援するAI搭載型のIP電話「MiiTel」を提供しています。 この製品は、通話の文字起こしを保存する機能を備えており、RevCommは数千時間の対話データに接しています。 この対話データに対する支援の1つとして対話要約が考えられます。対話要約とは、入力された対話から、その主要な概念を含む、より短い文書(要約)を自動的に作成することです。 ユーザは、要約を作成する手間が省けたり、あるいは要約を読むことで対話の概要をより早く理解できるなどの利点があります。 本記事では、はじめに対話要約の手法の概要を書き次に近年の研究をいくつかご紹介します。 対話要約手法の概要 ここでは対話要約の手法の概要を説明します。今回の記事の趣旨は、最近の研究をいくつか紹介することなので、こちらについては簡単な説明にとどめます。 要約手法の分類方法は何種類かありますが、ここでは抽出的要約と抽象的要約の2つの分類方法に従います。要約を制限するためのクエリや、対話状態の管理方法についてはここでは触れません。また、要約手法ではありませんが、与えられた対話の概要を得るために用いられる手法を紹介します。 抽出的要約 入力文書の一部を切り出して要約文を作成する方法です。この手法における重要な課題は、入力文書のどの部分を切り出すのかを検討することです。例えば、重要度の高い文を選んだり、特定のトピックの文を選んだりする方法があります。 [Song 20]の図を引用し、抽出的対話の例を示します。ここでは、患者の発言のうち特定のトピックに関連するものを抜粋することで対話の要約を作成しています。要約であるSUM1は、対話のうち4番目と7番目の発話をくっつけたものです。 [Song 20]の図 抽象的要約 抽象的要約は、入力文書の主要な概念を含む文書を新しく生成する方法です。機械翻訳などを含むテキスト生成のタスクの一部といえます。 下記に[Chen 21]の図を引用して、抽象的要約の例を示します。要約対象の対話では顔文字や絵文字が多用されていますが、正解として定義される要約文ではそれらは使用されていません。抽出的手法とは異なり、要約文は入力の文書を単に抽出したものではなく、要約手法が生成したものであることがわかります。 [Chen 21]の図 その他 情報抽出の手法が与えられた文書の概要を得る方法として使用されていたのでご紹介します。この方法は、事前に要約のためのテンプレートを用意して、情報抽出を使用してその必要箇所を埋めていくことで要約を作成する手法であるとみなせます。 下記の2つの研究では、どちらも医者と患者の対話をまとめるために情報抽出の手法が使用されていました。この手法を適用することで、医師が対話録を読む手間を削減することができます。 [Kannan 18]では、患者の症状を得るために情報抽出を適用しました。下記に[Kannan 18]の図を引用します。固有表現抽出を用いたシンプルなベースラインでは約20%の症状しか検出できないことが、この研究のモチベーションとなっています。 [Kannan 18]の図 [Zhang 20]では症状だけでなく、検査や手術などの情報も対象にしています。ここでは、LSTMを使ったDeep Matching Modelsと呼ばれる手法を提案しています。手法への入力の単位としてwindowレベルとdialogueレベルがあり、dialogueレベルの場合には適合率が97%以上で情報を獲得できたと報告されています。 [Zhang 20]の図 近年の研究 以下では、対話要約に関する近年の研究を3つ紹介します。2つは論文の内容であり、1つはRevComm内で評価したものです。 Pegasus Pegasusは[Zhang 19]によって提案された文書要約モデルです。最近の研究を紹介する文脈で2019年の研究を紹介することに違和感があるかもしれません。ですが、PegasusはGoogleの製品に使用されており、昨今の文書要約モデルの代表のひとつとして選びました。 2022年11月のGoogleブログへの投稿 では、Google Chatに要約機能が追加され、そこにPegasusを使用していることが報告されています。また、 2022年3月のGoogleブログへの投稿 では、Google Documentに対する要約作成機能が紹介されており、Pegasusが触れられています。なお、Pegasusを拡張し、より大規模な文書を対象にした Pegasus-X が2022年に公開されていますが、ここではあくまでもPegasusを対象に説明します。 Pegasusは事前学習を工夫しており、その観点ではMasked Language Model (MLM) の発展といえます。MLMは文書の一部の単語を隠し、その隠された部分を推測することで事前学習を行います。この一部を隠した部分をマスクと呼びます。 Pegasusは単語のマスクだけではなく、文のマスクを作成し、それらを推測します。下記にPegasusの概要を示す図を論文から引用します。[MASK1]が文のマスクを示し、[MASK2]が単語のマスクを示します。Pegasusは事前学習において[MASK1]と[MASK2]を推測します。この文のマスクを推定することを、論文中はGap Sentences Generation (GSG) と呼んでいます。 [Zhang 19]の図1 著者らは、文のマスクの選び方について、数種類の方法を比較しています。縦軸は文書要約における性能を示し、ランダムにマスクを選んだ場合を1.0としています。横軸は実験に用いたデータセットです。"MLM Solely” の棒がMLM(単語のマスクのみ)の性能であり、これと他の色を比較すると、文のマスクが性能の向上に寄与していることが分かります。 [Zhang 19]の図2 性能評価の実験では、パラメーターのサイズに応じてBASEとLARGEの2種類のモデルが比較されています。BASEは事前学習の対象として単語と文の両方を推測していますが、LARGEでは文のみを推測にしています。 [Zhang 19]の図3 DialogLM [Zhong 22]は、対話要約モデルDialogLMを提案しています。DialogLMは、この論文の著者がMicrosoftのインターンシップの際に行った研究であり、 コード がMicrosoftのGitHubアカウントから提供されています。 DialogLMでは、先に紹介したPegasusと同様に事前学習が工夫されています。具体的にはWindow-based Denoisingと呼ばれる手法であり、5種類のノイズを対話文に入れて事前学習を行います。ここでの事前学習は、文書の一部の単語を隠し、その隠された部分を推測することです。 下図において、Windowがノイズを入れる前の対話文、Noisy Windowがノイズを入れた対話文です。[MASK]は隠された単語を示しています。このNoisy Windowの部分が本論文で工夫されている点です。 下記にこの論文の図を引用して、この工夫についてもう少し詳しく説明します。この論文では、事前学習において対話に入れるノイズとして、5種類のノイズが試されています。 [Zhong 22]の図1 それぞれのノイズの内容を下記に説明します。 Speaker Maskでは、話者の部分が隠されます。そして、その隠された話者を言語モデルに推定させます。 Turn Splittingでは、1つの長い発話が複数の発話に分割されます。そして、最初の発話の話者をそのまま残されますが、分割された2つ目以降の発話の話者を言語モデルに推定させます。 Turn Merginでは、複数の発話が1つの発話にまとめられます。最初の発話の話者はそのまま残されますが、それ以降の発話の話者は削除されます。 Text Infillingでは、発話内の単語が隠されます。 Turn Permutationでは、発話の順序が変更されます。 下図は論文から引用した実験結果です。この表で示されているのはForeverDreamingとTVMegaSiteというデータセットを使った場合の結果ですが、他にAMIとICSIというデータセットを使った結果も論文には示されています。ベースラインとして、LongformerやBARTなどが使用されており、提案手法はそれよりも性能が良かったことを示しています。 [Zhong 22]の図2 ChatGPT/GPT3 OpenAIが提供しているChatGPTとGPT3は要約に特化したサービスではありませんが、これを使って要約を行うことができます。そこで、ChatGPT/GPT3を用いた要約の性能について報告します。なお、ChatGPTやGPT3の概要については割愛します。 本記事では、性能を測るためのデータセットとしてSAMSumコーパスを用いました。SAMSumコーパスは、チャットでの短い対話から作成された対話要約のためのデータセットです。このコーパスは広く使用されており、評価結果をさまざまな研究と比較できます。さらに、学習済みの対話要約モデルが多く公開されています。 GPT3の評価では、OpenAIが提供するAPIから「text-davinci-003」モデルを選択しました。ChatGPTの評価では、「gpt-3.5-turbo-0301」モデルを選択しました。 ベースラインとしては、3つの学習済みモデルを使用しました。1つ目は philschmid/bart-large-cnn-samsum (以下、BART-large)で、これはBARTをCNN Daily Mailコーパスと SAMSumコーパスの2つの要約データセットでファインチューニングしたものです。2つ目は philschmid/flan-t5-base-samsum (以下、Flan-T5-base)で、これは flan-t5-base をSAMSumコーパスでファインチューニングしたものです。最後は jaynlp/t5-large-samsum (T5-large)で、最近の対話要約に関する論文の成果物のひとつです。 さらに、 UL2 と Pegasus の2つのモデルのスコアを参照しました。 UL2は2022年後半に提案されたモデルであり、そのモデルがSAMSumコーパスで最先端のスコアを達成したと主張されています。 Pegasus は、Googleが提供しているサービスの要約機能で使用されているモデルであり、最も洗練された要約モデルのひとつです。 評価指標としてBLEUとROUGEの2種類を使用しました。結果を下記の表に示します。 モデル BLEU ROUGE1 ROUGE2 ROUGEL ChatGPT 0.093 0.406 0.165 0.318 GPT3 0.111 0.423 0.171 0.340 BART-large 0.123 0.403 0.203 0.312 Flan-T5-large 0.212 0.516 0.274 0.431 T5-large 0.200 0.506 0.262 0.418 UL2 - - 0.296 - Pegasus - 0.523 0.283 0.4783 GPT3はChatGPTよりも高いスコアを獲得しました。そして、ファインチューニングされたモデル (BART-large, Flan-T5-base, T5-large) はGPT3よりも優れていることがわかります。この結果は、 2023年2月に発表された論文 で報告されている内容と一致します。ただし、この論文では実験の際に40GB程度の大きなモデルを使用しているため、小さなモデル(例えば、T5-largeは3GB程度です)がGPT3およびChatGPTの性能を上回るという事実は、この実験で初めて明らかになりました。 Flan-T5-largeはGPT3/ChatGPTと比較して小さなモデルですが、GPT3/ChatGPTよりも高いスコアを獲得しました。この事実は、非常に大規模なモデルを使用せずに、高精度な要約モデルを開発できることを示唆しています。ただし、開発にChatGPTのような非常に大きなモデルが不要であるというわけではありません。ChatGPTを使用することでデータ拡張や教師データの作成などを行い、開発をスピードアップすることが可能だと思われます。 BART-largeは、ファインチューニングされたモデルの中では最低の性能でした。 BARTは要約タスクを含むテキスト生成タスクのベースラインとして頻繁に使用されており、一般に性能が低いわけではありません。 GPT3とChatGPTのスコアが低かった原因を分析するために、スコアが低かった要約結果の中身を確認しました。その結果、スコアが低かったにもかかわらず、対話の重要な部分はしっかりまとまっていることが確認されました。ただし、その表現は正解として定義された要約文を言い換えたものであり、単語でのマッチングをもとに評価を行うやBLEUやROUGEでは不正解と見なされていました。これはやBLEUやROUGEの弱点であり、この問題に対処するために近年いくつかのスコアが提案されています。詳しくは前編記事をご覧ください。 まとめ 本記事では、対話要約の最近の研究としてPegasus、 DialogLM、そしてRevComm内でGPT3/ChatGPTを評価した結果を紹介しました。 GPT3/ChatGPTの評価では、SAMSumコーパスを使用してGPT3とChatGPTの対話要約性能を評価しました。 GPT3はChatGPTよりも高いBLEU/ROUGEスコアを獲得しましたが、BARTやFlan-T5などをSAMSumコーパスでファインチューニングしたモデルはGPT3よりもさらに高いスコアを獲得しました。しかし、GPT3/ChatGPTによる要約結果は必ずしも悪いものではなく、むしろBLEUやROUGEといったスコアに改良が必要であることが示唆されました。 引用 [Chen 21] Chen, Y., Liu, Y., and Zhang, Y.: DialogSum Challenge: Summarizing Real-Life Scenario Dialogues, in Proceedings of the 14th International Conference on Natural Language Generation, pp. 308–313, Aberdeen, Scotland, UK (2021), Association for Computational Linguistics [Kannan 18] Kannan, A., Chen, K., Jaunzeikare, D., and Ra- jkomar, A. R.: Semi-supervised learning for information extraction from dialogue (2018) [Song 20] Song, Y., Tian, Y., Wang, N., and Xia, F.: Summarizing Medical Conversations via Identifying Important Utterances, in Proceedings of the 28th International Conference on Computational Linguistics, pp. 717–729, Barcelona, Spain (Online) (2020), International Committee on Computational Linguistics [Zhang 20] Zhang, Y., Jiang, Z., Zhang, T., Liu, S., Cao, J., Liu, K., Liu, S., and Zhao, J.: MIE: A Medical Information Extractor towards Medical Dialogues, in Proceedings of the 58th Annual Meeting of the Association for Computational Linguistics, pp. 6460–6469, Online (2020), Association for Computational Linguistics [Zhang 19] Zhang, J., Zhao, Y., Saleh, M., and Liu, P. J.: PEGASUS: Pre-training with Extracted Gap-sentences for Abstractive Summarization (2019) [Zhong 22] Zhong, M., Liu, Y., Xu, Y., Zhu, C., and Zeng, M.: Dialoglm: Pre-trained model for long dialogue understanding and summarization, in Proceedings of the AAAI Conference on Artificial Intelligence, Vol. 36, pp. 11765–11773 (2022)
アバター
2023年5月19-20日に開催されるスクラムフェス新潟にRevCommのQAエンジニアの大野泰代が登壇します。 トークタイトルは Whole-Team Approach (WhTA) for babies です。 開催概要 名称:スクラムフェス新潟 開催日時:2023年5月19-20日 開催場所:NINNO3(新潟市)、オンライン 主催:Scrum Fest Niigata実行委員会 イベントの詳細、お申し込みはこちら イベント内容 スクラムフェス新潟はアジャイルコミュニティの祭典です。 アジャイルやテストのエキスパートと繋がりを持ちましょう。この祭典は初心者からエキスパートまで様々な参加者が集い、学び、楽しむことができます。 参加者同士でアジャイルやテストのプラクティスについての知識やパッションをシェアするだけでなく、ここで出会ったエキスパートに困りごとを相談することもできます。 イベントサイトより引用 登壇情報 タイトル: Whole-Team Approach (WhTA) for babies 日時: 5月20日(土) 午後 5:00-5:45 confengine.com 登壇者紹介 大野泰代、RevComm QAチーム QAエンジニア 筑波大学人間学類卒業(社会心理学専攻)。CRC総研、フューチャーシステムコンサルティングなどのSIerで、DBAやPLなどを経験後、2010年頃より、QAとして、各種システム開発に従事。 2022年5月よりRevCommに参画。QMファンネルでいうところの「スプリットTE~インプロセスTE~TEコーチ」や「スプリットQA~インプロセスQA~QAコーチ」として活動中。 また、Sig-SQAで社外コミュニティ活動も行っている。 最後に RevCommは電話営業や顧客応対を可視化する音声解析AI搭載型のクラウドIP電話「MiiTel(ミーテル)」を開発しています。 MiiTelは電話サービスであり、高い信頼性が求められます。一方で、まだまだ機能の追加や発展も著しい側面もあります。お客様に MiiTel を安心して使っていただくため、品質向上のための取り組みは重要度を増すばかりです。 日々お客様が安心して使えるよう、品質保証への取り組みをさらに強化するための仲間を募集しています。MiiTelの開発や品質保証に興味をお持ちの方は、ぜひ当社の採用サイトをご覧ください。 www.revcomm.co.jp
アバター
はじめに Hello World! RevCommのバックエンドエンジニアの矢島です。 今回はMiiTelのアーキテクチャや技術スタックと開発・運用体制についてご紹介します。 MiiTelってなに? アーキテクチャや技術スタックの話題に入る前に、簡単にMiiTelについて紹介します。 MiiTelはAI搭載型クラウドIP電話です。 電話業務の可視化・分析を行うことで、セルフコーチングの機会を提供し、教育コストの削減・業績向上を実現するSaaSとして、電話営業やコールセンター、カスタマーサクセスなどの現場に導入いただいています。 MiiTelはそのサービスの性質上、特に平日の日中は業務のメインアプリケーションとして活用されることが多く、数秒でもサービス停止が発生するとお客様の業務にダイレクトに影響してしまいます。そのようなことが起きないように、適切な技術選定と設計を行わなければいけません。 MiiTelは大きく以下の3つのコンポーネントに分けることができます。 電話機能を提供するPBX 電話の音声データの話し方解析・言語解析を行う機械学習モデル 通話データを管理・可視化するWebアプリケーション RevCommではこれらのコンポーネントをすべて内製しています。 この記事では全体的なアーキテクチャや開発・運用体制に触れつつ、主にお客様に常に利用されているアプリケーションに焦点を当て、MiiTelを支える技術スタックとその変遷を紹介していきます。 ※当記事に記載された情報は公開時点(2023年5月)のものになります。 MiiTel アプリケーションアーキテクチャと技術スタック MiiTelには、管理者がユーザーを管理・電話の応答ルールの設定などを行うMiiTel Adminと、ユーザーが電話・通話履歴の管理・解析結果の確認などを行うMiiTel Analyticsがあります。 認証基盤アプリケーションは今後のサービス展開でも共通化できるよう、MiiTelアプリケーションから切り出して開発を行っています。 バックエンドの言語はPythonを採用しています。機械学習や音声認識分野でPythonが多く使われていることや、グローバル進出時に海外のエンジニア採用に有利であろうという観点から採用しました。 WebフレームワークにはDjangoを採用しており、機能単位にアプリケーションを分割して開発しています。 MiiTel はZoomとも連携しており、Web会議を自動で取り込んで解析し、会議の録画を解析結果とともに確認・管理できます。 MiiTelインフラアーキテクチャと技術スタック 要件 平日の日中に集中するアクセスを低レイテンシーで処理する 高い可用性を実現する 機能実装に集中できるインフラ構成を実現する 冒頭にも記載した通り、MiiTelはサービスの性質上、平日の日中にアクセスが集中します。そして数秒のサービス停止であっても大きな影響を及ぼします。 そのような柔軟なスケーリングと高い可用性を、なるべくリソースの管理に人員を割くことなく実現するためにさまざまなAWSサービスを活用しています。  CloudFrontとLambdaでのキャッシュ・アクセス制御をすることでバックエンドアプリケーションへの負荷を削減 Application Load Balancerでのヘルスチェックと負荷分散 ECSでコンテナ化されたアプリケーションをデプロイ Fargateでのマネジメント不要なスケーリング 負荷分散の観点からECSサービスを役割によって分割 OpenSearchで膨大なデータを横断して検索する機能の実現 SQSで音声解析システムとの連携を疎結合に実現 もちろん初めからこのようなアーキテクチャになっていたわけではありません。現在の構成に至るまで改善が繰り返されてきました。 そこで、MiiTelアプリケーションバックエンドの核を実行する赤枠の部分について、過去からの変遷を踏まえながら詳細を紹介します。 MiiTelアプリケーションバックエンドのインフラアーキテクチャの変遷 EC2の時代 創業から1年程度は、EC2のみを使ったシンプルな構成でした。 この画像は2017年11月のSlackでのやりとりです。 当時はスケーリングも考慮しつつ、スピードを意識した開発をしていた様子がうかがえます。 ECSの導入 ユーザー数が急速に増えていくなかで、スケーリングの課題が発生しました。 都度EC2インスタンスを管理しするのは運用に工数がかかり、スケールできないリスクが高まります。 そこで、以下のような改修を行いました。 アプリケーション環境をEC2からFargateに変更する ECSのAuto Scaling を利用し、実行するタスク数を自動的に増減させる この改修により急激なリクエストの増加にも耐えられるようになりました。 ECSサービスを役割で分割 ECSでタスク数をオートスケーリングするようになったことで、スケーリングは容易になりました。 しかし当時は、すべてのバックエンドへのリクエストを同一のサービスで処理していました。 それにより、サービス成長によりデータ量が多くなるにつれて、リクエストの中でも高負荷のものが他のリクエストのレイテンシーに影響を及ぼすようになってきました。 そこで、以下のような改修を行い、現在の構成になりました。 リクエストの内容によってCloudfrontのオリジンとビヘイビアを使い、異なるロードバランサーにリクエストを振り分ける それぞれのロードバランサーのターゲットを異なるECSサービスにする この改修により、高負荷なリクエストが増えても他のリクエストのレイテンシーに影響させないようにすることができるようになりました。 加えて、RevCommのTerraformを利用した現在のインフラ構築・運用の基盤ができたのもこの頃です。 次は、RevCommのインフラの構築・運用方法をご紹介します。 インフラ構築・運用方法 RevCommのインフラ構築・運用はヒューマンエラーを最小限にしつつ、よりスピーディーなリリースを実現するための工夫がなされています。 スピーディーなリリース 基本的に機能の開発者がそれに必要なリソースをつくる 職種によらずInfrastructure as Code (IaC) でリソース構築を行うことを推奨している RevCommにはインフラチームが存在しますが、アプリケーションのAWSリソースの構築には原則関わりません。アプリケーションの機能に必要なAWSリソースはアプリケーション開発者が構築・運用に責任を持ちます *1 。 このように機能開発からリソース構築まで一気通貫で行うことで、インフラチームのAWSリソース構築待ちといった時間が削減できています。 また私が入社して驚いたのが、フロントエンドエンジニアでもAWSリソースを構築・運用できる人がいることです。 RevCommには、在籍しているメンバーが市場価値の高いエンジニアになってほしいという方針があり、それが体現されているなと思いました。 多くのメンバーが担当できる技術領域を広げられる構築・運用体制になっていることで個人の成長に繋がっています。組織としても、属人化による運用コストの増加を防ぎ、スピーディーなリリースを実現できます。 ヒューマンエラーの最小化 RevCommでは、IaCのツールとしてTerraformとServerless Frameworkなどを利用しています。 以下の運用体制を敷いてヒューマンエラーを最小化するようにしています。 GitHub Actionsで、terraform fmt, validate, planを自動実行し結果を出力 特定のリソースはGitHub Actionsで applyを自動化 AWSアカウントに紐づくIAM roleで開発者が直接applyできるリソースを制御 実際の開発フローは以下のようになっています。 今後のMiiTelインフラアーキテクチャの展望 MiiTelを支える技術スタックやアーキテクチャとその変遷、開発・運用体制を紹介しました。 MiiTelのアプリケーションやインフラにおいては、今回ご紹介した以外においても様々な改善が繰り返されてきました。 そして今やMiiTelは日本だけでなくインドネシアでも提供されており、今後は北米進出も目指しています。 今後の更なるサービス成長や世界展開を視野に、インフラアーキテクチャにおいてはリージョンをフル活用して可用性と耐障害性を高められる構成にアップデートするPoCを実施しています。 まとめ 今回は、MiiTelを支える技術スタックと開発・運用体制というテーマで、記事を書きました。 2022年7月に入社してから、日々アーキテクチャやシーケンスのキャッチアップをしながら開発に奮闘している私としても、全体を俯瞰するいい機会となりました。 この記事をご覧いただいて、少しでもRevCommに興味を持っていただけたら、ぜひ採用ページもご覧ください。 www.revcomm.co.jp *1 : インフラチームは、インフラの全体最適化や、VoIPのためのインフラ構築・運用、セキュリティの強化などを行っています。
アバター
2023年4月28日(金)19:00 より、 Forbes AI 50 2023にアジアで唯一選出されたばかり の、 弊社の開発組織に焦点を当てたオンライン説明会 を開催します。 revcomm.connpass.com イベント内容 RevCommのエンジニア組織はどうなっているの?プロジェクトはどのように進めているの? Forbes AI 50 2023にアジアで唯一選出された と聞いて初めて知った会社だけど、どんな開発体制なの?…などなど、少しでも気になったことはありませんか? 本イベントでは、CTO・平村健勝をはじめとする弊社エンジニアが組織や開発体制について直接説明させていただき、皆様の疑問にお答えします。ぜひお気軽にご参加ください。 参加登録はこちら 登壇者 平村 健勝(ひらむら たけかつ)執行役員 CTO tech.revcomm.co.jp 瀬里 俊行(せり としゆき)執行役員 シニアエンジニアリングマネージャー tech.revcomm.co.jp 大谷 紗良(おおたに さら)Software Engineer, Backend tech.revcomm.co.jp 川添 貴之(かわぞえ たかゆき)Engineering Manager tech.revcomm.co.jp モデレーター 小幡 倫美(おばた ともみ)HR 参加登録 参加登録は、connpassにて受け付けております 。奮ってご参加ください。
アバター
はじめに バックエンドエンジニアの小門 照太です。 RevCommの主要製品であるAI搭載型IP電話「MiiTel」において、バックエンドAPIフレームワークの一つとしてDjangoを利用しています。 さて、4/3(月) にDjango 4.2がリリースされました。 Django 4.2 released これはLTS(Long-Term Support)バージョンであり、3.2 LTSから2年ぶりのリリースです。 サービスの継続開発と運用においてフレームワークのバージョンアップに追従することは、機能の追加や強化そしてセキュリティ面で重要です。 この度RevCommで運用しているサービスにおいてDjango 4.2へアップグレード(本番環境へ適用)しました。 今回の対応で実施した手順や必要となったソースコード修正の内容をご紹介します。 事前準備 本対応に際して事前にベータ版を使って検証を行いました。 Django 4.1から4.2正式リリースまでの間に下記のバージョンがリリースされており、事前検証や準備をするための期間が設けられています。 4.2a1 4.2b1 4.2rc1 本対応では検証バージョンに 4.2b1 を利用しました。検証用にブランチを作成し、その中でバージョンをアップグレードしてアプリケーションを起動させました。 いくつかエラーが出たため、修正した内容を後述します。 修正内容 django.conf.urls.url django.conf.urls.url() 関数がver4で廃止になりました。 例えば urls.py において下記のような修正です。 - from django.conf.urls import url + from django.urls import path urlpatterns = [ - url(r"~~~", ...) + path(r"~~~", ...) ] なお django.conf.urls.url() はver3.1から非推奨(Deprecated)とされています。 django.urls functions for use in URLconfs Deprecated since version 3.1: Alias of django.urls.re_path() for backwards compatibility. また urls() から path() への修正後に警告が出るようになりました。 $ python manage.py check System check identified some issues: WARNINGS: ?: ( 2_0.W001 ) Your URL pattern ' ^path/to/view$ ' has a route that contains ' (?P< ' , begins with a ' ^ ' , or ends with a ' $ ' . This was likely an oversight when migrating to django.urls.path () . System check identified 1 issue ( 0 silenced ) . これは path() のURLパターンに ^ や $ といった正規表現を含んでいたことが原因でした。 URLパターンに正規表現が必要な場合のためには django.urls.re_path() 関数が用意されています。 URLパターンから ^ と $ を削除して警告を解消しました。 urlpattenrs = [ - path(“^path/to/view/$”, …), + path(“path/to/view/”, …), ] django.utils.translation.ugettext_lazy 上記と同様に Deprecated な関数への対応です。 django.utils.translation.ugettext_lazt から gettext_lazy を使用するようにします。 - from django.utils.translation import ugettext_lazy as _ + from django.utils.translation import gettext_lazy as _ こちらもDjango 3.0のRelease noteに非推奨となる旨が記載されています。 Django 3.0 release notes django.utils.translation.ugettext(), ugettext_lazy(), ugettext_noop(), ungettext(), and ungettext_lazy() are deprecated in favor of the functions that they’re aliases for: Djangoドキュメントにおいて、関数/メソッドの deprecation はマイナーバージョンも含めた各Release noteで確認することができます。 しかし、メジャーバージョン毎の大まかなアップデートをRelease noteで俯瞰することは難しいです。 全てのバージョン毎の Deprecated あるいは廃止される関数/メソッドの情報を知るにはRelease noteではなく「 Django Deprecation Timeline 」を確認すると良いでしょう。 Psycopg 3 PostgreSQL 向けのデータベースドライバーである psycopg ver3 がサポートされました。 これは Django 4.2 リリースノート 「What’s new in Django 4.2」の1番目に記述されています。 Psycopg ver3 では 非同期操作のサポート を含む機能強化が行われています。 Differences from psycopg2 従来はPsycopg ver2でしたが、将来的にver2はDeprecatedとなるため今回で対応しました。 ドキュメントの手順に従ってPsycopg ver2からver3にアップグレードします。 ※パッケージマネージャーとしてPoetryを使用している例 $ poetry remove psycopg2-binary $ poetry add " psycopg[binary,pool] " また設定モジュール(settings.py)の記述もDjangoドキュメントに従い修正します。 Settings | Django documentation | Django DATABASES = { "default": { - "ENGINE": "django.db.backends.postgresql_psycopg2", + "ENGINE": "django.db.backends.postgresql", ... 動作確認 上述までの修正手順でローカルでエラーが出ないこと、およびCIの成功を以って検証環境への反映を行いました。 $ python manage.py check System check identified no issues ( 0 silenced ) . $ python manage.py test ... ---------------------------------------------------------------------- Ran 435 tests in 19 .712s OK Destroying test database for alias ' default ' ( ' myapp ' ) ... そして検証環境で一定期間稼働させて不具合が顕在化しないことを確認して、最終的なリリース判定として本番環境へ反映しました。 Django 4.2LTSが4/3(月)にリリースされて1週間ほどで本番環境にアップグレード適用を完了させました。 今回の迅速な対応を可能にした要素として下記の点が挙げられます。 Djangoのリリーススケジュールをウォッチして計画に組み込んでいた 事前準備としてベータ版を適用して検証を行った サービスの正常性を担保するためのCIを整備していた 今後に向けて 以上までの内容に加えてDjango ver4のアップデートに伴う修正の余地はまだまだあります。 今後対応していきたい箇所を合わせて例示してみます。 非同期サポートの強化 Django 4.1でORMによるクエリ実行に非同期サポートが導入されました。 Asynchronous queries SQLクエリを発行する全ての QuerySet メソッドの接頭辞に a を付けたものが追加されています。 async for author in Author.objects.filter(name__startswith= "A" ): # afirst(), not first() book = await author.books.afirst() データベースに対する操作はIOバウンドであるため、ノンブロッキング処理に切り替える効果が大きいはずですので、検証しつつ徐々に導入していきたいと考えています。 Redis用バックエンドクラスの提供 Django 4.0より、キャッシュ用途でRedisを利用する際のバックエンドクラスをDjangoがネイティブで提供するようになりました。 Django 4.0 release notes Redis cache backend The new django.core.cache.backends.redis.RedisCache cache backend provides built-in support for caching with Redis. これにより、DjangoとRedisを統合するための django-redis を利用する必要がなくなります。 CACHES = { "default" : { "BACKEND" : "django.core.cache.backends.redis.RedisCache" , "LOCATION" : "redis://127.0.0.1:6379" , } } まとめ Django 4.2LTSのリリースに伴いアップグレードを実施した事例をご紹介しました。 アップグレードして終わりではなく、「今後に向けて」のように対応の余地はまだまだたくさんあるので運用を継続していくことが最も重要であると考えています。 RevCommでは一緒に働いてくださるエンジニアを募集しています。 「コミュニケーションを再発明し人が人を想う社会を創る」というミッションの元、プロダクトの安定稼働を支えるために様々な取り組みをしていますので、ぜひご応募ください。 hrmos.co
アバター
1. はじめに こんにちは、RevComm Researchでリサーチエンジニアとして働いている髙瀬です。 2023年1月上旬にUltralytics社からYOLOv8が公開されました。 今回はYOLOv8について、v5との変更点や動かし方を紹介していこうと思います。 2. YOLOとは 非常に有名な物体検出手法なので、ご存知の方も多いと思います。 YOLOは、CVPR2016でJoseph Redmon氏らが発表した You Only Look Once: Unified, Real-Time Object Detection という論文で提案された物体検出手法です。 YOLOという名称はYou Only Look Once(見るのは一度だけ)の略称です。 YOLOは当時の物体検出手法で課題となっていた処理速度の遅さを、物体の検出と識別を同時に行うことで改善しました。 このため、推論速度が非常に高速でリアルタイム物体検出の先駆けにもなっています。 今日に至るまでに様々な物体検出手法が登場していますが、その中でも物体検出に興味を持ち始めた方、これから学ぼうとしている方には是非一度はチェックしてもらいたい手法の一つです。 本記事では詳細な説明は割愛しますが、日本語のわかりやすい解説記事も豊富ですので調べてみてはいかがでしょうか。 3. YOLOv8 YOLOv8は、YOLOv5の公開元であるUltralytics社が公開したYOLOの最新バージョンのモデルです。 大規模データセットでの学習はもちろんのこと、object detection, segmentation, classificationタスクで利用可能であり、CPU, GPUを始めとしたさまざまなハードウェアでの実行が可能になっています。 YOLOv8では、新しいbackboneや損失関数、anchor-free detection headの導入などの変更が加えられているだけでなく、過去のバージョンのYOLOをサポートし異なるバージョン間の切り替えや性能比較を容易にするといった機能を備えている点も大きな特徴と言えます。 現在、リポジトリを確認するとv3, v5, v8のconfigが用意されています。 なお、本記事執筆時点ではYOLOv8の論文は未公開のため、公式からの続報を待ちたいと思います。 4. YOLOv8のモデルサイズ YOLOv8にはモデルサイズが異なるn, s, m, l, xの5パターンのprerained modelが用意されています。 下記のパラメータ数とCOCO mAP(精度)に着目するとYOLOv5から精度がかなり向上していることがわかります。 特に大きいモデルサイズであるl, xはパラメータ数を削減しつつ精度が向上しています。[ 引用 ] 各モデルの精度は下記のようになっています。[ 引用 ] 5. YOLOv5とYOLOv8の変更点 YOLOv8になったことでYOLOv5から構成がいくつか変更されていますが、現時点で公開されているモデルの構成から読み取れる大きな変更は2点です。 C2f layerの導入 Decoupled head導入とobjectness branchの削除 この他にも一部のconv module削除、kernel sizeの変更など細かな変更が加えられています。 公式ではありませんが、 RangeKing 氏が公開している YOLOv8 detection modelアーキテクチャ の図が参考になります。 RangeKing氏によるYOLOv8 detection modelアーキテクチャ[ 引用 ] 6. YOLOv8の環境構築と推論実行 本章では、YOLOv8をインストールして実際に触れていこうと思います。 今回はpretrained modelを使ってM1 MacBook ProのCPU環境でどの程度動くのか気になったので検証してみます。 <筆者の環境> MacBook Pro (13-inch, M1, 2020) 16GB Mac OS Monterey YOLOv8のインストールは、下記のコマンドでできます。 pip install ultralytics インストールが完了したところで、実際に動かしてみます。 今回はPythonスクリプトで推論してみます。 画像に対しての推論 まずは画像を入力してみます。 本記事では 公式からダウンロードできる、バスと人が映った画像 を使います。 画像サイズはwidth=810, height=1080のRGB画像です。 from ultralytics import YOLO # load pretrained model. model: YOLO = YOLO(model= "yolov8n.pt" ) # inference # save flgをTrueにすることで推論結果を描画した画像を保存できる。 result: list = model.predict( "https://ultralytics.com/images/bus.jpg" , save= True ) YOLOv8nの推論結果の画像 動画に対しての推論 動画に対しても推論を行ってみました。 画像に対しての推論ではYOLOv8nを使っていたので、動画ではYOLOv8xを使ってみようと思います。 画像の推論時とインターフェースは変わらず、動画ファイルのパスを引数に渡します。 from ultralytics import YOLO # load pretrained model. model: YOLO = YOLO(model= "yolov8x.pt" ) # <figure class="figure-image figure-image-fotolife" title="YOLOv8xの推論結果のgif">[f:id:yasaka_uta:20230327173819g:plain]<figcaption>YOLOv8xの推論結果のgif</figcaption></figure>inference # save flgをTrueにすることで推論結果を描画した動画が保存される。 result: list = model.predict( "MOT17-14-FRCNN-raw.mp4" , save= True ) 今回、 MOT Challenge MOT17のTest set の動画を利用します。 なお、MOT17の動画ファイルはWebM形式なので、事前にMP4形式に変換を行っています。 変換した動画は30秒、フレームレートは30なので、900枚の画像に対して推論が行われる形になります。 YOLOv8xの推論結果のgif 補足 1. サポートされている動画像のファイル形式 YOLOv8でサポートしている画像、動画のファイル形式は以下のようになっています。 画像: "bmp", "dng", "jpeg", "jpg", "mpo", "png", "tif", "tiff", "webp", "pfm" 動画: "asf", "avi", "gif", "m4v", "mkv", "mov", "mp4", "mpeg", "mpg", "ts", "wmv" サポートされているファイル形式のコード上での定義はこちら 2. 検出結果のテキスト出力 推論を行っている時に検出結果をテキストとして保存したいことがあると思いますが、下記のように引数を設定すれば可能になります。 # 検出結果を描画した画像と検出結果をテキストに出力したいとき model.predict( "https://ultralytics.com/images/bus.jpg" , save= True , save_txt= True ) # 検出結果+各物体のconfidenceをテキストに出力したいとき model.predict( "https://ultralytics.com/images/bus.jpg" , save_txt= True , save_conf= True ) Prediction関数に設定できる引数はほかにも用意されているので、 公式ドキュメント を参照ください。 3. modelへの入力方法の補足 動作確認で動画像のパスを指定していますが、以下のようにlist形式で複数の動画像のパスを渡すこともできます。 source_list: list = [ "./sample1.jpg" , "./sample2.jpg" ] result: list = model.predict(source_list, save= True ) 7. 各モデルの推論結果を俯瞰してみる 前章で環境構築し推論できることが確認できたので、この環境を使ってYOLOv8のsからlのモデルで推論してみようと思います。 また、結果の比較としてYOLOv5だけでなく、ここ1年以内に出ているYOLOv6およびYOLOv7の出力結果も一緒に比較してみます。 なお、今回は各モデルの精度比較ではなく、モデルごとの出力を俯瞰するかたちで比較したいと思います。 YOLOv5, YOLOv6, YOLOv7についての解説は割愛しますが、気になった方は調べてみてください。※YOLOv6のモデルはYOLOv6 (v3.0) がYOLOv8とほぼ同時に公開されているため、YOLOv6 (v3.0)を使っています 対象とする画像はYOLOv8のサンプル画像を利用しています。 各モデルの検出結果を描画した画像と検出物体の情報、推論速度をまとめてみました。 YOLOv8l, xではYOLOv5l, xで検出できていなかった画像右上のbicycleを検出できていますね。 YOLOv8の検出物体のconfidenceをみていくとYOLOv5よりも基本的に向上していることがわかります。 YOLOv7が若干遅い印象はあるものの、どのモデルもかなり高速ですね。 YOLOv8 YOLOv5 YOLOv6(v3.0) YOLOv7 8. まとめ 本記事では、YOLOv8の概要・YOLOv5との差分・簡単な使い方を紹介しました。 YOLOv8を使ってみた所感としては、 pip install可能で導入が容易、かつ使いやすく整理されたインターフェース onnx, torchscriptなどへの変換が非常に簡単 以前のYOLOv5も使いやすかったですが、さらに利便性が向上した印象を持ちました。 モデルのexportについては今回触れていませんが、 export形式 が豊富で簡単に実行できるのは開発者にとってうれしいですね。 9. 参考文献 https://github.com/ultralytics/ultralytics https://docs.ultralytics.com/ https://github.com/meituan/YOLOv6 https://github.com/WongKinYiu/yolov7 https://github.com/ultralytics/yolov5 https://github.com/ultralytics/ultralytics/issues/189 https://motchallenge.net/data/MOT17/ https://blog.roboflow.com/whats-new-in-yolov8/
アバター
1. はじめに こんにちは、RevComm でバックエンドエンジニアとしてプロダクトの開発に携わっている池畠です。 2022 年 12 月下旬に弊社から MiITel の新機能として Outgoing Webhook をリリースしました。今回は弊社における Outgoing Webhook を活用した業務の効率化事例について、Python によるマイクロサービスを実装しながら紹介していこうと思います。 2. Outgoing Webhook MiiTel の Outgoing Webhook は、応対履歴の音声解析完了時に、設定した URL (Webhook 送信先サーバー) に HTTP リクエストを送信する機能です。開発者は、Webhook を利用して外部システムへ MiiTel 応対履歴情報を連携できます。 詳しい設定方法・連携内容は サポートページ をご参照ください。 3. 運用に向けた課題 弊社のカスタマーサポートではお客様からのお電話での対応に MiiTel を活用しております。MiiTel には既に Salesforce や kintone, HubSpot といった外部の CRM に応対履歴情報の連携機能は備わっていますが、問い合わせ内容のチケット管理には Asana を活用しているため、手動で Asana タスクを作成して応対履歴内容を転記するひと手間が要りました。 そこで、Outgoing Webhook によって MiiTel 応対履歴情報から自動で Asana タスクを作成するマイクロサービスを構築し、チケット作成を自動化するような業務改善の事例をご紹介します。 4. Asana 側の設定 Asana にタスクを自動作成するためには、事前に以下の項目を取得し控えておく必要があります。本章では、それらの確認方法を紹介します。 API token Workspace id Project id API token まずは Asana の デベロッパーコンソール にアクセスしてログインします。 画面下部の「トークンを新規作成」をクリックし、「API 利用規約に同意しますにチェック」を入れ、トークン名を入力します。 入力が完了したらトークンを作成ボタンを押下すると、トークンをコピーのモーダルが出現するので「コピー」ボタンを押下してすぐに参照できるように控えておきます。 「必ずここでこのアクセストークンをコピーしてください。二度と表示されません。」という表示もありますので紛失しないようにしましょう。「完了」を押下して API token の取得は完了です。 Workspace id まずは Asana のトップページにアクセスします。 ご自身のアイコンをクリックすると「所属先組織について...」が選択できるのでこれを押下すると別ウィンドウに遷移します。 そのときの URL を確認すると https://app.asana.com/admin/{数字}/overview のようになっており、 admin と overview に挟まれている数字が Workspace id に相当するのでこれを控えておきましょう。 Project id 本記事ではデモとして新規に Asana プロジェクトを作成してみます。 まずは Asana のトップページにアクセスします。 「プロジェクトを作成」をクリックし、「テンプレートを使用」を選んでいきます。 今回は、「Support チームへの機能要望のお問い合わせを Developer チームが確認しやすいようなチケット化をする」というユースケースを想定して、「IT リクエスト」のテンプレートを選択していきます。「テンプレートを使用」をクリック。 プロジェクトの詳細を追加していきます。プロジェクト名を記入し、チームを選択して「プロジェクトを作成」ボタンを押下します。 プロジェクトの作成が完了すると https://app.asana.com/0/{数字}/board という URL に遷移します。0 と board に挟まれている数字が Project id に相当するのでこれを控えておきましょう。 5.Chalice によるマイクロサービス構築 本章では、Python の AWS マイクロサービス構築用バックエンドフレームワークである Chalice を活用して Outgoing Webhook の受け口と Asana API を実行する Lambda を作成していきます。 筆者の環境 MacBook Pro (13-inch, M1, 2020) Python 3.10.2 Mac OS Ventura 導入 Chalice, Asana の Python 用モジュールのインストールは、下記のコマンドでできます。 pip install chalice asana 続いて Chalice の新規プロジェクトを作成します。ディレクトリを移動し、Lambda へのデプロイ用に pip freeze をしてファイルに出力させておきます。 chalice new-project helloworld cd helloworld pip freeze > requirements.txt 認証周辺の実装 本機能における「認証」とは初回リクエストで "challenge" キーの値をサーバー側でレスポンスするということになります。その部分を実装していきます。 現在のディレクトリに app.py というファイルがありますが、これがアプリケーションの本体になります。まず、例として認証周りの処理を下記のように記述していきます。 import json import os import asana from chalice import Chalice, ForbiddenError, Response app = Chalice(app_name= 'helloworld' ) @ app.route ( "/" , methods=[ "POST" ]) def index (): request = app.current_request body = request.json_body headers = request.headers # コメント 1 if headers.get( "X-MiiTel-Outgoing-Webhook-Key" ) != "OUTGOING_WEBHOOK_KEY" : raise ForbiddenError( "Invalid header key" ) if "challenge" in body.keys(): return Response( body=body[ "challenge" ], status_code= 200 , headers={ "Content-Type" : "text/plain" }, ) まずは Outgoing Webhook で設定予定の追加ヘッダーに該当する箇所を見ていきます。コメント 1 の箇所におきまして、”OUTGOING_WEBHOOK_KEY” という値があるかを確認しています。ハードコードは良くないので実運用においては環境変数にするか、AWS Systems Manager (SSM) や AWS Secrets Manager に格納した値を参照するなどしておく必要があります。存在しなければ 403 エラーに該当する FobiddenError を raise してその原因を軽く引数の文字列に記しておきます。次にポイントとなるのが、body 内に ”challenge” というキーが存在するかを確認するということです。初回リクエストではこの ”challenge” キーの値をそのままレスポンスで返す必要があるので早めに return しておきます。 応対履歴の整形 次は応対履歴から Asana タスクを作成する処理を以下のコードでしていきます。Outgoing Webhook ペイロードの形式に関してはサポートページにも記載がありますので詳しくはこちらを参照ください。 # コメント 2 success_response = Response( body= "Success" , status_code= 200 , headers={ "Content-Type" : "text/plain" } ) call_type = body[ "call" ][ "details" ][ 0 ][ "call_type" ] # コメント 3 if call_type not in ( "INCOMING_CALL" , "OUTGOING_TRANSFER" , "QUEUEING_CALL" ): return success_response comments = body[ "call" ][ "details" ][ 0 ][ "comments" ] # コメント 4 if not comments: return success_response sorted_comments = sorted (comments, key= lambda x: x[ "created_at" ]) first_comment = sorted_comments[ 0 ][ "value" ] second_comment = sorted_comments[ 1 ][ "value" ] if len (sorted_comments) > 1 else "" tags = [ t[ "value" ] for t in list ( filter ( lambda x: x[ "value" ] in ( "[OW] 緊急度: 高" , "[OW] 緊急度: 中" , "[OW] 緊急度: 低" , "[OW] 要望度: 高" , "[OW] 要望度: 中" , "[OW] 要望度: 低" , ), body[ "call" ][ "details" ][ 0 ][ "tags" ], ) ) ] # コメント 5 if not tags: return success_response sorted_tags = sorted (tags) first_tag = sorted_tags[ 0 ] second_tag = sorted_tags[ 1 ] if len (sorted_tags) > 1 else "" participants = { p[ "from_to" ]: p[ "company_name" ] for p in body[ "call" ][ "details" ][ 0 ][ "participants" ] } company_name = participants[ "FROM" ] speech_recognition_summary = body[ "call" ][ "details" ][ 0 ][ "speech_recognition" ][ "raw" ] url = f 'https://{body["call"]["tenant_code"]}.miitel.jp/app/calls/{body["call"]["details"][0]["id"]}' priority_and_urgency = { "[OW] 緊急度: 高" : "高" , "[OW] 緊急度: 中" : "中" , "[OW] 緊急度: 低" : "下" , "[OW] 要望度: 高" : "高" , "[OW] 要望度: 中" : "中" , "[OW] 要望度: 低" : "下" , } urgency = priority_and_urgency.get(first_tag, "" ) priority = priority_and_urgency.get(second_tag, "" ) note_template = """▼顧客が言っている要望詳細(もしあれば録画・録音): 企業名: {company_name} 応対履歴: {url} <原文ママ> {speech_recognition_summary} ▼なぜそう言っているか?どのような顧客か?解釈を記入ください: {second_comment} ▼要望度合い(高・中・下):{priority} ▼緊急性(高・中・下):{urgency}""" notes = note_template.format( company_name=company_name, url=url, speech_recognition_summary=speech_recognition_summary, second_comment=second_comment, priority=priority, urgency=urgency, ) コメント 2 の箇所では返却用のレスポンスオブジェクトを変数化しています。 Asana への連携する・しない/成功・失敗に関わらずこの値を返していきます。 お客様から受けた問い合わせを連携する想定なのでコメント 3 の箇所の分岐処理では着信系以外の応対種別を省いています。 コメント 4 の箇所の分岐では通話中のメモ用にとったコメントが存在しなければ連携なしとしています。 同じくコメント 5 の箇所の分岐では緊急度や優先度の応対メモがなかった場合にも連携なしとします。 その他取引先会社名・音声認識結果の要約・応対履歴 URL を変数に格納し、Asana の notes に挿入するテンプレートに埋め込みます。 Asana へのリクエスト 最後に下記のようになります。 try : client = asana.Client.access_token(asana_token) client.tasks.create_task( { "workspace" : "workspace_id" , "projects" : [ "project_id" , ], "name" : first_comment, "notes" : notes, }, opt_pretty= True , ) except : pass return success_response asana モジュールにて asana_token から access_token のオブジェクトを取得します。 これまでの処理で得られた workspace_id, project_id, first_comment, notes を引数に task を作成する関数を実行します。 例外処理はエラー確認用に出力しておくと良いですが今回は pass にて割愛します。最後に 200 レスポンスを返却することで実装は完了です。 デプロイ Chalice のデプロイは下記コマンドからできます。 chalice deploy 処理が終了すると api gateway の URL が発行されるのでそれを控えておきましょう。 6. MiiTel 側の設定 前章で Asana タスク自動作成を行うマイクロサービスを構築し、curl による疎通が確認できたので、発行された URL を MiiTel 側に設定していきます。 サポートページの引用になりますが、以下のように設定画面にアクセスします。 管理者権限があるユーザーで MiiTel Admin にログインします。 (MiiTel Admin にアクセスするには、MiiTel Analytics 画面右上の歯車アイコンをクリックします) [外部連携] > [Outgoing Webhook] を選択します。 [連携設定を追加] をクリックします。 各項目を設定していきますが今回のケースでは添付画像のような設定にしていきたいと思います。 設定時のポイントとしては以下になります。 追加ヘッダーを設定する リクエストの軽量化のため、音声認識結果のフレーズとキーワードをペイロードから除外する [保存] をクリックして設定は完了です。 7.着信〜音声認識〜タスク作成まで MiiTel Phone を起動した状態で着信通話をしてみます。まず、UI をワイドモードに変更し、「電話に出る」を押下すると通話情報が確認できます。 続いて「コメント」タブに移動し、Asana タスクのタイトルを記入して保存します。 次に「応対メモ」から緊急度・要望度タグを選択して保存しておきます。 通話が終了したときに応対メモとしてチェックした内容が正しいかを確認して保存、コメントも同様に保存を再度押下します。 作成された応対履歴に移動し、コメントからこの応対における補足内容を記入します。 音声解析が完了すると IT リクエストプロジェクトに Asana タスクが作成され、記入内容・音声認識結果が反映されていることが確認できました。 8.まとめ 本記事では、Outgoing Webhook の受け口として Chalice でマイクロサービスを構築し、Asana タスクを作成する実装と手順を紹介しました。 音声認識結果の要約が見れることによって、 MiiTel の応対履歴を閲覧せずとも要望背景の把握に活用することができそうですね。 お客様のユースケースに応じて自由にアレンジが可能な Outgoing Webhook をぜひご活用ください。
アバター
はじめに RevComm の小門です。 普段はバックエンドエンジニアとしてプロダクトの開発に携わっています。 2022年12月まではインフラエンジニアとして全社横断的なシステムのセキュリティ強化対応を担当していました。 今回は、セキュリティ強化の一環として「プラットフォーム診断」およびそれに付随したコンテナイメージのセキュリティ改善対応について紹介します。 プラットフォーム診断 プラットフォーム診断とは OS やミドルウェアに既知の脆弱性が潜んでいないか洗い出すことを指します。 プラットフォーム診断として脆弱性を検知するにはスキャンツールが必要となります。 例えば OSS の脆弱性ツールとして下記のものがあります。 サーバー用 Vuls, OpenSCAP, OpenVAS コンテナ用 Trivy, Clair RevComm では主に AWS を使用してサービス提供しており、AWS のセキュリティサービスに Amazon Inspector というものがあります。 Inspector を使うと EC2、ECR を対象にした脆弱性スキャンを実現できます。 結論として、下記のポイントからプラットフォーム診断のツールとして Amazon Inspector を採用しました。 機能要件を満たしている点 仮想マシン(Amazon EC2)とコンテナ(Amazon ECR)のスキャンに対応している マネージドである点 AWS の他サービスと連携して自動スキャンできる 運用に向けた課題 RevComm では Amazon ECS を利用して提供している Web アプリケーションのサービスがあります。 Inspector を利用するとスキャンが自動で実行されるため便利ですが、ECR イメージのスキャンに関してはデフォルトの機能だけでは運用を開始できない課題がありました。 1点目は、棚卸しすべきコンテナイメージ(ECR)の対象を絞り込むことが難しいことです。 サービスのリリースに伴って新しいコンテナイメージを ECR に保存し、タスク定義で指定するイメージも更新します。 Inspector の機能でリポジトリやタグなどの条件で ECR のイメージを絞り込むことはできますが、リリースの度に使用するイメージが変化する場合は特定が難しくなります。 例えば、ソースコードの git ハッシュ値をコンテナイメージのタグでバージョニングしていくケースが考えられます。 参考: Best Practices - Running your application with Amazon ECS - Amazon Elastic Container Service As a best practice, tag container images with a unique tag for each build. We recommend that you tag your images using the git SHA for the git commit that was used to build the image. また、開発と本番環境間で同じコンテナイメージを使用する方法として AWS アカウント間で ECR イメージを共有することができます(Resource based permission )。 これは複数の環境で同一コンテナイメージからアプリケーションを実行するのに便利ですが、この場合デフォルトだと Inspector で別アカウントの ECR イメージに関する情報が取得できません。 そのため、複数 AWS アカウント上の ECR イメージのスキャン結果を集約管理する必要があります。これが2点目です。 以上より、ECS サービスで使用するサービス提供のために実際に使用されるコンテナイメージのタグを適切に特定し、ECR リポジトリもアカウント跨ぎである可能性を考慮したツール整備と運用を検討しました。 実現した構成 上記の課題を解決するアプローチとして、本番環境で実稼働している ECS タスクの情報を取得し集計すべきコンテナイメージタグを抽出するようにしました。 具体的な構成イメージと処理概要を示します。 AWS Organizations の機能と連携して「Inspector 管理アカウント」を設定する。 …Inspector 管理アカウントでは全アカウントにまたがった Inspector スキャン結果を取得できる 本番環境で稼働している ECS タスクの情報から、実際に使用中のコンテナイメージを特定する 対象のコンテナイメージに関する脆弱性情報を Inspector 管理アカウント上でフィルタリング抽出して集計する ポイントは 2. において本番環境で稼働中の ECS サービスおよび ECS タスク定義から集計すべきコンテナイメージを絞り込んでいる点です。 下記の API を組み合わせて集計するスクリプトを実装しました。 ecs list-clusters ecs describe-services ecs describe-task-definition これにより、プロダクトとして稼働するサービスの実態を必要十分に集計することを実現しました。 コンテナイメージ改善 前述したプラットフォーム診断と合わせて、プロダクトサービスを提供するコンテナアプリケーションの脆弱性を改善する対応を実施しました。 具体的には、コンテナイメージが軽量な環境となるように Dockerfile を修正しました。 RevComm ではバックエンド言語として主に Python を使用しているため、Python を例にポイントとなる点を紹介していきます。 ベースイメージに slim イメージを使う 本番用のアプリケーション環境として使用する場合、ベースイメージとして slim イメージを使用します。 slim イメージと非 slim イメージ(例えば python:3 や python:3.11 )の大きな違いはビルトツールや dev パッケージの有無です。 $ docker run -ti --rm python:3. 11 . 1 apt list --installed | grep " ^lib.*-dev " | wc -l 84 $ docker run -ti --rm python:3. 11 .1-slim apt list --installed | grep " ^lib.*-dev " | wc -l 0 上記のように slim イメージには libxxx-dev といった dev パッケージが一切含まれていないことが分かります。 2 つのイメージを Amazon ECR の拡張スキャン機能でスキャンした結果を比較してみます。 ※スキャン結果は 2023/2/2 時点のもの python:3.11.1 python:3.11.1-slim(※脆弱性の検出なし) 不要なパッケージをインストールしない セキュアなコンテナイメージを作り上げるためには不要なパッケージをインストールしないことが重要です。 結果的にイメージが軽量になり、可搬性も向上します。 例えば前述の slim イメージを使うと gcc が使えませんが、Dockerfile の中で gcc をインストールしてしまうのは良い方法ではありません。 FROM python:3.11.1-slim RUN apt-get update \ && apt-get -y install gcc # <= ★No good ビルド用に gcc が必要な場合があっても、実行時に gcc は(ほとんどの場合)不要だからです。 マルチステージビルド アプリケーションに必要なビルド処理と軽量かつセキュアな実行環境を両立させるために有用なのがマルチステージビルドです。 ※本記事ではマルチステージビルド自体の解説は割愛します。 Multi-stage builds | Docker Documentation マルチステージビルドを使った Python 用の Dockerfile の例を紹介します。 サンプルとして、インストール時に C コンパイラが必要な uWSGI(WSGI 規格のアプリケーションサーバー)を slim イメージで利用するケースを考えてみます。 # -- stage: builder FROM python:3.11.1 AS builder RUN pip3 install --no-cache-dir uwsgi # -- stage: runner FROM python:3.11.1-slim AS runner RUN apt-get update \ && apt-get -y upgrade \ && apt-get install -y \ # for uWSGI libxml2 COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages COPY --from=builder /usr/local/bin /usr/local/bin # uWSGI を使用して WSGI アプリケーションを起動できることを確認 COPY main.py ./ CMD [ "uwsgi" , "--http" , ":8000" , "--wsgi-file" , "main.py" ] EXPOSE 8000 1つの Dockerfile の中で builder と runner 、2つの「ステージ」を定義しています。 builder ステージ:uwsgi ライブラリをビルド・インストールする runner ステージ:インストール成果物である site-packages 配下をコピーすることで使用できるようにする main.py は HTTP レスポンスを返すための最小限のコードです。 def application (env, start_response): start_response( '200 OK' , [( 'Content-type' , 'text/plain; charset=utf-8' )]) return [b 'Hello World' ] 上記 Dockerfile をビルド・起動してレスポンスが受け取れることを確認してみます。 $ # ビルド対象ステージを --target で指定する $ docker build . --target runner -t multistage-test $ docker run -d --rm \ --name multistage-test \ -p 8000:8000 \ multistage-test $ # アクセス確認 $ curl localhost:8000 Hello World $ docker kill multistage-test 本記事で紹介した Dockerfile の改善例については SpeakerDeck のスライドでより詳しく解説していますので、ぜひご覧ください。 まとめ Amazon Inspector を使ったプラットフォーム診断の実践例と、コンテナイメージ改善の取り組みについて紹介しました。 コンテナイメージには必要最小限のパッケージ、ライブラリのみインストールするようにすることで軽量かつセキュアな環境を作成することができます。 また、新しい脆弱性は日々報告されていくため、一度作ったイメージは定期的に最新化する運用も重要です。 RevComm は電話営業や顧客対応を可視化する音声解析 AI 搭載型のクラウド IP 電話 MiiTel (ミーテル) を提供しています。 今後もお客様に安心して MiiTel をご利用頂けるよう、引き続きプロダクトのセキュリティ向上に取り組んでまいります。 また、エンジニアを積極採用中ですので、興味をお持ち頂けましたらぜひともご応募ください。 hrmos.co
アバター
こんにちは、RevComm テックブログ運営担当の小山と申します。この度、社内で共有された技術スライドの一部を公開していくことにしました。 RevComm のエンジニアの情報発信は、今までこのテックブログが中心でした。しかし、社内には技術情報をまとめたスライドが多数あります。中には社内外を問わず広く参考になるような内容も共有されており、技術資料として公開することになりました。 今回はスライドを公開しようとした背景と、最初に公開するスライドの紹介を記事にします。 「どんなスライドが公開されているのかをまず知りたい!」という方は 今回公開する2つのスライドの紹介 をご覧ください! RevComm は社内での技術共有が盛ん 私が RevComm に入社したのは 2022 年の 1 月。そのときにはエンジニアの情報発信の文化はこれから作っていくのだろうなという印象でした。入社前は情報不足を感じていましたが、機会があれば自分で盛り上げていくのもありだろうなという気持ちで入社しました。 実際に入社してみると、社内では技術共有が盛んに行われていました。 Tech Talk(社内勉強会) は有志による発表がほぼ毎週行われており、そのほかにも業務に関わる技術共有の場が必要に応じて作られていました。 様々なジャンルのテーマで開催されている Tech Talk 社内の情報共有の代表例として Tech Talk について説明します。 RevComm では、毎週 30分間 Tech Talk が開催されています。Tech Talk は有志で運営されており、自主的に手をあげたり、発表して欲しい人にリクエストしたりという形で発表者が決まっています。ジャンルは自由で、より良いコードの書き方や、テスト、プロジェクトマネジメントなど様々です。個々人の経験や学習から得た知見を全体へ共有する場になっています。 直近の Tech Talk のタイトルは以下のようなものがあります。 RevComm 版 VSCode オススメプラグイン - 2022 データガバナンス入門 初心者プログラマーにこそ勧めたい TDD AWS 認定試験(アソシエイト)は業務に活きるのか、更に活かすには ゲームボーイを作ろう 2022 年には 39 回開催されており、発表に使われたスライドが社内資料として蓄積されています。 なぜスライドを公開するのか? Tech Talkを始めとして、社内では多数のスライドが作られています。これまでを振り返ると、ドキュメントよりもスライドで技術共有というケースの方が多いかもしれません。そんな RevComm の業務風景を公開して、自社を知ってもらいたいという気持ちが、技術スライドの公開を考えたきっかけです。あえてブログにまとめ直すよりも、そのまま公開した方が RevComm の情報共有のあり方が伝わると考えています。 Tech ブログを 2022 年の 2 月に始めて、以前よりは RevComm の技術情報を社外に伝えられるようになりました。しかし、十分とはまだ言えません。普段作っているスライドを通じて、RevComm を認知していただくきっかけや、より深く知っていただきたいと思っています。 また、スライドを通じて RevComm の幅広い業務領域を感じてもらえるきっかけになり得ると考えています。特にバックエンドチームはTech Talk などでも技術共有をよくしており、今回紹介するスライドもバックエンドチームメンバーの発表資料になります。その他のチームでも技術共有は盛んで、例えば私の所属するフロントエンドチームの優秀なエンジニアが、開発者体験を向上させるための取り組みを発表しています。 そういった技術共有に使うスライドは、日々の課題解決や工夫が詰まったものです。テーマによりますが、社内だけではなくどこかの誰かの学びの機会にもなりえるものと考えています。 今回公開する2つのスライドの紹介 よりよい Dockerfile を考える 〜 Python の実例とともに 〜 speakerdeck.com Python の Docker ファイルのより良い書き方を知ることができるスライドです。題名には Python とついていますが、Python 以外の言語でも参考にできそうですね。開発利便性・可搬性・セキュリティの観点で、最適化するポイントがわかるスライドとなっています。 Tech Talk での発表後、他のチームでも導入されて大きな改善をすることができたという実績があります。イメージサイズが 395MB から 94MB になり、脆弱性を無くすこともできました。 Introduction to Dependency Injection 「DI」の整理とそのメリット speakerdeck.com 依存性の注入(Dependency Injection)と依存性の逆転(Dependency Inversion)の関係が図解されているスライドです。プロジェクトの実コードを交えて解説がされています。どういったケースで使うと良いか、注意点があるかということもわかりやすいものとなっています。 終わりに 社内のコミュニケーション・技術共有の手段としてスライドが作られてきました。今後、社内で共有されたスライドを、このブログでもいくつか紹介していく予定です。 ブログ以外にも、技術スライドの公開によって、学びの機会や、RevComm に興味を持っていただけるきっかけになると嬉しいです。 RevComm は開発者やデザイナーの採用に力を入れています。情報発信をしていきたいという意欲のある方も大歓迎です!是非とも仲間になっていただけると嬉しいです! hrmos.co
アバター