TECH PLAY

NTTドコモビジネス

NTTドコモビジネス の技術ブログ

613

本記事では、ソフトウェアプロダクト開発において、スクラムから独立した エンジニア × デザイナ × マーケタ の少人数チーム(以下、ミニチーム)を作って活動することにより、事業優先度が低く後回しになりがちなユーザビリティの課題を解決していった事例や学びを紹介しています。 目次 目次 はじめに NeWorkとは NeWorkのチーム編成 エンジニアが自由にプロダクト改善に取り組むことの難しさ ミニチームの発足 ミニチームの課題解決フロー 1. 課題選定 2. 見つけた課題が解決する価値のある課題か見極める 3. 他チームとの連携 4. デリバリープロセス ミニチームの改善事例 ミニチームのメリットと課題 メリット ユーザー対話で高評価を得ている機能は、ミニチーム発のものが多かった コミュニケーションのオーバーヘッドが小さい 簡単なバグ修正のリードタイムが短い 体験価値の向上を軸に越境できるチーム体制 課題 効果測定手法が定まっていなかった 収益拡大に寄与しているか、定量的に示せなかった メンバーからのコメント デザイナ 齋藤 マーケタ 藤原 おわりに (付録) ミニチームの改善事例の詳細 デフォルトのルーム名を変更 ルームバブルのクリック入室 招待リンクの送信 にゃわーく ルーム名の折り返しの改善 バーチャル背景のアップロード オンボーディング タイルレイアウト選択機能 デバイスの切り替えトースト フォールバック入室の通知 プロフィール画像の拡大 カメラの映像と画面共有の同時配信 通話中に画面をOFFにしない 通知音量調整 ワードバブル(仮) 離席 通話中の UI からルーム詳細を開く動線の追加 はじめに こんにちは、NeWorkチームの中里です。 「なんとなく使いづらいし、ユーザーもモヤモヤしていそうだけど、ビジネスインパクトが小さいから後回し…」 —— そんな課題、あなたの担当するプロダクトにもありませんか? NeWorkでも、まさにそうした機能を改善できずにいましたが、思い切って専任の少人数チームを作り、改善活動に取り組みました。この記事は、具体的な取り組み内容とそのチームのエンジニアとして 1 年程活動をしていた私目線での得られた学びやメリット、課題を紹介します。 NeWorkとは NeWorkは、NTT Comが提供するオンラインワークスペースです。 「リアルよりも話しかけやすい」コミュニケーションを実現することを目指し、オンラインでも気軽に声をかけ合える環境を提供しています。 残念ながら、NeWorkは約1年後の2026年3月31日をもってのサービス終了を発表しています。これまでご利用くださっていた皆さまには申し訳ない気持ちでいっぱいです。 しかしサービス終了が決まってからも前向きな気持ちで活動は続けてきました。本記事もそのような気持ちから執筆したものとなっております。 NeWorkのチーム編成 NeWorkには、以下のようなチーム体制があります。 1 プロダクトチーム: サービスの企画を担当 プロモーションチーム: 販売推進やマーケティングを担当 開発チーム: 実際の開発を担当 開発体制としては、プロダクトチームがプロダクトオーナーを務めるスクラムチームが3つ存在し、そこに開発チームのメンバーがそれぞれ参加して、2週間のスクラムで開発しています。 スクラムチーム1: Web 全般 スクラムチーム2: 主にエンタープライズ スクラムチーム3: モバイルアプリ エンジニアが自由にプロダクト改善に取り組むことの難しさ このプロダクトが大好きな私は、開発優先度に物足りなさを感じることがありました。たとえば、 全ユーザーの1%にも満たないエンタープライズプランの管理者向け機能に多くの開発時間を割く一方、すべてのユーザーが利用する通話画面の課題は後回しになってしまう。 このようなやるせなさを感じることが何度もありました。 NeWorkチームはアジャイル開発を行っており、NTT Comの中では比較的柔軟に動ける組織です。しかし、多くの企業に見られる傾向として、どうしても事業計画の遂行や収益拡大を最優先に考えないといけないプレッシャーがあります。 「本当はもっと改善したい部分が山ほどある」と感じていても、ビジネスを成立させるために、すぐに収益化につながる機能を優先せざるを得ない、というわけです。 1年前に投稿した「 NeWork開発チームが自主的な改善を行う 20%ルールを 1 年間運用してみて 」という記事では、スプリント内で最大20%の時間を自由に使ってプロダクトのためになることを行う、という制度を紹介しました。 このルールのおかげで、新技術の調査や技術的負債の返済、開発基盤整備、エンジニアのアイデアの実現などはある程度進められるようになりました。しかし、2週間スプリントの最後の2日間だけ自由に使えるといっても、そこで終わらなかったタスクは次回の自由時間まで2週間も空いてしまう。 結果として、 20%ルールの中で"ユーザー体験まで深く考え抜いた課題解決"を行うのは難しい 現状がありました。 ミニチームの発足 こうした課題感をなんとか解決しようとして生まれたのが、ミニチームです。 このミニチームはスクラムチームとは完全に独立して活動し、メンバーの入れ替わりはありましたが、最終的には以下の4名体制で改善を回していました。 エンジニア - 2人 デザイナ - 1人 マーケタ - 1人 以下の図は、NeWorkにおける全体のチーム体制を視覚化したものです。 ミニチームの改善活動はディスカバリーを行い、ユーザーストーリーを書くところからスタートします。そこからデザイナがデザインを起こし、エンジニアが実装し、マーケタが効果計測をする —— つまり、一連の流れをミニチーム内で完結できる仕組みです。 とはいえ、デザイナとマーケタはミニチーム専任というわけでもなく、ミニチームをメインにコミットしつつ、スクラムチームのタスクもこなすという体制を取っていました。 ミニチームの方針としては、直ちに大きな収益効果は見込めないものの、ユーザーが実際に使いにくさを感じている箇所の改善を担当していました。これは、スクラムチームが事業計画を軸に開発を行い、さらにユーザーフィードバックの中でも収益面や事業方針に影響しそうな課題を解決するという方針を補うことを狙ったものです。 もっとも、ミニチームの活動は“ビジネス的に意味がない”わけではないと考えており、収益面でもよい結果をもたらす効果はありえると考えています。たとえば、トライアルからの有償契約につなげるうえでの使いやすさの向上や、導入後に解約を減らす効果が期待できるといったことです。 ミニチームの課題解決フロー ミニチームで行っていた「どのように課題を見つけ、どうやって解決していくか」のプロセスをご紹介します。いろいろな方法を試した結果、最終的には下記のような流れに落ち着きました。 1. 課題選定 まずは、課題の選定です。 課題のネタとしては、プロダクトチームがユーザーフィードバックやチーム内フィードバックに ICE スコアリングをして Notion のデータベースにまとめてくれているので、これを参照しています。 ICEスコアリングとは以下の 3 つを元に優先度を判断するフレームワークです。 Impact (影響度) Confidence (成功率の自信度) Ease (実現のしやすさ) スクラムチームの場合は、これに Business(有償契約につながるか) も加え、B-ICEという形で独自に採点していました。 一方、ミニチームは "B"を外した純粋なICE のスコアが高い課題 を優先的に見ていました。つまり「ビジネス的な収益には直結しないかもしれないけど、多くのユーザーの利益になり、難易度も高くない」という課題を見つけるわけです。 また、私たち自身も普段から NeWorkを使って仕事をしている(いわゆるドッグフーディング) ので、日常的に「ここ不便だな…」と気づいたらバックログに投げ込む、というケースも多いです。あとはユーザーからは報告されていないような小さなバグでも、発見次第対処するようにしていました。 2. 見つけた課題が解決する価値のある課題か見極める 見つけた課題がユーザーが本当に解決したいものかという視点は、案外見落としがちです。ミニチームは少人数でリソースが限られているので、本当に価値がある課題かどうかを厳しく見極めるようにしていました。 そこで取り入れているのが、 「前提 / As-is / To-be」 というフレームワークです。課題に着手する前に、以下の 3 点をしっかり書き出して整理します。 前提 : 「誰がどのような状況におかれているか」 As-is : 「いま、実際にどうなっているか」 To-be : 「理想的にはどうあるべきか」 ここで、As-is / To-be を客観的に書けない場合は、そもそも改善の優先度が低いと判断してスルーするようにしていました。 そして私たちは、この「前提 / As-is / To-be」をユーザーストーリーとして活用しています。 一般的なユーザーストーリーは「誰が / なぜ / 何をしたい」を書く手法が主流で、NeWorkの他のスクラムチームもこれを採用しています。しかしミニチームでは、すでに存在するNeWorkの課題を解決することがメインであるため、より客観的に“現状のプロダクトの課題”と理想とのギャップを浮き彫りにできる「前提 / As-is / To-be」のほうが適していると考えました。 実際、「誰が / なぜ / 何をしたい」を使っていた頃は、「この技術を使えば新しい機能が作れそう!」という、いわゆる“How”ベースのひらめきに突っ走ることがありました。この手法だと案外自分たちに都合のいいストーリーが書けてしまうため、アイデアに勢いがつきすぎると 「この機能、絶対いいじゃん!」と客観性を失ってしまう ケースがありました。 そこで、私たちは As-is / To-be を明確に書き出し、課題の本質を客観的に捉えることを意識するようにした結果、より確かな価値につながる改善を行えるようになったと感じています。 我々が書いていたユーザーストーリーの例 [前提]: ルームに入室する際に、認識されているマイクが存在しない場合は自動的に聞き耳入室になり、通常の入室はできないという仕様がある。 [As-is]: 上記の仕様をユーザーは知らない(知ることができない)ため、この事象に遭遇した際に不具合だと勘違いしてしまい、問い合わせや別の通話アプリに移動してしまう。 [To-be]: 認識できるマイクが存在しないユーザーがルーム入室時に不具合だと誤認せず、解決方法が理解できるようになっている。 3. 他チームとの連携 ミニチームはスクラムチームから独立していますが最低限のスクラムイベントには参加して、情報共有や進捗をすり合わせていました。 デイリースクラム : 日々の進捗をお互いに簡単に確認 スクラムオブスクラムミーティング : 各スクラムチームや関連チーム間での連携を図る さらに、 NeWorkそのものを使って仕事をしている ことも大きいです。NeWorkは「誰がどこで、どんな話をしているか」がひと目でわかるインタフェースと、「聞き耳」という機能で発言せずとも会話を“聞く”ことだけをできる仕組みがあり、透明性の高い働き方ができています。 「あ、あのチームが今 ○○ 機能をいじってるっぽい? じゃあタイミングがかぶらないように注意しよう」 みたいな、ちょっとした情報共有や調整を自然と行え、コミュニケーションにあまりコストをかけずに、コードのコンフリクトを防いだり解決するべき課題が被らないようにしています。 (ところで、入社以来NeWorkを使って仕事をしているので、NeWorkのサービス終了後、どうやって仕事をしていけばいいか…路頭に迷っています) 4. デリバリープロセス NeWorkのデリバリープロセスはデイリーリリースが基本です。ステージング環境(developブランチ)で1日間ドッグフーディングしたインクリメントは自動的にプロダクション(mainブランチ)環境へデプロイされる仕組みになっています。詳しくは「 リリース頻度を毎週から毎日にしてみた 」という記事で紹介しています。 ミニチームは要件定義〜デザイン〜実装までチーム内で完結するため、改善の多くがプロダクトオーナーやステークホルダの目にほとんど触れません。 大きめの変更についてはスプリントレビューで関係者に見てもらい、リリースの判断を仰ぎます。一方、小さな改善であればわざわざレビューを待たずに mainブランチへマージ → 自動リリースの流れに乗せてしまい、次のスプリントレビューで事後報告という形を取っていました。 こうすることで、Feature Flagをわざわざ設定する手間やリードタイムを短縮できているのもポイントです。もちろん、こうしたやり方はマネージャ陣の協力や信頼関係が不可欠で、理解を示してくれているマネージャ陣には本当に感謝しています。 ミニチームの改善事例 ミニチームでは以下のような改善を行ってきました。詳細は本記事の末尾の付録に記載しましたのでご興味がありましたらご覧ください。 デフォルトのルーム名を変更 ルームバブルのクリック入室 招待リンクの送信 にゃわーく ルーム名の折り返しの改善 バーチャル背景のアップロード オンボーディング タイルレイアウト選択機能 デバイスの切り替えトースト フォールバック入室の通知 プロフィール画像の拡大 カメラの映像と画面共有の同時配信 通話中に画面をOFFにしない 通知音量調整 ワードバブル(仮) 離席 通話中の UI からルーム詳細を開く動線の追加 ミニチームのメリットと課題 メリット ユーザー対話で高評価を得ている機能は、ミニチーム発のものが多かった 社内外のユーザーと話す機会があると、 「あの機能すごく便利ですね」と言われるものの多くがミニチームで作った機能 でした。小さな改善でも直接的にユーザー体験を向上させることが多く、結果的にプロダクトのファンを増やすことにもつながったと思います。 コミュニケーションのオーバーヘッドが小さい チームが少人数であるため、PBI(Product Backlog Item)の記載を必要最小限の簡素な形で進められました。加えて、デザインやインタラクションなどの細かな仕様は口頭ですり合わせることで、ドキュメント作成にかかる手間を大幅に削減できたのも大きなメリットでした。 簡単なバグ修正のリードタイムが短い 問い合わせがあってから、早いもので最短 2 日ほどで不具合を修正しリリースできることもありました。 体験価値の向上を軸に越境できるチーム体制 ミニチームでは、エンジニア・デザイナ・マーケタといった職種の垣根を越え、 全員が「ユーザー体験の向上」を共通の目標として捉えていました 。必要であれば、誰もが仕様検討やデザイン検証、アンケート作成、計測設計などに積極的に関わる姿勢ができていました。 特徴的だったのは、エンジニアとデザイナがペアデザインを行うケースがあったことです。たとえば、エンジニアがデザインの素案を作り、それをリアルタイムでデザイナがレビューするという流れです。こうすることで、エンジニアはデザインスキルを学び、デザイナは技術的制約や実装容易性をその場で把握できるため、拡張性と実装難易度を考慮したデザインの感覚の醸成に繋げられるメリットがありました。 また、ミニチームでは、ディスカバリー(課題の洗い出し)からデザインの方向性検討、実装、検証、そしてリリースまでをほぼ自分たちの裁量で進められるという特徴がありました。振り返ると、これはいわゆる“ プロダクトエンジニア ”的な動きに近かったのかもしれません。 「プロダクトエンジニア」という言葉は、AtlassianのSherif Mansourさんが「 Product engineers 」という記事で提唱して話題になった概念です。具体的には、フロントエンド・バックエンド・デザインなどの領域を横断しながら、ビジネス面やユーザー体験を総合的に考え、愛されるプロダクトを作るエンジニアのことを指すと認識しています。 ミニチームでの動きがどこまで理想的な“プロダクトエンジニア”に近かったかは分かりませんが、少なくとも私自身のキャリアにおいては、NeWorkの価値を高めるために幅広い経験を積めたことが大きな収穫だったし最高にやりがいを感じていました。 課題 効果測定手法が定まっていなかった まず、適切なKPIが定まっていませんでした。もともとは新規登録ユーザーの定着率(1週間・4週間後の利用率)をKPIにしていましたが、利用率は企業やチーム単位の導入状況に大きく左右されるため、短期的な成果を見る上では参考になりにくかったです。 結果として 「体験の改善」を数値化することは簡単ではなく 、ユーザーテストやアンケートによる定性的な評価を行うのがベストかと議論しましたが、コストが高いという課題もあり、十分に手をつけられませんでした。 さらに、個々の機能改善の効果測定についても、必ずしも十分にできていたとは言えない状況でした。ボタンなどの明確なユーザーアクションを伴う改善は計測しやすく、ある程度の効果は数値化できたものの、ユーザビリティのような心理的変化はほとんど見えていませんでした。 振り返ってみると、社内のNeWorkユーザーの集まるSlackチャネルが存在したので、そこを活用して気軽に意見を聞ける仕組みを整えておけば、定性的な評価も比較的低コストでキャッチできたのではないかと感じています。 収益拡大に寄与しているか、定量的に示せなかった ミニチームでは、トライアルユーザーの体験向上や解約率の低減といった観点から、長期的には収益やブランド価値に貢献できると考えています。 そして、ミニチームが プロダクトにおいてなかなか手の回らない箇所を率先的に改善し、スクラムチームが大きな機能や収益拡大施策に専念できるようにしている 、という構造を意識していました。 もっとも、直接的な収益拡大にどこまで貢献しているかは、定量的に示すのが難しいという課題もあります。多くのメンバーには理解をいただきつつも「収益に貢献しているわけではないのでは?」と思われがちで、開発の現場から距離の遠いステークホルダに十分説明できていなかったかもしれません。この点はもう少しコミュニケーションを取るべきだったと感じています。 メンバーからのコメント 本記事執筆にあたり、デザイナとマーケタの方からもコメントをいただきましたので、以下に紹介します。 デザイナ 齋藤 ミニチームの活動はただ純粋に”おもろかった”。 ちゃんとユーザーが欲しているものを作れている感覚、コミュニケーションや管理のストレス無かったこと、頑張って作った機能がユーザーに刺さった反応など、複合した結果”おもろかった”に集約されています。 各メンバーからもこのコメントが出ていることを考えると本当に良い活動だったのだと感じます。デザイナー目線でも、開発メンバーと共創でものづくりをしていく過程は通常のAgile開発よりもスピードが速くとても多くの学びを得られました。 今まで NeWorkをご利用いただきありがとうございました。 サービス終了になってしまった以上、私は次の価値を作りに行きます。そしてまたいつか、皆さんの手元にその価値が届くことを願っています。 マーケタ 藤原 NeWorkが大事にしている「誰が言ったかではなく、何を言ったか」をものすごく体現できているチームだったと思います。私は新入社員としてこのチームに加わりましたが、フラットな関係性のおかげで、自分の意見を素直に発信しやすい環境でした。互いに「違うものは違う」「良いものは良い」と率直に意見を交わせたことが、何よりもユーザー視点での改善につながったと思います。 また、効果検証を担う立場として、私たち自身が「使いたい!便利!」と感じる機能ほど、実際のユーザーも気に入って使ってくれていました。(ルームをクリックして入室する機能や、にゃわーくなど…) ミニチームでの経験を通じて、サービス提供者とユーザーが対立構造にあるのではなく、一緒に使いやすいプロダクトを創っていく関係性を築くべきだと実感しました。 NeWorkとしては一区切りとなりましたが、これまでの経験を活かし、毎日使いたくなるプロダクトづくりに携わっていきたいと思います。今までありがとうございました! おわりに ミニチームのリリースした機能が好評だったことを考えると、活動自体には一定の効果があったと感じています。一方で、ビジネス面への貢献度をどう評価するかは、引き続き課題として残ります。周囲の理解を得た上で良いプロダクトを生むために必要なことだと思うので、これからも考えていきたいです。 個人的には、この活動を通じてさまざまな経験を積むことができ、確かな成長を実感しています。ミニチームを任せてもらえたことには、大変感謝しています。 もし同じようなプロダクト改善専任の少人数チームを立ち上げるなら、 独立性や裁量、目的意識の共有、迅速でフラットなコミュニケーション、そしてマネージャやステークホルダの理解・信頼 が重要になると思います。 残念ながら、NeWorkはサービス終了となってしまいますが、終了を惜しむ声をいただけたことや「NTT Comにはこうした良いサービスを作れる人がいる」と思ってもらえた(と信じています)ことは、私にとって大きな財産です。今後も、この経験を活かしてより良いプロダクト作りに貢献していきたいと思います。 (付録) ミニチームの改善事例の詳細 さいごにミニチームが改善した事例をいくつかご紹介します。これ以外にも小さな改善やバグ修正を行っています。 デフォルトのルーム名を変更 NeWorkでワークスペースを新規作成した際のデフォルトのルーム名を変更しました。 変更前は「定例」、「開発チーム」、「朝会」、「カフェ」というルーム名でしたが、これは多くの人にとって具体的に利用しているイメージが湧きにくいルーム名でした。そこで、具体的な動作に結びつく「雑談ルーム」、「ミーティングルーム」、「作業ルーム」というルーム名にしました。また、1つを未定義にしたことでルーム名を自由に定義できることを暗示しています。 ルームバブルのクリック入室 ルームバブル自体をクリックするだけで入室できるようにしました。 改善前はルームバブル上の青い入室ボタンか、「…」からしか入室できずわざわざカーソルを合わせるという心理的負荷がありました。 改善後は押下範囲の拡張により、操作性が上がりました。さらに直接聞き耳に参加することも可能になりました。一方で誤操作を起こしやすくなったため、通話中のルーム移動時にダイアログを出すオプションや機能をOFFにするオプションも用意しています。 招待リンクの送信 ワークスペースの招待リンクをNeWork上で送信できるようにしました。 これまでは招待リンクをコピーして別の方法で共有する方法のみでしたが、相手のメールアドレスを指定して招待を送信できるようにしています。 にゃわーく エイプリルフールのお楽しみとして、『にゃわーく』モードを実装しました。 アイコンやルームリアクションが猫仕様になったり、入退室音が猫の鳴き声になったりします。 ルーム名の折り返しの改善 ルーム名が自然な位置で折り返されるように改善しました。 バーチャル背景のアップロード ユーザーがバーチャル背景をアップロードできるようにしました。 それまでバーチャル背景機能はありましたが、ユーザー自身がバーチャル背景をアップロードできないためベータ機能という位置づけでした。 バーチャル背景のアップロード機能や、自身の映像を反転させるか選択できる機能を追加し、ベータから正式な機能にしました。 オンボーディング NeWorkを初めて使うユーザーに対してオンボーディング機能を追加しました。 これまでは、NeWorkを初めて使うユーザーには使い方を紹介する動画をポップアップで表示していました。しかしクリック率(再生率)が著しく低く、NeWorkの基本的な使い方を理解する前に離脱しやすい状況だったため、チュートリアル形式でオンボーディングできる機能を実装しました。 タイルレイアウト選択機能 タイルレイアウト選択機能を正式リリースしました。 開発チーム改善活動 で「タイル表示スタイル選択機能」としてベータリリースされていた機能を、フィードバックを元に改善し、正式リリースしました。 デバイスの切り替えトースト 音声入出力デバイス・映像入力デバイスが切り替わったときにそれを知らせるトーストを実装しました。 ユーザーの意図に反して使用中のデバイスが認識できなくなり別のデバイスにフォールバックした場合に、気付けるようにしています。 フォールバック入室の通知 音声入力デバイスがない状態で室内に入室しようとすると自動的に聞き耳入室をするが、その際にその旨をトーストで通知するようにしました。 これにより、ユーザーにマイクを繋ぐなどの具体的な動作を動機づけられるようになりました。 プロフィール画像の拡大 プロフィール画像を拡大表示できるようにしました。 一般的には、画面にユーザーアイコンがある場合、クリックなどで拡大して表示できると期待されます。NeWorkではできなかったので実装しました。 カメラの映像と画面共有の同時配信 カメラの映像と画面共有を同時に配信できるようにしました。 NeWorkの特徴として、複数人が画面を共有できる点が挙げられます。一方で、これまでは画面共有とカメラ映像を同時に配信できないという制限がありました。たとえば、チームメンバーが全員カメラをオンにして会議をしていても、画面共有をしている人の表情だけは確認できない状態でした。これでは不便なので、全員がカメラ映像と画面共有を同時に使えるようにアップデートしています。 通話中に画面をOFFにしない パソコンを一定期間触らないと自動的に画面がOFFになる設定をしていても、通話中は画面OFFにならないよう変更しました。 もともとブラウザは映像が流れている場合、画面をOFFにしない仕組みになっています。しかし、「誰も映像を配信していないルーム」で通話を続ける場合は、画面が消えてしまうことがありました。今回の対応により、映像がない状態でも通話中は画面が消えないようになり、より快適に会話を続けられるようになりました。 通知音量調整 通知音量を調整できるようにしました。 1on1やルームへの呼び出しの呼び出し音が聞こえなかったというフィードバックや、逆に入退室音がうるさいというフィードバックなど、通知音量に対するフィードバックは千差万別でした。 そこで、好みに合わせて調整できるようにスライダーで音量を調整できるようにしました。なお、人間の聴覚特性に合わせて低い音量レベルでより細かい調整ができるようにスライダーを実装しています。 ワードバブル(仮) ルーム内の会話から話題を抽出して、ルームバブル上に表示する機能(ワードバブル(仮))を実装しました。 ルームの外から、ルームの中で行われている会話の内容や温度感を把握できるようにすることで、ルームに参加しやすくする機能です。 開発中にサービス終了が決まり、社内向けのリリースに留めました。 離席 一時的に席を外していることを表せる、離席機能を機能を実装しました。 リモートワークにおいて、宅配や着信などで突発的に席を外さざるを得ないことは少なくありません。そして、自分が話者ではないときにそれを伝えることは難しいです。そこでワンボタンで離席状態を表現できる機能を実装しました。 通話中の UI からルーム詳細を開く動線の追加 通話中にそのルームの詳細パネルを簡単に開ける動線を追加しました。 これまで通話中にルームの詳細を開くときは、ルームバブルの「…」から開く必要がありました。特に映像をタイル表示しているときは、タイル表示を非表示にしてから「…」ボタンを押す必要があり手間でした。 そこで、通話中でも常に表示されている場所に、ルーム詳細を開く動線を追加しました。 執筆時点では、開発体制は縮小しています。 ↩
アバター
こんにちは。イノベーションセンター Generative AI チームの安川です。今回はrokadocのパブリックベータ版( https://rokadoc.ntt.com/ )が公開されたため、その紹介と解説をします。 本記事では「ドキュメント変換技術」であるrokadocの概要を説明した上で、実際の使い方や結果を紹介します。 使い方の部分では、WebUIを用いて簡便にドキュメント解析を行う方法や、解析結果が実際にRAG(Retrieval-Augmented generation、検索拡張生成)で有用なのかを示します。また、手元のRAGへ組み込むためにAPI経由で処理を実行する方法についても紹介します。 rokadoc概要 多様なファイルへの対応 高い検索精度 オンプレミス対応 利用方法 WebUIからの利用方法 ドキュメントの解析 RAGの実行 APIを用いた利用方法 前提 解析の実行 おわりに rokadoc概要 「AIの力で埋もれた情報を価値あるものに」 というコンセプトの元、rokadocは開発されています。 そして、生成AIで取り扱うには難解なドキュメント類を効果的に利活用可能なデータへ変換するための技術として、2025/2/19 にパブリックベータ版が公開されました。 昨今、LLM(Large Language Model)をはじめとした生成AIは爆発的なブームを迎えています。しかし、実際にLLMを使ったものの、必要な情報を精度高く得ることができず悩んだ方や、RAGをいざ構築したは良いものの、ドキュメントからうまく情報を抽出できずにもどかしく感じた方はいると思います。 rokadocは、このような問題を解消するために作られ、以下の特徴を持っています。 多様なファイルへの対応 ファイル形式は、PDFに加え、Microsoft Word、Excel、PowerPointを利用可能です。 高い検索精度 変換後のテキストを用いて行った検索では他社製品に比べて高い精度を示しました。 rokadocは複数の機械学習モデルと、それらの機械学習モデルに合わせたアルゴリズムを用いており、多数の要素を持った複雑なドキュメントが対象であっても精度高く変換します。 また縦書きなどの日本語特有の要素を含むドキュメントであっても対応が可能です。 オンプレミス対応 私たちは、オンプレミスで動く精度の高いモデルの開発も行なっています。 公開したパブリックベータ版とは異なる構成で、オンプレミスで動く形での提供も今後行っていく予定です。 こちらを利用すれば、インターネットに接続することなく、自社のネットワーク環境に閉じた状態で rokadoc を利用できます。 利用方法 ここからは、具体的な使い方について紹介していきます。 rokadocはWebUIとAPIの2つの利用手段があります。 WebUIからの利用方法 ここではWebUIから利用する手順を示します。 今回はつい先日行われた言語処理学会第31回年次大会(NLP2025)へ、当チームのメンバーが投稿した「chakoshi: カテゴリのカスタマイズが可能な日本語に強い LLM 向けガードレール」 *1 という論文を対象にrokadocを使ってみます。 ドキュメントの解析 以下が、WebUIからログインした場合のホーム画面です。このページの左側から、解析したいファイルをアップロードします。 アップロードを行うと、右側に解析状況が表示されます。進捗が”Succeeded”へ切り替わった後にファイル名をクリックすると解析結果が表示されます。 対象とした論文 を見るとわかりますが、このPDFは二段組かつフッターも存在し、表や図が文章中に登場するという複雑な構造のものになっています。今回は、 文章の読み取り 表の読み取り 図の読み取り の三点に焦点を当て、解析結果の一部を例示します。 1. 文章の読み取り このドキュメントは、以下のようにベースが二段組となっており、フッターが存在する複雑な構成となっています。 しかしpage 3の解析結果を見ると、 (前略) 4.1 有害性判定に関する評価実験 本実験の目的は、日本語の有害表現に対する, chakoshi の判定精度の評価である. 既存の代表的なモデレーション API やガードレールを比較対象とし,3.2 節で構築したデータセットを用いてファインチューニングした chakoshi モデルの性能を評価する. 4.1.1 実験手続き (中略) 4.2 カテゴリ追従性能の評価実験 本実験の目的は, chakoshi のカテゴリカスタマイズ機能の評価である. 医療相談や金融相談など, chakoshi が元々対応していない新規カテゴリを自然言語で追加し,それらへの追従性能を検証する. This work is licensed by the author(s) under CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). –– 2805 –– と、テキストを正確に読み取るだけではなく二段組であることを理解し、「4.1 有害性判定に関する評価実験」の途中で段組が変わっている部分に対しても問題なく繋げることができています。また末尾にはフッターとして表示されているものも正確に出力できています。 2. 表の読み取り page 3には以下の表が掲載されています。 この表は結合したセルが存在した上で罫線が引かれていない部分が存在しているなど、複雑な構造を持つ表となっていますが、解析結果を見ると、 表1 ベースラインと chakoshi モデルの比較結果 < table border = "1" > < caption > 表1 ベースラインと chakoshi モデルの比較結果 </ caption > < tr > < th rowspan = "2" ></ th > < th colspan = "2" > XSTest </ th > < th colspan = "2" > RTP-LX </ th > </ tr > < tr > < th > F1 </ th > < th > F2 </ th > < th > F1 </ th > < th > F2 </ th > </ tr > (中略) < tr > < td > gemma-2-9b-it-chakoshi </ td > < td > 0.835 </ td > < td > 0.884 </ td > < td > 0.966 </ td > < td > 0.964 </ td > </ tr > </ table > と、セル内部のテキストを正確に取得した上で、列及び行方向に結合したセルも正確に構造を取得できています。 3. 図の読み取り page 2には以下の図が掲載されています。 アイコンを用いて処理に登場する要素を、矢印で処理の流れを表現しています。 またアイコンや矢印に対応する文字も記載されています。 このように多数の要素が含まれますが、解析結果を見ると、 **画像の説明:** 1. イラストは「chakoshiの概念図」と題されており、ユーザーが入力するテキストを基に、システムがその安全性を評価するプロセスを示しています。図の中央には「chakoshi」という名称が記載されており、矢印を使ってプロセスの流れが説明されています。 2. 左側には「ユーザー」のアイコンが描かれており、ユーザーが入力するテキストが「入力が安全だと考えられるケース」「入力に害があるケース」「出力に害があるケース」の3つのケースに分類されることが示されています。 3. 右側には「LLM(Large Language Model)」のアイコンが描かれており、システムがテキストを評価する際にLLMを活用することが示されています。 4. 矢印の先には「判定の例示イメージ」として、以下の具体的な数値が記載されています: - 「判定結果:safe」 - 「unsafeスコア:0.13」 - 「判定結果:unsafe」 - 「unsafeスコア:0.89」 - 「カテゴリ:暴言」 5. 図の下部には「※1 入出力はどちらもテキスト形式」との注釈が記載されており、入力または出力がテキスト形式であることを補足しています。 このイラストは、chakoshiがどのようにテキストの安全性を判定するかを視覚的に説明しており、プロセスの流れや具体的な判定例が詳細に示されています。 と、グラフについての情報を正確に出力するだけではなく、各図がキャプションに対してどのように対応しているかも含めて解析ができています。 以上のように、複雑な構成や多種多様なコンテンツを含むものでも、正確に解析できました。 RAGの実行 以下のドキュメント解析結果の画面上部にある「チャット」ボタンからチャット画面へ遷移できます。ここでは論文の解析結果に基づいた回答が可能か試してみます。 例えば「chakoshiは画像も対応できますか?」と入力すると、以下の内容が返ってきます。 いいえ、chakoshiは画像や音声といったマルチモーダルな入出力には対応していません。関連情報によると、chakoshiはテキストベースの入出力に特化しており、シンプルかつ確実な有害性の検出を目指しています。この設計方針により、ユーザー固有の環境でのテキストチャットでの利用を想定しており、画像や音声などの非テキスト形式のデータは対象外となっています。したがって、chakoshiはテキスト形式のデータに限定して動作するガードレールモデルです。 また「chakoshiの性能について端的に教えてください」と聞くと、以下のように解説してくれます。 chakoshiは、日本語特有のニュアンスや表現に対応した軽量なLLM向けガードレールモデルであり、以下の特徴を持っています: 1. 高い判定精度 - 有害性判定において、既存のモデルを上回る性能を示し、XSTestでF1スコア0.835、RTP-LXでF1スコア0.966を達成しました。 2. カテゴリカスタマイズ機能 - 防ぎたい話題を自然言語で指定できる柔軟性を持ち、新規カテゴリ(例: 医療相談、金融相談)でも高い検知率を達成しました(医療相談87.1%、金融相談93.1%)。 3. 日本語特化 - 日本語特有の遠回しな嫌味やハラスメント表現にも対応可能で、文化的背景を考慮した設計がされています。 全体として、chakoshiは日本語に強く、ユーザー固有の要件に応じた安全性確保が可能なモデルです。 このように論文の内容を踏まえた正確な回答ができています。 APIを用いた利用方法 自身の環境で構築したRAGにrokadocの解析結果を用いたい場合、WebUIから1つずつファイルをアップロードしていくのではなく、CLIから操作したい場合もあると思います。そのような場面を想定して、APIを用いてドキュメント解析を行う例を提示します。 前提 まずAPIキーを確認しておく必要があります。APIキーは以下のホーム画面の上部にある「ユーザ設定」の「APIキーの確認/切替」から確認ができます。 また利用方法の詳細はAPIリファレンスから確認が可能です。同様にホーム画面の上部にある「ユーザ設定」をクリックし、「APIキー発行」をクリックすると以下の画面に遷移します。 その後上部の「APIリファレンス」をクリックすると、各APIの使い方や挙動を確認できます。 解析の実行 1. 変換処理 以下のコマンドを実行することで、対象のドキュメントの解析ができます。 api-key には先程確認した APIキー を設定します。 upload_file には対象のドキュメントを指定します。今回は対象の論文ファイルである @NLP2025_P7-7.pdf を指定しています。 curl -X POST "https://beta-api.rokadoc.ntt.com/v1/api/conversions" \ -H "Cache-Control: no-cache" \ -H "api-key: {YOUR_API_KEY}" \ -F "upload_file=@NLP2025_P7-7.pdf" \ -F "from_page=1" \ -F "to_page=6" ここでfrom_page及びto_pageはそれぞれ、対象のドキュメントの中で解析するページの範囲を選択するために使用します。 こちらを実行すると、 { " code ": 202 ," status ":" Pending "," conversion_id ":" {conversion_id} " } のようなメッセージが返却されます。このconversion_idを用いてファイルの解析結果を確認できます。 2. ジョブ一覧の確認 以下のコマンドを実行することで、これまで行ったジョブの状況が確認できます。 curl -X GET "https://beta-api.rokadoc.ntt.com/v1/user/conversions" \ -H "Cache-Control: no-cache" \ -H "api-key: {YOUR_API_KEY}" こちらを実行すると、 { " code ": 200 ," total_count ": 1 ," last_page_number ": 1 ," data ": [{ " status ":" Running "," conversion_id ":" {conversion_id} "," document_name ":" NLP2025_P7-7.pdf "," created_date ":" 202503021710 "," updated_date ":" 202503021711 " }]} のようなメッセージが返却されます。ここでstatusがSucceededになっていれば解析処理が完了しています。上記のようにRunningになっている場合は実行中ですのでお待ちください。 3. ジョブ結果の表示 以下のコマンドを実行することで、対象のジョブの実行結果が確認できます。 curl -X GET "https://beta-api.rokadoc.ntt.com/v1/user/conversions/{conversion_id}/document" \ -H "Cache-Control: no-cache" \ -H "api-key: {YOUR_API_KEY}" 長くなるため実行結果は省略しますが、これで各ドキュメントに対するAPIでの処理が実行できました。この結果をRAGの検索データベースに格納することで、お手元の環境にあるRAGでrokadocの解析結果を用いることができます。 おわりに この記事では、2025/2/19にパブリックベータ版を公開した rokadoc について紹介しました。 利用回数に上限はありますが無料で利用可能ですので、気になった方は是非ともお試しください。 利用上限なしで使いたい方向けに個別相談も可能です。もっと使いたい!と思っていただけた方は、 rokadocお問い合わせフォーム からお問い合わせください。 それでは皆さん、お読みいただきありがとうございました。 *1 : 新井一博, et al, "chakoshi: カテゴリのカスタマイズが可能な日本語に強い LLM 向けガードレール", 言語処理学会 第31回年次大会, 2025
アバター
こんにちは、イノベーションセンターの加藤です。この記事では、大規模言語モデル(LLM)にJSONやソースコードを正しく出力させるための生成手法であるStructured Generationについて紹介します。 Structured Generationとは パーサーを用いた制約手法 正則言語とは 正則言語のStructured Generation 文脈自由言語とは 字句解析について 正則言語+文脈自由言語のStructured Generation まとめ Structured Generationとは 大規模言語モデル(LLM)はよくチャットボットとしての活用が目立ちますが、LLMの入出力を外部のプログラムに繋ぎ込むことでより高度な自然言語処理システムを作ることができます。 例えばOpenAIのCode Interpreter 1 はLLMをPythonの実行環境と接続することで、ユーザーに要求された複雑な情報処理をまずPythonコードに書き起こし、その実行結果を使って応答するシステムです。 また、Meta社によるアシスタントロボットの取り組み 2 ではユーザーの音声入力をテキストに書き起こし、LLMがその文章からプログラムが解釈可能な命令列に変換することで自然言語とプログラムの橋渡しを行なっています。 このように、特定のスキーマに沿ったJSONや特定のプログラミング言語でのソースコードといった構造化データをLLMに出力させるStructured Generationが最近注目されています。 しかしながらこのようなユースケースではLLMの出力形式がブレるとシステムが動作しなくなるため、ファインチューニングやプロンプトの工夫だけでは不十分です。 下図のようにJSONの出力を例にとると、プロンプトで「JSONのみを出力してください」と指定していても、関係のない文章やコードスニペットの記法を混入させてしまうことが多々あります。 そこで、プロンプトのような確実性のないものに頼るのではなく、出力として選択されるトークンの候補をコントロールすることで、目的のフォーマットに必ず従わせる制約付き文章生成の手法が広く研究されています。 パーサーを用いた制約手法 LLMなどの文章生成モデルは、これまでの単語列から次に現れそうな単語を自信度の形で予測し、何らかの戦略のもとで出力する単語を決定します。一般的に使われている戦略は貪欲法で、毎回最も自信度の高い単語を出力することを繰り返すことで文章を生成していき、文章の終了を表すトークン(よく EOS として表されます)を出力した時点で停止します。 Structured Generationでは以下の画像のように、選択前に好ましくない単語の自信度を全て0にすることで文法的に正しくない文章の出力を防いでいます。 そしてどの単語が文法的に好ましくないかを判定するために、その文法に対応したパーサーが使われます。 パーサーは基本的に入力文章を頭から読み取っていき、文法的に正しくない文字列が現れたところでエラーが発生するようになっています。Structured Generationではこの性質を利用して、LLMが予測する次の単語をパーサーに入れてみて、エラーが起こるようならその単語を除外することで文法的に正しい出力を実現しています。 しかし、この方法では1単語生成するたびに数万近くあるLLMの語彙を走査してパーサーに判定させる必要があるため、計算時間が非常にかかってしまいます。 そこで、パーサーの動作を利用して判定を効率化するテクニックがいくつか研究されています。 本記事ではStructured Generationでよくサポートされる正則言語と文脈自由言語の2種類のパーサーに対して効率的な制約付き生成手法を紹介します。 正則言語とは 正則言語は後方参照を用いない正規表現で表現可能な言語のことで、例えば「整数」は /0|(-?[1-9][0-9]*)/ として表現できます。 正則言語のパーサーは決定性有限オートマトン(DFA)で実装できることが知られています。DFAとは入力文章を頭から読み取っていき、入力文字と現在の状態から定まる次の状態へ遷移することを繰り返す機械のことで、前述の「整数」を判定するDFAは以下のように構成できます。 この丸が状態で矢印が読み取った文字に対応する遷移先を表しており、文字を全て入力して最終的に二重丸の状態(受理状態)に移動していればOKという判定がなされます。 例えば「整数」を判定するDFAに「-16」という文章を入力すると次のように状態が遷移し、「-16は整数である」と判定されます。 一方で、例えば「0-1-1」という文章は途中で遷移に失敗します。また、「-」という文章は最終的に受理状態に到達しません。そのためこれらは整数とは判定されません。 正則言語のStructured Generation このようなパーサーをStructured Generationに活用する場合は、「文法的に正しくない文字列が現れる」という現象を「この先受理状態へ到達し得ない状態に遷移してしまう」と読み替えることができます。 例えばLLMに整数を出力させようとしており、現状の中間出力が何もない場合、「090」や「apple」という単語は出力できませんが、「0」や「-」という単語は受理状態もしくはこの先受理状態へ到達可能な状態に遷移可能なので出力しても良いと判定されます。 そうした状態と単語の組み合わせの数は有限であることを利用するとうまく判定を効率化できます。 各状態 q から各語彙 t を入力した時に「この先受理状態に到達可能な状態」に遷移するかを前計算しておき、 dict[q][t] として保存しておきます。この結果をマスク処理で利用することにより、状態数 Q とLLMの語彙数 T に対してサイズ Q*T のメモリ消費のもと、長さ T のマスク処理だけで各単語の出力可否を判定できます 3 。 これにより、LLMの選択肢に挙がった単語を毎回DFAに入力していたことで発生する計算時間を減らすことができます。 文脈自由言語とは 文脈自由言語は正則言語よりも表現力の高い言語で、JSONのようにネスト構造を持つ言語もこれに属しています。 文脈自由言語を表現する文法の定義は少し複雑で、以下の4つをまとめたものになっています。 終端記号の集合 (文を構成する最小単位) 非終端記号の集合 開始記号と呼ばれる特別な非終端記号 1つの非終端記号から0個以上の記号列への変換規則 そしてこの文法が表現する言語は開始記号から変換を繰り返して生成可能な終端記号列の集合となります。例として次のような文法を考えてみます。 終端記号 a , b 非終端記号 S , E 開始記号 S 変換規則 S→aE , E→Sb , E→b S から適当に変換規則を選んでいくと、例えば S→aE→aSb→aaEb→aabb と繰り返して aabb が生成されます。 そのため aabb はこの文法で表現された言語に含まれていることが言えます。 実はこの文法は「任意の正整数Nに対して、 a をN個並べ、その後 b をN個並べた言語」を表しています。 このように正規表現では作れないような言語も表現できることが文脈自由文法の特長です。 よくプログラミング言語などの定義で現れるBNF(バッカスナウア記法)やEBNF(拡張BNF)はこの文脈自由文法を簡易的に記述するための記法です。 例えば先ほどの文脈自由文法に対応するBNFは次のようになります。 <S> ::= "a" <E> <E> ::= <S> "b" | "b" "" で囲われている単語は終端記号、 <> で囲われている単語は非終端記号と見なすと、これが文脈自由文法のいち記法に過ぎないことがわかりやすいかと思います。 こういった文脈自由言語を解析するときは、基本的には与えられた文章を生成するための変換の過程を特定できれば解析できたことになります。 この過程は構文木と呼ばれるもので表現でき、例えば先ほどの文法に対して aabb という文章は S→aE→aSb→aaEb→aabb と変換されたわけですが、これを以下のような木で表現できます。 文脈自由言語のパーサーはこの構文木を作成するのが最終目的ですが、解析手法にはさまざまなものがあります。 一般的にパーサーで広く使われているのはLALR(1)法と呼ばれているもので、文頭から1単語ずつ読み出していき、構文木を右の葉側から特定していく手法です。 例えば前述の文法に対して「a a b」までを入力すると次のように作りかけの構文木が出来上がります。 字句解析について 一般的なプログラミング言語のパースにおいては、文脈自由文法での解析を行う際の複雑さを減らすために、文字レベルでは無くある程度まとまった文字列にまとめてから分析を行います。 例えばJSONでは以下のように文字列がまとめられて終端記号に変換されます。 文字列リテラル ("John" など) → STRING 数値リテラル (-3, 1.2 など) → NUMBER 配列用の開きカッコ [ や閉じカッコ ] → LBRACK, RBRACK 配列内のカンマ → COMMA 辞書用の開きカッコ { や閉じカッコ } → LBRACE, RBRACE 辞書内のコロン → COLON 真偽値やnull → TRUE, FALSE, NULL このルールにもとづくと、例えば {"temperature": 25.7} というJSON文字列は LBRACE STRING COLON NUMBER RBRACE という終端記号列に変換されます。 このように文字列から終端記号の列への変換を字句解析と呼び、正則言語などの比較的シンプルなルールで解析が行われています。 正則言語+文脈自由言語のStructured Generation 前節で説明したように、一般的なプログラミング言語にLLM出力を制約したい場合はDFAによる字句解析とLALR(1)による文法解析を行うパーサーを利用します。 このパーサーには次に現れるべき終端記号の候補がわかるという特徴があり、これをLLMの出力制約に用いることができます。 具体的には次のようにLLMの語彙に制約を与えられます。 LLMの中間出力をパーサーに与えて途中まで字句解析させる 例: {“key”: [ → LBRACE({) STRING(“key”) COLON(:) LBRACK([) 確定した終端記号をパーサーに与えて途中まで文法解析させる 次に続くことができる終端記号を列挙する 例: {"key": [ に続く終端記号は文字列 STRING , 数値 NUMBER , 辞書の開きカッコ LBRACE , 配列の開きカッコ LBRACK , 配列の閉じカッコ RBRACK 各終端記号を判定するDFAから、前計算しておいた語彙マスクを取り出す 語彙マスクの和集合を取り、次に続くことができるLLMの単語を列挙する これにより、文脈自由文法の終端記号の種類数に比例した計算量でStructured Generationを行うことができます。この終端記号の種類数はLLMの語彙よりもずっと少なく、例えばPythonでも94種に抑えられることが知られています 4 。 まとめ 今回はLLMにJSONの出力やプログラムのソースコードの出力などを安定させたい場合に有用なStructured Generationについて紹介し、 語彙に制約を与えるための具体的な手法と効率化のアルゴリズムについて解説しました。 https://platform.openai.com/docs/assistants/tools/code-interpreter ↩ https://languageguidedskillcoordination.github.io ↩ Willard and R. Louf, "Efficient Guided Generation for Large Language Models", https://arxiv.org/abs/2307.09702 ↩ Ugare et al., "SynCode: LLM Generation with Grammar Augmentation", https://arxiv.org/abs/2403.01632 ↩
アバター
この記事では、ドコモグループで実施したイベント “dcc Engineer Day 25” において、Telegramを使ったワークショップを開催した様子を紹介します。 はじめに 注意 dcc Engineer Dayについて ワークショップの様子 Telegramとは何か Telegramの活用・悪用事例 アカウント設定とプライバシー メッセージング(チャット) APIとBot 参加者の声 ワークショップを開催してみて おわりに はじめに みなさんこんにちは、イノベーションセンターの遠藤です。Network Analytics for Security (以下、NA4Sec) プロジェクトのメンバーとして活動しています。 NA4Secプロジェクトは「NTTはインターネットを安心、安全にする社会的責務がある」を理念として、攻撃インフラの解明、撲滅を目指すプロジェクトです。 NTT Comイノベーションセンターを中心としてNTTセキュリティ・ジャパンやエヌ・エフ・ラボラトリーズからもメンバーが参画し、日夜攻撃インフラを追跡しています。 注意 この記事はTelegramの仕様やワークショップの内容を紹介する目的で書かれています。Telegram自体は適切に利用する分には問題ありませんが、残念ながらTelegramコミュニティの中には特殊詐欺や犯罪行為に利用されているものが存在します。興味本位でそういったコミュニティを覗いたり、素性のわからない人とのやり取りに利用したりすると意図せず犯罪に巻き込まれる危険性があるため、注意してください。 dcc Engineer Dayについて dcc Engineer Dayは、NTTドコモ・NTTコミュニケーションズ・NTTコムウェア3社の社員が技術を軸に交流を深める場として開催しているイベントです。2022年から年に1度開催され、今年は4回目となります。イベントは現地+オンラインのハイブリッドで開催され、今年は現地とオンラインを合わせて459人が参加しました。 我々NA4Secプロジェクトは、今年から新たに始まったワークショップ枠の講師として、本イベントに参加しました。 ワークショップの様子 ワークショップは「Telegramの危険性を正しく理解し、安全に使うための実践ワークショップ」と題して、ハンズオンを含む以下の構成で行いました。 Telegramとは何か 日本、海外での活用(悪用)事例 インストールとアカウント設定 メッセージング(チャット)の利用 APIの紹介 お昼時の開催だったので、参加者のみなさんにはピザをつまんでもらいながら、ハンズオンを進めました。 Telegramとは何か 初めに、Telegramについて座学方式で学びました。 Telegramは2013年にリリースされたマルチプラットフォーム対応のメッセージングアプリケーションです。その高速性やシンプルさ、透明性(オープンソース)から海外を中心に人気で、現在のアクティブユーザ数は全世界で9億人を超えています。 *1 また明確なプライバシーポリシーやセキュリティ、表現の自由に重きを置く考え方 *2 から、インターネット検閲の厳しい国々において、検閲されていない情報の発信・取得に利用されています。 Telegramの活用・悪用事例 次に、日本や海外におけるTelegramの活用・悪用事例を紹介しました。 日本におけるTelegramのイメージは、下記のような特殊詐欺や闇バイト・犯罪などの連絡手段に使われる事例から、「危ない」や「怖い」といった声が多いのではないでしょうか。 逮捕されるまで辞められない?闇バイトの勧誘方法の実態 (東京都 特殊詐欺加害防止 特設サイト) 正規の求⼈サイトに掲載されている有害求人情報に注意!! (警察庁) 一方で海外では先述の通り、情報統制下においても自由度の高い情報を発信できるツールとして利用されています。例えばNew York Times誌はTelegramを通じて、紛争地域に向けて ロシア・ウクライナ戦争に関する国際ニュースを発信するチャンネル を運営しています。またウクライナ政府が運営するWebメディア UkraineNOW は、Webサイトのほか、Telegramのオフィシャルチャンネル @UkraineNow を通じて、戦況をリアルタイムに世界へ発信しています。 これらのようにTelegramの特徴や優位性が活用されている事例と、残念ながら悪用されてしまった事例を学んだうえで、Telegramを安全に利用するためにはどのようなポイントに気をつければ良いかを、次に紹介するハンズオンで学んでいきます。 アカウント設定とプライバシー ここからは参加者の皆さんに、実際に手を動かしてもらいながらワークショップを進めていきました。 まずは実際にTelegram公式アプリケーションをインストールしてもらいます。続いてアカウントを作成して、各自でプロフィールを作成しました。 Telegramはプロフィール設定とは別に、自分の情報を相手がどの範囲まで見ることができるかを設定可能です。ワークショップでは実際に参加者同士で設定の差による見え方の違いを見せ合いながら、設定によっては自分の名前や写真、電話番号を第三者が参照可能な状態になることを体験しました。 メッセージング(チャット) ここでは作成したアカウントを利用し、チャットの閲覧・発言を体験しました。チャットは大きく分けて以下の4種類が存在します。 チャンネル:管理者のみが発言可能な複数人チャット グループチャット:管理者・参加者とも発言可能な複数人チャット 個人チャット:1対1のチャット シークレットチャット:E2EE(End-to-End Encryption)の1対1チャット なかでもシークレットチャットは秘匿性が高く、通信内容はエンドツーエンドで暗号化されています。エンドツーエンド暗号化が有効なチャットにおいては、メッセージなどの通信データがすべて暗号化された状態で扱われます。送信者と受信者のみがデータを復号して閲覧できるため、セキュリティの高い通信方式です。 このほか、シークレットチャットでは独特な機能も提供されています。ワークショップでは参加者間でシークレットチャットを開始し、Self-destruct Timer(自動消去機能)を数秒程度に設定することで、会話した内容が数秒で自動消去される様子を体験してもらいました。また端末でスクリーンショットを取得すると自動でプロテクションが動作し、スクリーンショットが無効化されるうえで、取得した事実が会話相手に通知される様子を確認しました。 APIとBot 最後にAPIの紹介と、チャットBotに対して会話をする体験をしました。Telegramはいくつかの開発者向けAPIが提供されており、大きく以下の3種類が存在します。 Bot API Telegram API & TDLib Gateway API 今回の体験では、講師側が上記のBot APIを利用して準備したチャットBotと会話をしてもらいました。 参加者はチャットBotに対して、準備されたいくつかのコマンドを使って自由に会話をします。それらのコマンドのうちいくつかには、端末の電話番号や位置情報など個人情報を送信させるスクリプトを講師が仕込んでいました。参加者には、取得可能な情報範囲の理解と、意図しない情報開示のリスクを体感してもらいました。 Telegram API、及びTelegramクライアントはオープンソースのため柔軟性や拡張性が非常に高い反面、利用する際にはこれらの動作仕様について十分に注意することが必要です。 参加者の声 ワークショップ後に実施したアンケートを見ると、参加者全員がTelegramを初めて利用したという結果でしたが、利用後のTelegramの印象を聞くと「怖くない」「どちらかというと怖くない」という回答を多くの参加者からいただきました。また「実際に触りながら学ぶことができ楽しかった」、「面白かった!」という声や、ワークショップを他の方に勧めたいかという問いに対しても全員からポジティブなリアクションをいただき非常に嬉しく思いました。 一方で「せっかくなので自己紹介を交えて交流を深めたかった」、「ボリュームが少なかった」、「サービスの背景など座学的な部分を深く知りたかった」というフィードバックもあり、今後を考えるうえで非常に参考になりました。 Telegramを闇雲に怖がるのではなく、実際に体験するなかで注意すべきポイントを知ってもらうことができ、ワークショップを開催した意味があったのではないかと思います。 ワークショップを開催してみて 私自身初めてのイベント参加、ワークショップ講師で至らぬ点が多くありましたが、イベントを主催して下さった皆さん、一緒に講師をした同プロジェクトの鮫嶋さんやプロジェクトメンバーに支えていただき、無事開催に至ることができました。ありがとうございます。 開催前は1時間半という時間枠のなかで終えることができるのかという不安であったり、アプリケーションのインストールやSMS利用に抵抗感があるのではないかという心配もありましたが、いざ始めてみると時間はやや余るくらいで、ハンズオンもスムーズに進めることができました。 再度開催する機会があった際は、アンケートで頂いた意見を盛り込みながら、より良いワークショップを目指していきたいと思っています。 ワークショップに参加して下さった皆さんにも、改めて感謝いたします。 おわりに Telegramは漠然としたイメージで「危ない」と言われることが多いですが、具体的にどのようなリスクがあるのか、どのような動作をするのかを体験を通じて学んでもらいました。 繰り返しとなりますが、特に日本においては詐欺や犯罪に利用されることが多く、Telegramへの誘導や利用の強要があった場合は利用せず下記の相談先への連絡を検討してください。 闇バイト 警察の呼びかけ強化以降 応募者など保護のケースも 匿名通報ダイヤル 読んで頂いた方にとって、本ブログの内容がTelegramについて「正しく知って正しく恐れる」ことに繋がれば幸いです。 *1 : Telegram FAQ *2 : Telegram Privacy
アバター
こんにちは、イノベーションセンターの鈴ヶ嶺です。普段は AI/ML システムに関する業務に従事しています。 本記事では、CUDA 12.8 から追加された Checkpoint API の概要について解説します。 まず、Checkpoint のユースケースやこれまでの NVIDIA CUDA における Checkpoint の試みなどの背景を説明し、新たに追加された CUDA Checkpointing について解説します。 さらに実際に実装し、torchvision や transformers などの CUDA アプリケーションに対して、Checkpoint の検証をしています。 背景 CUDA Checkpointing 実装と検証 cu_check tool 検証 Pytorch Counter torchvision transformers まとめ 背景 Checkpoint は計算途中の内部状態(メモリなど)をディスクなどに保存し、任意のタイミングで計算を再開できる技術です。 想定されるユースケースとして「障害発生時のバックアップ」、「ライブマイグレーション」、「長時間実行される計算の途中結果保存」、「タスクスケジューリングにおけるプリエンプション」、「フォレンジック分析における証拠保全」などが挙げられます。 特に GPU 分野では、昨今の大規模言語モデルに代表される長期間にわたる学習処理の一時保存や、リソース最適化の一環として、一部の GPU プロセスを別の GPU サーバへ移行するといった用途が考えられます。 しかし、これまでの NVIDIA CUDA における Checkpoint 手法としてさまざまな試みはありましたが、アプリケーションの実行環境自体に変更を加えて、CUDA Driver API の呼び出しを傍受しているため完全に透過的なものではありませんでした。 1 2 3 4 5 6 7 8 9 10 一方、2024 年 7 月 NVIDIA の Technical Blog において、 CUDA Driver API として version 555 から Checkpoint が実験的に実装されたことが発表されました。 オープンソースな Checkpoint utility の CRIU (Checkpoint/Restore in Userspace) との組み合わせについても説明されています。 https://developer.nvidia.com/blog/checkpointing-cuda-applications-with-criu/ 以下にそのツールである cuda-checkpoint が公開されています。リポジトリにはツールのバイナリしか置いておらず、バイナリの文字列を調べると cuGetExportTable 11 以外の API 呼び出しが存在しておらず、おそらくドキュメント化されていない関数を利用する形で実装されていました。 https://github.com/NVIDIA/cuda-checkpoint git clone https://github.com/NVIDIA/cuda-checkpoint.git cd cuda-checkpoint strings ./bin/x86_64_Linux/cuda-checkpoint | grep cu # libcuda.so.1 # cuDriverGetVersion # cuGetExportTable 他にも、 MemVerge 社は早期にこの API を利用した AI の学習 PoC を実施して GTC24 などで発表しています。 CUDA 12.x driver enhancements will enable the open-source CRIU project to checkpoint and restart a GPU-based compute node. We'll provide a technical overview and demonstrate this new capability. https://www.nvidia.com/en-us/on-demand/session/gtc24-p63184/ www.youtube.com そして、2025 年 3 月の現時点では Driver version 570 および CUDA 12.8 から CUDA Checkpointing として正式に API が公開されました。 先ほどの check-checkpoint のリポジトリにも一部その API を利用するコードが公開されていますが、 cuda-checkpoint と併用されており、新たに仕様公開されたものに置き換わっていないと思われます。 12 13 そのため、現在 CUDA 12.8 で新たに公開された API を利用したサンプルコードが見当たらない状況になっていると思われます。 次の章で公開されている Checkpoint API を調査し、どのように利用するのかを確認します。 CUDA Checkpointing CUDA Checkpointing の API 一覧が以下になります。 https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__CHECKPOINT.html CUresult cuCheckpointProcessGetState ( int pid, CUprocessState* state ) CUDA プロセスの現在の状態( CU_PROCESS_STATE_RUNNING , CU_PROCESS_STATE_LOCKED , CU_PROCESS_STATE_CHECKPOINTED , CU_PROCESS_STATE_FAILED )を取得します。 CUresult cuCheckpointProcessLock ( int pid, CUcheckpointLockArgs* args ) CUDA プロセスを lock して、以降の CUDA API 呼び出しをブロックします。 CUresult cuCheckpointProcessCheckpoint ( int pid, CUcheckpointCheckpointArgs* args ) GPU メモリの内容を host memory に保存し、CUDA プロセスを checkpoint します。 CUresult cuCheckpointProcessRestore ( int pid, CUcheckpointRestoreArgs* args ) CUDA プロセスをリストアします。状態は CU_PROCESS_STATE_CHECKPOINTED である必要があります。 CUresult cuCheckpointProcessUnlock ( int pid, CUcheckpointUnlockArgs* args ) CUDA プロセスの lock を解除して、CUDA API Call を再開できるようにします。 CUresult cuCheckpointProcessGetRestoreThreadId ( int pid, int* tid ) CUDA プロセスの Thread ID を取得する。 引用: https://arxiv.org/abs/2502.16631 14 上図を参考にすると、実行中のプロセスの Checkpoint は次のように実行します。 cuCheckpointProcessLock cuCheckpointProcessCheckpoint CRIU dump また、保存したものを Restore するには次のように実行します。 CRIU restore cuCheckpointProcessRestore cuCheckpointProcessUnlock 次の章で実際にこれらを動作するコマンドツールを実装して、Pytorch などのアプリケーションの Checkpoint が可能かを確認します。 実装と検証 cu_check tool 次のようにそれぞれの Checkpoint API をサブコマンドとして、特定のプロセス ID に実行するツールを実装します。 cu_check.c #include <cuda.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define CHECK_CU (func) \ do { \ CUresult res = (func); \ if (res != CUDA_SUCCESS) { \ const char *errName = NULL ; \ const char *errDesc = NULL ; \ cuGetErrorName (res, &errName); \ cuGetErrorString (res, &errDesc); \ fprintf ( stderr , " %s failed: %s %s\n " , #func, errName, errDesc); \ return - 1 ; \ } \ } while ( 0 ) const char * getCUprocessState (CUprocessState state) { switch (state) { case CU_PROCESS_STATE_RUNNING: return "CU_PROCESS_STATE_RUNNING" ; case CU_PROCESS_STATE_LOCKED: return "CU_PROCESS_STATE_LOCKED" ; case CU_PROCESS_STATE_CHECKPOINTED: return "CU_PROCESS_STATE_CHECKPOINTED" ; case CU_PROCESS_STATE_FAILED: return "CU_PROCESS_STATE_FAILED" ; default : return "OTHER_STATE" ; } } int main ( int argc, char **argv) { if (argc < 3 ) { fprintf ( stderr , "usage: %s [state|lock|checkpoint|restore|unlock] <pid> \n " , argv[ 0 ]); return - 1 ; } const char *subcommand = argv[ 1 ]; int pid = atoi (argv[ 2 ]); CHECK_CU ( cuInit ( 0 )); if ( strcmp (subcommand, "state" ) == 0 ) { CUprocessState state; CHECK_CU ( cuCheckpointProcessGetState (pid, &state)); printf ( "state: %s\n " , getCUprocessState (state)); } else if ( strcmp (subcommand, "thread" ) == 0 ) { int threadId = 0 ; CHECK_CU ( cuCheckpointProcessGetRestoreThreadId (pid, &threadId)); printf ( "thread id: %d\n " , threadId); } else if ( strcmp (subcommand, "lock" ) == 0 ) { CUcheckpointLockArgs args = { .timeoutMs = 600000 // 10min timeout }; CHECK_CU ( cuCheckpointProcessLock (pid, &args)); printf ( "locked successfully \n " ); } else if ( strcmp (subcommand, "checkpoint" ) == 0 ) { CHECK_CU ( cuCheckpointProcessCheckpoint (pid, NULL )); printf ( "checkpointed successfully \n " ); } else if ( strcmp (subcommand, "restore" ) == 0 ) { CHECK_CU ( cuCheckpointProcessRestore (pid, NULL )); printf ( "restored successfully \n " ); } else if ( strcmp (subcommand, "unlock" ) == 0 ) { CHECK_CU ( cuCheckpointProcessUnlock (pid, NULL )); printf ( "unlocked successfully \n " ); } else { printf ( "unknown subcommand: %s\n " , subcommand); return - 1 ; } return 0 ; } gcc -I /usr/local/cuda-12. 8 /include cu_check.c -o cu_check -lcuda # install sudo mv cu_check /usr/local/bin # Usage cu_check state < pid > cu_check lock < pid > cu_check checkpoint < pid > cu_check restore < pid > cu_check unlock < pid > 検証 事前に CRIU をインストールします。 curl -LO " http://github.com/checkpoint-restore/criu/archive/v4.0/criu-4.0.tar.gz " tar xvfz criu-4. 0 .tar.gz cd criu-4. 0 / make -j sudo make install Pytorch Counter CUDA Memory 上に保存し、 1 秒ごとに inc される Counter コードでまず検証します。 torch_counter.py import torch, time counter = torch.tensor( 0 , device= 'cuda' ) while True : print (counter) counter.add_( 1 ) time.sleep( 1 ) 次のように実行します。 1 秒ごとに Counter が継続して出力される様子が確認できると思います。 pip install torch python torch_counter.py & sleep 5 PID = $( pgrep -f ' python torch_counter.py ' ) # checkpoint rm -rf tcnt && mkdir -p tcnt cu_check lock $PID cu_check checkpoint $PID sudo criu dump -j -D tcnt -t $PID du -sh tcnt # 755M # restore sudo criu restore -j -D tcnt & while ! pgrep -f ' python torch_counter.py ' > /dev/null 2 >& 1 ; do sleep 1 ; done sudo cu_check restore $PID sudo cu_check unlock $PID sleep 5 kill -9 $PID torchvision 次に、torchvision の ResNet で検証します。 学習途中の状態が Checkpoint され、再開後に学習途中から実行される様子が確認できると思います。 git clone https://github.com/pytorch/examples.git cd examples/imagenet/ pip install -r requirements.txt python main.py -a resnet152 --dummy -j 0 & sleep 20 PID = $( pgrep -f ' python main.py -a resnet152 --dummy -j 0 ' ) # checkpoint rm -rf resnet && mkdir -p resnet cu_check lock $PID cu_check checkpoint $PID sudo criu dump -j -D resnet -t $PID du -sh resnet # 50G # restore sudo criu restore -j -D resnet & while ! pgrep -f ' python main.py -a resnet152 --dummy -j 0 ' > /dev/null 2 >& 1 ; do sleep 1 ; done sudo cu_check restore $PID sudo cu_check unlock $PID sleep 20 sudo kill -9 $PID transformers 最後に、transformers で検証します。 こちらも同様に継続して学習可能である様子を確認できました。 train_bert.py # ref: https://huggingface.co/docs/transformers/training from datasets import load_dataset from transformers import ( AutoTokenizer, AutoModelForSequenceClassification, TrainingArguments, Trainer, ) dataset = load_dataset( "yelp_review_full" )[ "train" ].select( range ( 10000 )) tokenizer = AutoTokenizer.from_pretrained( "google-bert/bert-base-cased" ) def tokenize_function (examples): return tokenizer(examples[ "text" ], padding= "max_length" , truncation= True ) small_train_dataset = dataset.map(tokenize_function, batched= True ) model = AutoModelForSequenceClassification.from_pretrained( "google-bert/bert-base-cased" , num_labels= 5 ) trainer = Trainer( model=model, args=TrainingArguments(num_train_epochs= 10000 ), train_dataset=small_train_dataset, ) trainer.train() 次のように実行します。 pip install transformers datasets accelerate python train_bert.py & sleep 60 PID = $( pgrep -f ' python train_bert.py ' ) # checkpoint rm -rf bert && mkdir -p bert cu_check lock $PID cu_check checkpoint $PID sudo criu dump -j -D bert -t $PID --tcp-established du -sh bert # 5.5G # restore sudo criu restore -j -D bert --tcp-established & while ! pgrep -f ' python train_bert.py ' > /dev/null 2 >& 1 ; do sleep 1 ; done sudo cu_check restore $PID sudo cu_check unlock $PID sleep 20 sudo kill -9 $PID まとめ 本記事では CUDA 12.8 で導入された Checkpoint API について解説しました。 また実際の実装を通して、昨今の大規模言語モデルのデファクトなライブラリである transformers などの CUDA アプリケーションに対して、Checkpoint が動作することを確認しました。 今後これらの技術が活用されることで、長期間にわたる学習処理の一時保存や、効率的なリソース最適化が行われることを期待しています。 Takizawa, Hiroyuki, et al. "CheCUDA: A checkpoint/restart tool for CUDA applications." 2009 International Conference on Parallel and Distributed Computing, Applications and Technologies. IEEE, 2009. ↩ Nukada, Akira, Hiroyuki Takizawa, and Satoshi Matsuoka. "NVCR: A transparent checkpoint-restart library for NVIDIA CUDA." 2011 IEEE International Symposium on Parallel and Distributed Processing Workshops and Phd Forum. IEEE, 2011. ↩ Jiang, Hai, et al. "A checkpoint/restart scheme for cuda programs with complex computation states." International Journal of Networked and Distributed Computing 1.4 (2013): 196-212. ↩ Garg, Rohan, et al. "CRUM: Checkpoint-restart support for CUDA's unified memory." 2018 IEEE International Conference on Cluster Computing (CLUSTER). IEEE, 2018. ↩ Jain, Twinkle, and Gene Cooperman. "CRAC: checkpoint-restart architecture for CUDA with streams and UVM." SC20: International Conference for High Performance Computing, Networking, Storage and Analysis. IEEE, 2020. ↩ Shukla, Dharma, et al. "Singularity: Planet-Scale, Preemptive and Elastic Scheduling of AI Workloads. arXiv. org (February 2022)." arXiv preprint arXiv:2202.07848. ↩ Eiling, Niklas, et al. "Cricket: A virtualization layer for distributed execution of CUDA applications with checkpoint/restart support." Concurrency and Computation: Practice and Experience 34.14 (2022): e6474. ↩ Nukada, Akira, Taichiro Suzuki, and Satoshi Matsuoka. "Efficient checkpoint/Restart of CUDA applications." Parallel Computing 116 (2023): 103018. ↩ Eiling, Niklas, Stefan Lankes, and Antonello Monti. "Checkpoint/Restart for CUDA Kernels." Proceedings of the SC'23 Workshops of the International Conference on High Performance Computing, Network, Storage, and Analysis. 2023. ↩ Yang, Yanning, et al. "On-demand and Parallel Checkpoint/Restore for GPU Applications." Proceedings of the 2024 ACM Symposium on Cloud Computing. 2024. ↩ https://forums.developer.nvidia.com/t/cugetexporttable-explanation/259109/2 ↩ https://github.com/NVIDIA/cuda-checkpoint/blob/6ec728aff032c18c9fb0794a272d94c6adcce508/src/r570-features.c ↩ https://github.com/checkpoint-restore/criu/blob/4b099510b35f98a1f1d6589b1660470402fc1fef/plugins/cuda/cuda_plugin.c ↩ Stoyanov, Radostin, et al. "CRIUgpu: Transparent Checkpointing of GPU-Accelerated Workloads." arXiv preprint arXiv:2502.16631 (2025). ↩
アバター
こんにちは、ソリューションサービス部の田中です。 約半年間、イノベーションセンターのNetwork Analytics for Security(以下、NA4Sec)プロジェクトに、社内ダブルワーク制度を通して、参画していました。 今日は、タイトルにもある通り、営業系キャリアを歩んできた私がアナリスト/エンジニア業務をして学べたことや感じたことについて紹介します。 営業系出身の方で、アナリスト業務に興味がある方向けに、今後のキャリア参考になればと思います。 RemcosというRATファミリーについて、机上調査をしましたので、そちらもご興味あれば! どんなキャリアを歩んできたか なぜ社内ダブルワークに申し込んだのか NA4Secプロジェクトの紹介 従事した業務「RATファミリーの机上実態調査」 Remcosの机上実態調査(特徴) Remcosの机上実態調査(事例/感染チェーン) Remcosの机上実態調査(推奨対策) 個人的にぶち当たった壁 ダブルワークを通して、学べたこと どんなキャリアを歩んできたか 現在入社6年目になります。 初期配属は、製造業向けのアカウント営業をしておりました。 4年目のタイミングで、一度部署異動してまして、今はセキュリティ領域のプリセールスエンジニアを担当しています。 普段はSASEやセキュリティオペレーション(SOC/SOAR)領域を提案することが多いです。 ということで、構築や運用経験は皆無であり、机上知識のみで少しセキュリティをかじっている系の人です。 LinuxやPython等のプログラミングも全く触ったことがありません。。。 なぜ社内ダブルワークに申し込んだのか 一言でいうと、「実務経験を積みたい!」です。 構築や運用の実務経験がなく、机上ベースだと提案時の発言の重みがなかったり、説得力を出し切れなかったり、課題を持っていました。 また、セキュリティアナリスト業務がどんなものかシンプルに興味もありました。 そんな時、未経験者でもOKというNA4Secプロジェクトの社内ダブルワークの募集要項を見て、ポチっと申し込みをしました。 なんとか無事、面談も実施して、採用していただけました。 NA4Secプロジェクトの紹介 「Network Analytics for Security」 通称NA4Sec(なよせ)と呼ばれています。 「NTTはインターネットを安心・安全にする社会的責務がある」という理念に基づき、攻撃インフラの解明、撲滅の実現を目指して活動しているイノベーションセンターのプロジェクトです。 従事した業務「RATファミリーの机上実態調査」 私がダブルワーク中に従事した「RATファミリーの机上実態調査」について、ご紹介します。 RATとは、Remote Access Trojanの略で、リモートアクセス型のトロイの木馬です。 攻撃者はRATを利用してコンピュータに不正に侵入し、遠隔操作を可能にしてユーザーの個人情報を盗み見たり、端末内のウイルス対策ソフトを停止させ別の攻撃を仕掛けるための踏み台に悪用します。 RATの中でも特に日本での攻撃被害が多いものをピックアップして、汎用RATの実態について調査をしました。 Remcosの机上実態調査(特徴) Remcos, Xworm, NjRATという3つのRATファミリーを対象に机上調査を始めましたが、今回はRemcosにフォーカスして簡単にご紹介します。 Remcosは、2016年7月に最初のバージョンがドイツのBreakingSecurity社から販売されたリモートアクセスツールです。 現在もリモートアクセスツールとして公式販売されていますが、攻撃者たちにRATとして悪用されている実態があります。 YouTubeでもRemcosの設定動画が公開されていたり、非常に身近なツールです。 Check Point Software Technologies社によると、2023年7月にマルウェアファミリーランキングで3位入っており、全世界で悪用が観測されています。 そんなRemcosの特徴としては、大きく3点あります。 特権の昇格 感染したシステムの管理者権限を取得し、ユーザーアカウント制御(UAC)等を無効にすることが可能になります。 攻撃者は管理者権限を利用し、悪意のある機能を実行しやすくなります。 防御回避 プロセスインジェクションを使用して正当なプロセスに自身を埋め込み、検出を困難にします。 Windows OSのパイプ方式を活用し、データ転送のための秘密チャネルを使い、EPPやEDRによる検出を回避することも可能です。 データ収集 キーストロークを記録し、スクリーンショット、オーディオ、クリップボード等の内容をキャプチャし、感染したシステムからパスワードの収集も可能にします。 Remcosの机上実態調査(事例/感染チェーン) 今回は、2023年にコロンビア企業を標的とする攻撃で、Remcosが利用されたケースを見ていきます(下記添付に本ケースの感染チェーンをまとめています)。 本ケースでは、 まずはフィッシング経由で、添付されている圧縮ファイルをダウンロードさせます。 格納されていたBATファイルからPowershellを実行し、2つの.NETモジュールをメモリに読み込ませます。 この2つの.NETモジュールで、Remcos本体をダウンロードする前に、ウイルス検知/開始の回避や証跡削除を試みます。 1つ目の.NETモジュールで、Kernel32.dllやntdll.dllのフックを外し、監視を回避。そしてamsi.dll AmsiScanBuffer関数にパッチを適用し、ウイルススキャンも回避します。さらに、ntdll.dll EtwEventWrite関数にパッチを適用し、イベントトレースログが残らないように、証跡を消します。 2つ目の.NETモジュールで、デバッガがあるのか確認。PowerShellを使用し、メインモジュールファイルを削除し、ステルス性を確保します。 上記のウイルス検知/監視を回避、証跡を可能な限り消したのち、Remcos本体をダウンロードします。 セキュリティ初心者からも私からすると、ただ単にRemcosがダウンロードされるのみかと思っていたのですが、本体ダウンロード前にこれだけのプロセスがあったのは非常に驚きでした。 Remcosの机上実態調査(推奨対策) Remcosのようなマルウェアを対策するには以下のような多層防御が推奨となります。 メールフィルタリングソリューションを利用して、ユーザーがメール受信する前にスパムメッセージを排除すること。 電子メールの怪しいハイパーリンクをクリックしたり、添付ファイルを開いたりしないように、ユーザートレーニングを実施すること。 OSやソフトウェアの脆弱性対応を迅速に実施すること。 ネットワークセキュリティ(SASE, NGFW等)を利用して、脅威に関連する悪意のあるアクティビティを検出すること。 EDRを利用して、エンドポイントで発生する異常な振る舞いを検出すること。 個人的にぶち当たった壁 プログラミングがわからない! マルウェアや攻撃者を調査する際も、ワークフローツール等を組み合わせて、自動化して情報収集するケースが多いです。その時には最低限のプログラミングスキルが必要でした。 また、すでにデプロイされている分析内容/マルウェア解析等の海外ドキュメントを正確に理解する上でもPythonやC++を理解できていないと非効率的でした。 一朝一夕で、身につくスキルでもないので、日々の勉強が重要だなと実感。一方で、即時的な打ち手としては、ChatGPTさんに聞くとプログラミングの意味をクイックに回答してくれるので非常に重宝していました。スゴイ便利。。。 ダブルワークを通して、学べたこと 学ぶことができた点としては、以下3点になります。 部署異動や転職という大きな決断を下す前に、業務が自分にマッチしているか事前検証できる点です。 営業とアナリスト業務の間には、非常に大きなGAPがあると思います。大きな決断前に業務イメージを一部でも把握できることは、今後のキャリア選択をする際の大きな材料になりました。 本業では得られない知識・スキルを実践で学ぶことができる点です。 RATファミリーの調査で海外ドキュメントを読み込んでみたり、簡単な分析環境を構築してみたり、実際に手を動かすことで、新しい知識の定着ができました。 わからないことがわかる!GAPがわかる!点です。 想像はしていましたが、セキュリティアナリスト業務に従事するには、プログラミングやLinuxが触れて当たり前!等の自分とのGAPがわかる点は、非常によい学びでした。 普段からSOC等で、アナリスト実務されている方は、改めて大尊敬する機会になりました。 このような学びがあるため、セキュリティ領域の営業系の方にも、アナリスト実務をぜひお勧めしたいです!
アバター
こんにちは、イノベーションセンターの加藤です。この記事では、Transformerベースの言語モデルで利用可能な高速化技術である投機的デコーディング(speculative decoding)を用いて、音声認識モデルのWhisperの高速化を検証したのでその結果を紹介します。 投機的デコーディングとは Whisperとは 実験 英語音声 (LibriSpeech) の結果 日本語音声 (Common Voice 17.0 日本語サブセット) の結果 まとめ 投機的デコーディングとは 大規模言語モデル(LLM)をはじめとするTransformerベースの言語モデルは、これまでの単語列から次に現れそうな単語を予測することを繰り返して文章生成を行なっています。 これに対し、元のモデルよりも軽量な言語モデルの出力を下書きとして利用することで、元のモデルの出力を完全に再現しながら文章生成を高速化する投機的デコーディング(speculative decoding)と呼ばれる手法があります。これは下図のように、軽量なモデルで数単語先まで予測してから元の大きなモデルでその予測を検証することで、元の大きなモデルの推論回数を節約しながら文章を生成する手法です。ちょうど人間が予測変換を活用しながら文章を入力するのと似た流れになっているのがわかると思います。 投機的デコーディングの詳細は 過去の記事 を参照してください。 下書きとして利用される言語モデルはLLMのようなTransformerベースである必要はなく、これまでの単語列から次に現れそうな単語をなんらかの形で予測できれば十分です。 投機的デコーディングでよく使われる下書きモデルは元モデルの蒸留モデルであったり、同じアーキテクチャでパラメータ数の少ないLLMであったりしますが、要約タスクやRetrieval Augmented Generation (RAG)などプロンプトから文言を抜き出すことの多いユースケースでは、プロンプトから収集したN-gramを参照して次に現れそうな単語を予測する Prompt Lookup が活用されることもあります。今回の実験ではこのPrompt Lookupの実装を少し変更して採用しています。 Whisperとは Whisper はTransformerベースの音声認識モデルであり、音声から特徴を抽出するEncoderと、対応するテキストを出力するDecoderからなります。 このDecoderでは文章生成タスク用の言語モデルと似た動作をしており、音声の特徴とこれまで出力したテキストから次に現れそうな単語を予測することを繰り返しています。そのため、投機的デコーディングをWhisperのDecoder部分にも適用できます。また、一般的な文章生成タスクと異なり出力文章の正解が大体決まっているため、下書きを作成する際に元モデルの途中までの出力を参照しなくても十分な正確性が期待できます。 そこで、性能が高いがモデルサイズの大きいWhisperモデルに対してまず軽量な音声認識モデルで文章を出力し、これを下書きとして参照することで、精度を維持したまま高速化する手法を実装してみました。推論の流れを下図に示します。 各時点での書き起こしの続きを下書きから抜き出す際はPrompt Lookupと同様の手法を使い、下書きのN-gramから一致度の高いものを選択しています。例えば上図の例では The man worked の時点で元モデルの予測が下書きから乖離していますが、下書きから a に続く文字列である security guard. を抜き出し、先読みに再度成功しています。 実験 今回は元モデルとしてwhisper-large-v3を使い、軽量モデルとしてwhisper-tinyを使いました。評価データセットは英語音声の LibriSpeech ASRコーパス と日本語音声の Common Voice 17.0 日本語サブセット の2つを用意しました。音声認識の精度は認識に失敗した単語数と関連が深い Word Error Rate (WER) を用いて評価し、その際日本語データに対しては MeCab で単語分割を行なっています。 処理速度はReal Time Factor (RTF)で算出します。これは1秒のデータを処理するのにかかった秒数を表し、小さいほど良い結果であることを示しています。 結果は以下の表のようになりました。 英語音声 (LibriSpeech) の結果 モデル WER RTF tiny (参考) 0.089 0.013 large-v3 0.032 0.085 large-v3 + tiny下書き 0.032 0.072 参考としてtinyモデル単体で音声認識した結果も示していますが、large-v3よりも6.5倍速い代わりにWERが悪化していることがわかります。 また、speculative decodingは元モデルの出力を完璧に再現するため、large-v3単体で動かした時と先読みをつけた時どちらもWERが0.032となっています。 そして先読みをつけた場合は実行速度が18%向上しました。参考として各モデルの書き起こし例を以下に示しますが、large-v3とtinyの出力の一致率が高く、うまく先読みを当てられていることがわかります。 Ground Truth (原稿) large-v3 tiny HURSTWOOD WALKED THE FLOOR MENTALLY ARRANGING THE CHIEF POINTS OF HIS SITUATION Hurstwood walked the floor, mentally arranging the chief points of his situation. First would walk to the floor mentally arranging the chief points of his situation. HE ALSO THOUGHT OF HIS MANAGERIAL POSITION He also thought of his managerial position. He also thought of his managerial position. FORTUNATELY THERE WAS NOTHING FROM HIS WIFE EITHER Fortunately, there was nothing from his wife, either. Fortunately, there was nothing from his wife either. HE AROSE FROM HIS CHAIR AND WENT AND LOOKED OUT INTO THE STREET He arose from his chair and went and looked out into the street. He rose from his chair and went and looked out into the street. HURSTWOOD ALMOST EXCLAIMED OUT LOUD AT THE INSISTENCY OF THIS THING Hurstwood almost exclaimed out loud at the insistency of this thing. Herstwood almost explained out loud at the insistence of this thing. 日本語音声 (Common Voice 17.0 日本語サブセット) の結果 モデル WER RTF tiny (参考) 0.844 0.017 large-v3 0.143 0.108 large-v3 + tiny下書き 0.143 0.120 一方で日本語音声では実行速度が改善せず、元のlarge-v3単体で動かした方が速いという結果になりました。そもそも全体的にWERが高く音声認識に苦戦していることもあり、品質の高い先読みを提供できていないようです。 各モデルの書き起こし例を以下に示します。 Ground Truth (原稿) large-v3 tiny セリヌンティウスは、縄打たれた。メロスは、すぐに出発した。初夏、満天の星である。 セリノンティウスは縄打たれた ネラスはすぐに出発した 初夏満天の星である セリナンティーズは奪われたネラズはすぐにしようっぱいずした、そこは満転の押すである。 僕らは何かを求めてゴミの山を漁っていた 僕らは何かを求めてゴミの山を漁っていた。 僕らは何かを求めて説明をさっていた ブラシを板の上に置くや否や、 ブラシを板の上に置くや否や では、教えておいては、お家に行きたいな。 私はポピュラー音楽を聞きたい。 私はポピュレア音楽を聴きたい 私はポフリアーを仲置きたい 大事なものじゃないの?と君はきいた 大事なものじゃないの?と君は聞いた 大事なものじゃないの?と、君が聞いた まとめ 本稿ではLLMの文章生成に使われている高速化手法のspeculative decodingを音声認識モデルに適用するとどれくらい高速化できるのか検証しました。 結果、一部の条件下では速くなることがわかりましたが万能ではなく、認識精度が確保できないケースでは先読みの恩恵が受けられないようでした。 また、Whisperはturboモデルというlargeモデルの軽量化版を提供しており、こちらは largeとほぼ同じ性能で8倍の高速化 をうたっています。このように学習時に工夫を入れ込んだ方がより高速な推論を期待でき、リソースが十分にある場合は学習部分の改善も視野に入れた方が良さそうです。
アバター
この記事では、NTTコミュニケーションズの先端AI数理PJが埼玉大学で行った時系列分析に関する研究会の様子とその講義資料およびハンズオン資料について紹介します。本記事で紹介した資料の完全版は こちら をご覧ください! 目次 目次 はじめに 講義の準備 講義内容の紹介と研究会の様子 AI・データ分析関連事業紹介と時系列分析の背景 可視化と探索的データ解析/前処理 線形モデリング Deep Learningによる時系列予測 質疑応答 参加者の声 感想 おわりに はじめに イノベーションセンター テクノロジー部門 先端AI数理PJの石山です。普段の業務では、因果推論や機械学習をもちいた時系列データ分析の研究開発やお客さまデータ分析案件支援を行っています。 この記事では、2023年12月に埼玉大学で行われた 「埼玉大学産学官連携協議会データサイエンス技術研究会第4回」 の内容とその様子を紹介します。 研究会では「時系列データの解析と産業応用」という題で、埼玉大学の学生の方や埼玉県の企業の方向けに講義とGoogle Colaboratoryによるハンズオン演習を行いました。 この講義は、先端AI数理PJがインターネット上に公開している 1 時系列データ分析コンテンツ 「ごちきか」 をもとに構成し、時系列分析の各手法から最新のDeep Learningに関する議論についても扱うといった内容です。 本研究会は、2024年人工知能学会全国大会でのNTTコミュニケーションズの展示に来ていただいたことをきっかけとして埼玉大学の平松薫教授からお話をいただき、実施することになりました。 人工知能学会では、2023年、2024年に「ごちきか」のトピックをまとめた冊子を配布したため、そういった活動も声をかけていただいたきっかけになったかもしれません。 なお、2024年度には、この研究会の内容を元に大学生向けに再編した講義を、「データサイエンス実践基礎」の一部として岩手大学で実施しました。 2 私は、「第5回: 分析モデリング」と「第7回: 因果推論」の講義を担当し、特に「第5回: 分析モデリング」に関する内容は今回の研究会の内容や反響を踏まえて作成しました。 講義の準備 「ごちきか」の運営メンバー5人が各コンテンツを担当して資料作成と講義を行う形式で準備を進めました。 準備の中では、伝わるか不安、ニーズを捉えられているかわからないといった議論が何度か起こりました。というのも、講義作成を担当したメンバーが所属するのは先端AI数理PJという研究開発を行うチームであることから興味の対象が比較的新しい技術になりがちな一方で、研究会には私たちが専門とする研究分野以外の方も多く参加されることが想像されることや、「ごちきか」はある程度数学やプログラミングを学んだ経験がある読者を対象に書かれているため、実務家にとってはハードルが高い話を説明無しにしてしまっているのではないかといった懸念がありました。 実施してみたところ、こうした不安とは裏腹に、意外にも(?)最新のディープラーニングに関するコンテンツが人気で、Transformerなどに触れての質問が当たり前のように出ていて驚きました。加えて、実務に関連した質問が多く、時系列データ分析に対してもこうしたディープラーニングを利用することへの期待度の高さが窺えました。 ここからは実際の講義の内容を紹介します。 講義内容の紹介と研究会の様子 講義は以下の構成で、ハンズオン演習とともに講義を行いました。 (NTTコミュニケーションズにおける)AI・データ分析関連事業紹介 (時系列分析の)背景 可視化と探索的データ解析/前処理 線形モデリング Deep Learningによる時系列予測 講義は、ドメイン知識を活かしたモデリングが大切であることと、今後、時系列データに対してディープラーニングをはじめとした大規模モデルを活かすためには、大規模時系列データセットを集めることが必要ということをメインメッセージとして展開しました。 AI・データ分析関連事業紹介と時系列分析の背景 時系列分析に関する私たちの取り組みと、時系列データがどのようなもので、分析によってどのようなことが可能になるかといった時系列分析の背景について説明しました。応用例として AIプラント運転支援ソリューション などの私たちの取り組みを挙げることによって講義で扱う内容についてイメージを持ってもらいました。 可視化と探索的データ解析/前処理 本格的な分析の前段階で必要となる可視化とそれによる探索的データ解析、そして前処理について解説しました。統計量の確認や特徴量の作成に関しては、時系列特有の方法や注意点があるため、通常の方法を素朴に行うのではなく、時系列性を考慮した手法で慎重に行う必要があることを説明しました。 線形モデリング 時系列線形回帰モデリングの説明を行い、線形モデルの課題である多重共線性の説明とその対策として、縮小推定や次元削減を伴うモデリングについての説明とハンズオンを行いました。 Deep Learningによる時系列予測 MLP(多層パーセプトロン)からCNN(畳み込みニューラルネットワーク)、RNN(リカレントニューラルネットワーク)について説明し、近年話題のTransformerのアーキテクチャとそれを時系列に応用したInformerについての説明とハンズオンを行いました。 最後に時系列分析に関して話題になったトピックを紹介しました。人工知能分野の国際会議AAAI2023の発表である「Are Transformers Effective for Time Series Forecasting?」とそのアンサーとして書かれたHugging Faceのブログ記事「Yes, Transformers are Effective for Time Series Forecasting 🤗」について、お話ししました。 質疑応答 参加者は埼玉県の地元企業の方と学生の方であわせて15名程度でしたが、ほとんどの方に質問をいただきました。質疑応答では、機械学習を実務で活かすうえでの課題についての質問が多くありました。参加者の方の技術レベルも高く、難易度の高い講義である深層学習パートに関する質問が盛況で、実際に手を動かす中で困っていることであったり逆にDX推進を取りまとめるという立場からのコメントもありました。さらに、製造業で直面する課題についてはお互いの事例を交えて踏み込んだ議論ができたため、私たちとしても非常に勉強になり、有意義な時間となりました。 参加者の声 参加された方からは 「研究会の内容があまり他にはないユニークな内容だった」 「初心者に対してもわかりやすい、かつ、リッチな内容を含んでいた」 「古典的な線形回帰から最先端のTransformerベースの手法までを示されたことで、現場で直面する課題を具体的に認識することができた」 「時系列データに特化した内容で、より深く知ることができた。実務で取り入れる際の実践的な手法に沿って講義されていたため、今後の実務に活かせそう」 と大変好評をいただきました! 感想 研究会のために講義資料を用意するのは大変でしたが、参加者の方からも好評をいただくことができ、また私たちとしても、あらためて時系列分析の勉強や最新情報へのキャッチアップを行うことができ、大変よい機会でした。 また研究会代表の平松教授からは「次もまたお願いします」とのお言葉を頂きました。私どもとしても埼玉大学をはじめとして埼玉県内の企業・組織のみなさまと今後も連携させていただければと思っております。 おわりに 本講義は、先端AI数理PJが運営する時系列データ分析コンテンツ「ごちきか」の内容をもとに構成し、講義を行ったものです。当日の講義資料と演習用コードも こちら で公開しております。 「ごちきか」では、ほかにも時系列分析に関連して、 スパースモデリング や VAR-LiNGAM などの時系列因果探索、NTTグループ合同で行ったDeep Learningに関する 勉強会資料 なども公開していますので、ぜひご覧ください! 私たちの取り組みに興味がございましたら、時系列データ解析/予測/異常検知/因果探索/因果推論を対象としたPoC、各種機関との共同研究、 Node-AI のご契約を募集中ですので、メールにてご連絡ください。(メール: ai-deep-ic[at]ntt.com) 「ごちきか」公開の経緯やコンセプトについては、 過去のエンジニアブログの投稿 もご覧ください。 ↩ https://www.iwate-u.ac.jp/info/news/2024/11/006453.html ↩
アバター
みなさんこんにちは、イノベーションセンターの益本 (@masaomi346) です。 Network Analytics for Security (以下、NA4Sec) プロジェクトのメンバーとして活動しています。 この記事では、2025年1月21日・22日に開催されたセキュリティカンファレンスJSAC2025で登壇したことについて紹介します。 私たちが観測したある2つのPhishing as a Service (PhaaS) の分析結果についての講演 ぜひ最後まで読んでみてください。 JSACについて JSAC (Joint Security Analyst Conference) はJPCERT/CCが主催するセキュリティカンファレンスで、現場のセキュリティアナリストが集い、高度化するサイバー攻撃に対抗するための情報を共有することを目的に開催されています。 非常に注目を集めているセキュリティカンファレンスであり、数日で定員が埋まって参加申し込みが締め切られるほどです。 海外からも注目されており、今年のJSAC2025は海外からの登壇が半分以上を占めていました。 昨年のJSAC2024と比べると、明らかに海外比率が増加していて、国際会議としての色が濃くなってきています。 日本を含むAPACに関係している脅威についての講演が多数占めており、特に今年はAPT攻撃 (高度標的型攻撃) をテーマにした講演が多くなっていました。 また、メイントラックの講演以外にも、ハンズオン形式のワークショップなどもあります。 #JSAC2025 2日目です。本日もよろしくお願いいたします。 pic.twitter.com/3zvTppzOpG — Analysis Center (@jpcert_ac) 2025年1月22日 会場では、さまざまな職種や役割が書かれたシールを配布しており、参加者はそれを付けて参加します。 NA4Secについて 「NTTはインターネットを安心・安全にする社会的責務がある」を理念として、インターネットにおける攻撃インフラの解明・撲滅を目指すプロジェクトです。 NTT Comグループにおける脅威インテリジェンスチームとしての側面も持ち合わせており、有事において脅威インテリジェンスを提供し、意思決定を支援することもあります。 イノベーションセンターを中心として、NTTセキュリティ・ジャパンやエヌ・エフ・ラボラトリーズ(以下、NFLabs.)からもメンバーが参画し、日夜攻撃インフラを追跡しています。 昨年もNA4SecメンバーがJSACに参加しており、それについての記事がありますので、興味がある方はぜひ読んでみてください。 セキュリティカンファレンス「JSAC2024」に参加してきた話(登壇編) セキュリティカンファレンス「JSAC2024」に参加してきた話(聴講編) NA4SecによるJSAC2025登壇 NA4Secからは、フィッシング詐欺に関する講演が1件採択されました。 以下のタイトルで登壇させていただきました。 Analysis of Two Phishers : Like a doppelganger / イベント登壇情報🎙️ \ 国内有数のセキュリティカンファレンス #JSAC2025 にて、NTT Comの益本が二日目(1/22)に登壇✨ ドッペルゲンガーのように同じ振る舞いをする奇妙なPhaaS (Phishing as a Service) について報告します🎣🎣 詳細はこちら⬇ https://t.co/vO0LejZpuJ #ドコモビジネス pic.twitter.com/0QQKySxvbX — ドコモビジネス|NTTコミュニケーションズ (@NTTCom_online) 2025年1月21日 サイバー犯罪を支援するためにさまざまなサービスが誕生しています。フィッシング詐欺においても同様であり、フィッシング詐欺を支援するPhishing as a Service (PhaaS) が存在しています。 PhaaSを利用することで、フィッシング詐欺をするための技術的なハードルが下がり、フィッシング詐欺をしやすくなります。 NA4Secで取り組んでいる活動の1つに、フィッシング詐欺についての脅威分析があります。 活動の中で偶然観測したある2つのPhaaSは、まるでドッペルゲンガーのように同じ振る舞いをしていることがわかりました。 ほぼ同じ時間に同じ投稿をしている 使われているフィッシングサイトやツールが同じである 講演では、2つのPhaaSコミュニティで投稿されている内容や提供されているサービスの内容、2つの攻撃者の関連性などを紹介しました。 分析結果から、これらのPhaaSは何かしらの協力関係があるか、同じ攻撃者によって運営されている可能性があることについても言及しました。 また、PhaaSのフィッシングサイトや環境構築に使われているツールの分析結果、検知やハンティングについても紹介しました。 環境構築に使われるツールを分析することで、どのようにフィッシングサイトを構築されているかを理解できます。 なので、このような分析はフィッシング詐欺の実態解明につながる価値があると考えて紹介しました。 こちらに講演資料が公開されていますので、参加できなかった方もぜひ読んでみてください。(なお、一部の講演スライドを非公開にしています) 英語版 日本語版 さいごに 昨年に続き、JSACで2年連続登壇させていただきました。 昨年のJSAC2024が初めての外部登壇でしたが、あの時と比べると、外部登壇にかなり慣れてきたような気がします。 国内有数のセキュリティカンファレンスを通じて、継続的にセキュリティ業界に貢献しつづけることができて良かったです。 この講演が、少しでもフィッシング詐欺の実態解明に貢献できればいいなと思っています。 今後も引き続き、何かしらの形でセキュリティ業界を盛り上げていくつもりでいます。 この講演に興味を持たれた方へ 攻撃者の詳細に関わる情報については、外部公開資料では非公開になっています。 ただ、サイバー攻撃に係る情報を共有することは実態解明や被害低減につながる価値があると考えています。 出張講演なども前向きに検討しますので、興味のある方はTeam NA4Secまでお気軽にご相談ください。(公開されている資料の最後の方に連絡先が書かれています)
アバター
本記事では、現在進行中の研究「機械学習×数理最適化」に関する取り組みの一環として検討している、需要予測を活用した業務プロセスの改善について紹介します。 はじめに 背景 数理最適化とは 機械学習×数理最適化で解決が期待できる課題 実現方法の検討 問題設定 Node-AIでの需要予測 数理最適化によるシフト計画 条件データ 定式化 プログラム 結果 まとめ おわりに はじめに こんにちは、イノベーションセンターの伊藤です。 普段は Node-AI や AI Autopilot System といったプロダクトの品質向上を目的に、研究開発を行っています。現在は予測精度の向上を目指した機械学習技術の研究に加え、予測結果の活用に向けた技術の研究に取り組んでいます。 また、我々のチームでは、これらの取り組みを通じて得られた研究成果やデータ分析ノウハウを ごちきか というナレッジベースに体系的にまとめています。 本記事では、コールセンターにおける人員配置を一例に、需要予測を活用した業務プロセスの効率化に関する検討を、数理最適化に主眼を置いて紹介します。 背景 数理最適化とは 数理最適化とは、「制約条件を満たす候補の中から最善なものを数学的に導き出す技術」です。 身近な例として、500mlのスムージーを作ることを考えてみます。 例えば、数理最適化の技術を活用すると、「果物や野菜などの食材を合わせて500ml以下に収める」、「スムージーに含まれるビタミンやミネラルといった栄養価を一定以上に保つ」という制約条件の下、費用を最小化する食材の組み合わせを見つけることができます。 数理最適化の問題の一般形は、次のように表現されます。 つまり、不等式 や等式 の制約を守りながら、目的関数 を最小化あるいは最大化するような最適な変数 を見つける数理モデルを表します。 例えば、現行の高校数学Ⅱで学ぶ連立1次不等式が表す領域において最大値・最小値を求める問題は、まさに数理最適化の問題の一種です。具体的には、「点 が連立不等式 の領域を動くとき、 の最小値を求めよ 」といった問題が該当します。実際にその問題を定式化すると、以下のようになります。 この式が数理最適化の問題の一例であることは容易に確認できます。 機械学習×数理最適化で解決が期待できる課題 機械学習と数理最適化を掛け合わせることで解決が期待できる実課題を3つ紹介します。それぞれの課題について、ユーザーが実現したいことと各技術を組み合わせて活用したその解決策を説明します。 ユースケース1 (シフト最適化) 👧:「サービスの需要予測とそれにもとづくシフト割当を自動化して、業務効率を向上させたいです…」 💡: 機械学習 → 過去の需要データや時系列データ(曜日、天気、特定のイベントなど)から将来の需要を予測 数理最適化 → 予測された需要に基づいて、最適なシフト割当を自動で決定 ユースケース2 (在庫管理) 👨:「在庫の過不足を防ぎコスト削減ができたらなぁ」 💡: 機械学習 → 販売履歴や市場動向、季節要因などから未来の需要を予測 数理最適化 → 需要予測に基づき、リードタイムや在庫コストを考慮し、適切な発注量や在庫水準を決定 ユースケース3 (ダイナミックプライシング) 👥:「需要予測に応じて最適な価格を設定し売上を最大化したい!」 💡: 機械学習 → 消費者の購買行動などを分析し、該当サービス/商品における将来の需要を予測 数理最適化 → 需給バランスを保ちながら、売上最大化を実現化する最適な価格を決定 このように、機械学習と数理最適化の技術を組み合わせることで、片方の技術だけでは解決困難だった課題に対して、効果的な解決策を提供できることが期待できます。 次章では、ユースケース1(シフト最適化)を一例に、具体的な実現方法を詳しく検討していきます。 実現方法の検討 問題設定 取り扱う問題は以下の通りです。なお、問題はシンプルに設定しています。 勤務内容:コールセンター 勤務時間:9:00〜18:00 (土日・休日も営業) サービス:A, B, Cの3種類 例えば、リモートワーク支援ツールやサブスクリプションサービスなどの対応 オペレーター:10人 (呼称:a ~ j) ただし各々で対応可能なサービスは異なる ユーザーの状況 現状 これまでシフト作成は経験則に基づいて手作業で行われていた 具体的には3種類の業務に対して1週間分の架電数を予測し、必要な人員を配置している しかし、シフト計画の策定には複雑さが伴い、膨大な時間を要している シフト計画の主な目的は人的リソースの効率的活用で、1週間分のオペレータ業務における総労働時間の最小化を目指している あるオペレータがその日の勤務時間が0分となる場合、そのオペレータの業務参加は任意となり、庶務作業などの他の業務にリソースを割り当てることが考慮される サービスごとの過去の需要データは記録している 各オペレータの1週間分の勤務可能時間や、サービスごとにかかる平均対応時間も把握している 要望 シフト計画の作成を定量的に自動化したいと考えている シフト表は、月曜日始まりの1週間単位で出力してほしいという希望がある 上記の設定から、次のような計画を立案しました。 - 自動化の全体像: ・ 3種類のサービスに関する架電数予測 → 機械学習 ・ 月曜日を始まりとした1週間単位のシフト計画 → 数理最適化 - 機械学習: ・ 過去の需要データを用いて、サービスA, B, Cそれぞれに対して機械学習モデルを構築 - 数理最適化: ・ 最小化 -> 全オペレータの1週間分の総労働時間 ・ 制約条件: % 各サービスの需要を満たすこと % 各オペレータの最大勤務時間を超えない % 各オペレータに対応不可能なタスクを割り当てない 全体像としては、次のようなイメージです。 この計画を踏まえて、適用する機械学習と数理最適化の技術を実際に検討してみます。 Node-AIでの需要予測 前述した計画をもとに、最初にサービス3種類の架電数を予測します。今回はNTT Comで提供しているノーコードAI開発ツールNode-AIを使用して、架電数予測を実施します。本検討では、現実のデータではなく人工データを用いています。 詳細な説明は省略しますが、次のようにNode-AIでキャンバスを作成しました。 (データ分析のやり方の詳細は こちら に掲載しています。ここではサービスAにおける架電数予測モデルのキャンバスのみ掲載します。) こうして、サービスA, B, Cの需要予測モデルを構築しました。このモデルにより、今後1週間分の需要予測が可能となります。 実際に、サービスAをNode-AIで架電数を予測した結果は次のようになりました。 こうして、以下のような結果が得られました。 (※1 スペースの都合上一部のみを表示, ※2 後段処理のために予測結果を整数値に補正) 2021-12-13 (Mon) 2021-12-14 (Tue) … 2021-12-19 (Sun) A 81 81 … 81 B 15 15 … 17 C 5 6 … 5 数理最適化によるシフト計画 次に、Node-AIで予測した結果と数理最適化の技術を活用して、1週間分のシフト計画を作成していきます。 条件データ ユーザー状況から、各オペレータの1週間分の勤務可能時間とサービスごとにかかる平均対応時間が把握されています。 これらに対応するデータを以下に掲載します。 ○ 各オペレータの1週間分の勤務可能時間 (スペースの都合上一部のみ)     ・ 行には各オペレーターの名前が、列には日付が示されています。     ・ 例えば、オペレーター jは2021-12-14 (Tue)に480分勤務可能であることを表しています。 2021-12-13 (Mon) 2021-12-14 (Tue) … 2021-12-19 (Sun) a 240 240 … 240 b 300 0 … 0 … … … … … j 480 480 … 480 ○ 各オペレータのサービスごとにかかる平均対応時間 (スペースの都合上一部のみ)     ・ 行は各オペレーターの名前を、列はサービス種類を表しています。     ・ 例えば、オペレーター aはサービスBの対応に平均30分かかることを意味します。 A B C a 15 30 20 b 20 35 30 … … … … j 35 35 0 定式化 ここから、数理最適化の問題として定式化していきます。まず定式化に使う変数を定義します。 非決定変数 (モデル内で固定されているパラメータ) :スケジュールを実施する日数 (今回: ) :タスクの種類数 (今回: ) :オペレータの人数 (今回: ) :オペレータ がタスク を対応するのにかかる平均労働時間 [分] の場合、そのタスクに対応できないことを意味します :オペレータ が日付 に勤務可能な最大の時間 [分] の場合、その日は勤務できないことを意味します :タスク が日付 に処理する必要があると 予測された 数 決定変数 (最適化する変数) :オペレータ が日付 にタスク を処理する数 続いて、これらの変数を用いて定式化していきます。以降、数式が多くなります。 ○ 目的関数:全オペレータの対象日数の総労働時間を最小化 ○ 制約条件:     ・予測タスク数の対応に関する制約     ・ 最大勤務時間を超えないようにする制約     ・ 各オペレータに対応不可能なタスクを割り当てないようにする制約     ・ タスクの処理数はすべて0以上であるという制約 (非負制約) 以上が、目的関数と制約条件の説明でした。改めて整理すると、以下のように定式化しました。 プログラム 本検討では、最適化モデルを構築するためにPySCIPOptを、そしてそのモデルをベースに最適解を求めるためにSCIPソルバーを使用します。ここで、PySCIPOptは問題をコンピュータが処理可能な形式に変換するモデリングツールであり、SCIPソルバーはそのモデルを用いて最適解を探索するツールです。PySCIPOptとSCIPソルバーのドキュメントはそれぞれ、 こちら と こちら をご参照ください。 以下に、PySCIPOptとSCIPソルバー、numpyがインストールされていることを前提に、これらのツールを用いたコードを示します。 import numpy as np from itertools import product from pyscipopt import Model """ version Python: 3.8.10 PySCIPOpt: 5.2.1 SCIPソルバー: 9.2.0 numpy: 1.22.4 """ def solve_scheduling_problem (T, K, N, C, A, O): """ 引数(T, K, N, C, A, O):非決定変数に相当 """ # Modelクラスのインスタンス作成 model = Model(problemName= 'Scheduling' ) # 決定変数の定義 x = {} for i, j, t in product( range (N), range (K), range (T)): x[i, j, t] = model.addVar(vtype= "I" , lb= 0 , name=f "x_{i}_{j}_{t}" ) # 目的関数(全オペレータの対象日数の総労働時間を最小化)を定義 model.setObjective( sum (C[i][j] * x[i, j, t] for i, j, t in product( range (N), range (K), range (T))), sense= "minimize" ) # 予測タスク数の対応に関する制約 for j, t in product( range (K), range (T)): model.addCons( sum (x[i, j, t] for i in range (N)) == O[j][t] ) # 最大勤務時間を超えないようにする制約 for i, t in product( range (N), range (T)): model.addCons( sum (C[i][j] * x[i, j, t] for j in range (K)) <= A[i][t] ) # 各オペレータに対応不可能なタスクを割り当てないようにする制約 for i, j in product( range (N), range (K)): if C[i][j] == 0 : model.addCons( sum (x[i, j, t] for t in range (T)) == 0 ) # 最適解導出 model.setParam( 'display/verblevel' , 0 ) # ログ出力を抑える model.optimize() # 最適化の結果出力 status = model.getStatus() if status == "optimal" : # 最適解が見つかったならば solution = np.zeros((N, K, T)) # N x K x Tのゼロ行列を作成 for i, j, t in product( range (N), range (K), range (T)): solution[i, j, t] = int (model.getVal(x[i, j, t])) return solution else : print ( "エラー:{}" .format(status)) return None # エラーの場合は None を返す 個人的な見解ですが、数理最適化の問題に適切に定式化できれば、プログラム自体は直感的に実装できると思います。 結果 以下に最適化のコードを実行した結果を示します。今回の実行により最適化結果が表示されたので、最適解が得られたことを確認できます。なお、最適化結果は瞬時に返されました。 タスク割当表 (スペースの都合上一部のみ記載) 行は各オペレーターの名前を、列は(日付、サービス種類)の組み合わせを表しています。 例えば、オペレーター dは2021-12-14(Tue)にサービスBの対応を15件予定しています。 シフト表 タスク割当表および各オペレーターの1週間分の勤務可能時間に基づいて作成されています。 例えば、オペレータ d は 2021-12-14 (Tue)のコールセンターの勤務が予定されており、オペレータ j は 2021-12-16 (Thu)については任意となっています。 Node-AIで予測した各サービスの架電数とタスク割当表を照らし合わせると、適切にタスクが割り当てられていることが確認できます。例えば、2021-12-13(Mon)でのサービスBの架電数が15件と予測されていましたが、実際にオペレータeに15件が割り当てられていることが確認できます。 このようにして、機械学習と数理最適化の技術を活用することで、タスク割当表とシフト表の作成を定量的に自動化することが可能となりました。 まとめ 本記事では、数理最適化を中心に、需要予測を活用した業務プロセスの最適化に関する検討をご紹介しました。特に、コールセンターにおけるシフト最適化を例に、課題設定から実装までの一連の流れを示しました。 今後の展望としては、実社会への適用、新たな手法の研究、さらには定式化支援の研究などを進めていく予定です。 おわりに 本記事が少しでも皆さまのお役に立てたのであれば、嬉しく思います。さらにNode-AIに関する知見を深めたい方は、 こちら の情報もご参考にしてください。本記事の内容についてお問い合わせがございましたら、 こちら のフォームからお気軽にお問い合わせください。
アバター
ノーコードAI開発ツール「Node-AI」のプロダクト開発チーム(以下Node-AIチーム)は、 2024年1月から1年間採用していたLeSSでの開発体制を見直し、1チームによるスクラム体制で再出発しました。 本記事では、その背景についてご紹介します。 はじめに LeSSの課題 原因1 原因2 課題のまとめ チーム体制変更の検討 調査と決定 狙い 調整 今後に向けて おわりに はじめに こんにちは。 Node-AI チームのスクラムマスター 中野 と申します。 もともとはNode-AIの開発者でしたが、前任者の異動を機に、スクラムマスターに挑戦しています。 得意な分野はデータ分析や機械学習で、プロダクトに関連するログデータの分析にも取り組んでいます。 さて、Node-AIチームは2024年の1年、 LeSS (Large-Scale Scrum)を採用しスクラムを運用していました。 確かに最初はうまくいく事が多かったですし、判断は間違いではなかったと考えています。 当時の状況は以下の記事で紹介していますので、ご興味があればご覧ください。 engineers.ntt.com しかし、Node-AIはこの1年でさまざまな状況が変化し、 地道で小さなプロセス改善だけでは対応しきれない問題が増えていきました。 そこで年末にチーム全体で話し合い、1チームによるスクラム体制で再出発することを決定しました。 LeSSの課題 この記事は、LeSSそのものを批判する内容ではありません。 現在のNode-AIチームの状況を踏まえると「LeSSが合わなくなってきた」という理解をしています。 細かい原因はいくつかありますが、要約すると以下に帰着すると考えています。 「Node-AIチームの取り組みが多様化・高度化する中で、 小規模なフィーチャーチームごとにプロダクトバックログを消化する方法で、 ユーザー価値を最大化することが難しくなってきた」 原因1 2024年、おかげさまでNode-AIは多くのお客さまや社内営業から引き合いをいただきました。 そのため、Node-AIチームのメンバーはソフトウェア開発以外の業務にも積極的に取り組み、 要望に応えるべく全力を尽くしていました。 例えば、社内営業にNode-AIを理解してもらう勉強会や社内コミュニティの活動、 営業への同行、SNS等を活用したマーケティング活動をコンサルティングチームと協力しながら開発チームのエンジニアも含めて対応しています。 そのようなタスクは差し込みで発生することが多く、優先度を付けるのも難しいため、 プロダクトバックログとは別の場所で管理し、可視化していました。 しかしタスクによっては個人で動いているものや、 複数メンバーでローテーションを組んで対応しているもの、 実は可視化や共有が十分でなかったものなどさまざまでした。 その結果、誰が何をやっているのか把握するのが次第に難しくなっていきました。 頻繁な差し込みは頭の切り替えにも負荷がかかるため、 開発者のモチベーションや生産性にも影響を与えているという意見も出ました。 ここまではLeSSに関係なく起こり得ることですが、LeSSを採用していた影響で、 小規模な(6人以下の)フィーチャーチームにおいてメンバーが不在となるケースが増えました。 それにより「あるスプリントではフィーチャーチーム内に2人しか開発者がいない」という状況も発生し、 一時的に機能横断ではなくなるためチームが取れるプロダクトバックログに偏りが生じ、 チームごとのベロシティも安定しませんでした。 原因2 また、Node-AIは大規模で専門性の高い機能追加、ユーザー理解のための調査、 研究開発チームと協力して行う高度な機械学習アルゴリズムの実装、 安定的なサービス提供を目的としたOps強化など、 チーム全体での最適化や腰を据えたスキルトランスファー(スキトラ) が必要な取り組みを並列で進めていく必要性が増していました。 そのため、各フィーチャーチームで物事を完結するのは難しく、 スプリント内で無理が生じることも度々発生していました。 対応策として、一時的に1チームにしたり有識者を別チームに派遣するなどしていましたが、 都度調整するコミュニケーションコストも増加し、チームとして不安定な状態と言わざるを得ませんでした。 課題のまとめ LeSS体制における課題をまとめると、以下の2点となります。 プロダクトバックログ外のタスクの差し込みにより、各フィーチャーチームのベロシティが安定しない チーム横断での最適化やスキトラの必要な取り組みが増え、フィーチャーチーム個別での最適化がチーム全体の最適化とマッチしない チーム体制変更の検討 調査と決定 上記の課題を解決するには、地道なプロセス改善だけでは難しいという意見が開発者から上がり、 チーム体制の変更で解決を目指す実験をすることをまず決定しました。 ただしチーム体制といっても多数の選択肢があるため、 まずは他社事例やフレームワークを調査し、どのような方法があるのか洗い出しました。 そして、Node-AIのメンバーで現実的に組めるチーム構成案を複数作成しました。 具体的には以下の方法です。 プロダクトを2つのプロダクト群に分割し、2つのスクラムで別々の目標を設定する体制 チームトポロジー の考え方にもとづく分割方法 1チームでスクラムを回す体制 各案を採用した場合の各チームの責務やメリット・デメリットを整理し、 メンバーの希望も加味して最終的にDevOpsの1チームスクラム体制を採用することに決定しました。 この作業はスクラムマスターが一部整理・誘導した部分もありますが、 ほとんどの検討プロセスはチーム全員で主体的に決定しました。 狙い 1チームスクラム体制を選んだ決め手の1つは、 「うまくいかなかった場合、元に戻しやすく、他の案へ柔軟に変化もさせやすい」という点です。 あまり凝ったことをしてもチーム体制変更の影響を評価しにくく、ルール決めにも体力が必要となります。 一方、1チームスクラムは過去に経験があるため、各自が勘所を把握しており、 1チームで回すこと自体に伴う新たな知識の習得やルール決めを最小限に抑えることができます。 小規模なチームですし、ダメだったら他の案にすればいいだけ、と軽く考えられます。 また、2チームに分散していた個々人のスキルを1チームにまとめることで、 課題(2)に対してタスクに集中して取り組める環境を作り、 チーム全体の最適化が進むことを狙っています。 他の構成案をベースとしてチームごとに役割を分けることでも課題の解消は可能だと思いますが、 社内の他プロダクトのネガティブな例や開発者個人のキャリア面も考慮して今回は見送りとしました。 課題(1)に関連する差し込みタスクについてはプロダクトオーナー(PO)・スクラムマスターでの巻き取りや、 後述するメンバー調整により緩和できると考えていますが、 スクラムチームのビジネスサイドとの関わりを完全に停止するのはリスクもあります。 一定量はスクラムチームに残しつつ、チーム全体での開発者稼働が極端に減る状況が常態化しないように調整していきます。 調整 Node-AIチームは現在約10人のメンバーが所属しています。 1チームだと人数が多すぎること(これがLeSSを採用した背景の1つ)や、 POへの負荷が異常に高いといった別の問題も存在していたため、 今回の課題も考慮して以下の変更も同時に実施しました。 POとプロダクトマネージャー(PdM)を2名で分業し、PdMはスクラム外からプロダクトを支援する。 旧POがPdMとなり、新POは開発者から選任する。 プロダクトバックログ以外のタスクが特に集中していた開発者2名は(同意のもと)スクラムから外れてもらい、 チームX(名称検討中)として、各自の裁量で遊撃的に動けるようにする。 これによりバックログ外のタスクをスクラムの外で独立して対応できると考えています。 変更前後の構成を図に表すと以下のようになります。 ※ "az" "mm" はチーム名の略称です。 ※ POの変更は以下の記事で一部紹介しています。 engineers.ntt.com 今後に向けて PdMやチームXの今後の動きについては、進行しながら調整していくことになりますが、 スクラムの観点から見るとステークホルダーという位置付けになります。 引き続き、各種スクラムイベントでは密に連携していく予定です。 今後の課題としてはチーム体制変更を含むプロセス改善の効果測定を定量的に実施することです。 これまでベロシティを基準としたり、Four keys等の調査までは行ったものの、 形骸化したり導入が後手となり、結局は肌感を優先した検査・適応となっているのが実情です。 さまざまな指標をモニタリングできる環境も整いつつあるので、近いうちに検証を始めてみたいと考えています。 おわりに 1チームスクラムに移行したことで、チームが抱えていた課題が緩和されることを期待しています。 しかし、チーム体制を変更すればすべての問題が解決されるわけではありません。 今後は地道にプロセスを改善し、どうすれば最もユーザー価値を高められるのか試行錯誤していきます。 また、そもそも1チームからLeSSに移行した際には逆の課題があったわけですから、当然それが再燃することも考えられます。 その時に、再度チーム体制の変更で問題を乗り越えるのか、別の方法を取るのかは現時点では分かりません。 ただ、今回チーム全員が主体的に課題に対する手段を選択し、 変化を実現できたことはチームにとって非常に価値のある経験となりました。 引き続き、どのような変化にも対応できる強いチームを目指していきたいと思います!
アバター
この記事は、  NTT Communications Advent Calendar 2024  の記事です。 みなさんこんにちは、イノベーションセンターの冨樫です。Network Analytics for Security 1 (以下、NA4Sec)プロジェクトのメンバーとして活動しています。この記事では「 利用終了したドメイン名の終活に向けて 〜観測環境を作った話〜 」で紹介した観測環境から収集したログの分析結果について説明します。また、この分析の過程で利用終了ドメイン名を管理するにあたり有効なアクションを発見したので、それらについても一部紹介したいと思います。 ログの分析 DNSクエリの分析 Webアクセスログの分析 残存リンクの削除 まとめ ログの分析 本施策では、さまざまな用途で使用していた複数の利用終了ドメイン名に対して、DNSクエリとWebアクセスログを収集しました。ドメイン名の元々の用途によってログの分析結果に傾向がありましたので、一部のマスキングしたドメイン名を使って紹介します。 DNSクエリの分析 7月から11月にかけて収集した約18,000,000件のDNSクエリのタイプを集計しました。下図は、調査対象の全ドメイン名のクエリを合算した集計結果とaaa.example、bbb.exampleにおける集計結果です。 aaa.exampleとbbb.exampleはそれぞれ以下の用途で使用されていた利用終了ドメイン名です。 aaa.example : Webサイトとして利用されていたドメイン名 bbb.example : NTTコミュニケーションズの関連会社のコーポレートドメインとして利用されていたドメイン名 aaa.exampleでは、Aレコードの割合が87%を占めており、全ドメイン名の集計結果におけるAレコードの割合が59%であることを考慮すると、高い傾向にあります。 これはaaa.exampleがWebサイトのドメイン名として使用されていたため、利用終了後の現在においてもWebアクセスを起点とする名前解決が行われていることが原因の可能性があります。さらにここからインターネット上にこの利用終了ドメイン名宛のリンクが残っており、そこからアクセスが発生している可能性も考えられます。 一方、コーポレートドメインであるbbb.exampleはメールアドレスとしても利用されていた背景があり、MXレコードの割合が28%を占めていて、これは他のドメイン名と比較して高い傾向にあります。 また、bbb.exampleのMXレコードに絞ってDNSクエリが来た曜日を集計したところ、下図のように平日のカウントが比較的に高い結果になっていました。これらのことから現在もこのドメイン名を宛先としたビジネスメールや広告が送信されている可能性があると考えられます。(月曜日のMXレコードの件数が土曜日よりも少なかったことは、日本と標準時間が異なる地域からのメールによるものと推察しています。) その場合には、このドメイン名がドロップキャッチされると、それらのメールを第三者が確認することも可能ということになり、ドメイン名の廃止には注意が必要です。 Webアクセスログの分析 Webアクセスログについては6月から11月にかけて約1,700,000件を収集しました。今回はWebアクセスログに含まれるUser-Agentを活用してクライアントの特性を分析しました。 下記は実際に収集したUser-Agentであり、クライアントのOS、デバイス、ブラウザの種類等の情報を得ることができます。また、それらを用いてクライアント端末がPCとモバイルに分類することも可能です。 下図は、クライアントがPCかモバイルかを判別し、全ての利用終了ドメイン名を対象に集計した結果と、ccc.example のみを対象に集計した結果を比較したものです。(Others は分類するための情報がUser-Agentに含まれていなかった場合に該当) ccc.exampleは以下の用途で使用されていた利用終了ドメイン名です。 ccc.example : NTTコミュニケーションズと関連するプロスポーツチームのホームページに利用されていたドメイン名 ccc.exampleのモバイルからのアクセスは18%であり、全ての利用終了ドメイン名を対象に集計した結果と比較すると5倍以上比率が高いという結果でした。これはccc.exampleで運営さていたWebサイトは、スポーツチームのホームページであり、訪問者の嗜好でアクセスが発生している場合も多く、そのためモバイルの比率が高まったと考察しています。 下図は各クライアントが使用したOSの件数を示しています。ccc.exampleではiOSからのアクセスが3位(全体では6位)、Androidからのアクセスが4位(全体では5位)であり、ここからもモバイルのアクセスが多いことを確認できます。 今回User-Agentを使ったように、WebアクセスログにはDNSクエリにない情報が含まれており、これらを活用して利用終了ドメイン名のクライアントの情報を分析可能です。 残存リンクの削除 利用終了ドメイン名を廃止する際には、インターネット上にそのドメイン名宛のリンクが残っていないことが理想的です。これは廃止後にそのドメイン名がドロップキャッチされ、新たな登録者がWebサイトを立ち上げた場合に、そのインターネット上に残ったリンク (以下、残存リンク) から訪問者が意図しない新規のWebサイトに誘導される可能性があるためです。また、それが悪性のWebサイトである場合、そのドメイン名を前に登録していた企業のレピュテーションに影響が生じることも想定されます。以上より、インターネット上の残存リンクはできれば削除することが好ましいです。 そのために、まずは残存リンクが掲載されているWebページを特定する必要があり、今回は収集したWebアクセスログのRefererを利用した調査をしました。 Refererを参照することで、Webサイトの訪問者がどのサイトからアクセスしてきたのかを確認でき、そのサイトには残存リンクが存在すると想定されます。ただし、クライアントのWebブラウザの設定などが影響し、Webサイトの詳細なパスまで入手できないことがほとんどでした。つまり、訪問者が来たWebサイトのドメイン名 (サイト名) は分かるが、どのページから来たのかということまでは分からない状況がほとんどでした。 訪問者が来たWebサイトのページを特定するためにGoogle Dorksを用いた調査をしました。Google Dorksは、演算子を駆使したGoogleでの検索手法のことで、今回は下記の検索演算子を使用しました。 site 演算子 : 指定されたドメイン名でインデックスされているWebページを検索 link 演算子 : 指定URLへのリンクを含むWebページを検索 例えば、Refererから確認できたドメイン名がexample.comで、アクセスされた利用終了ドメイン名がaaa.exampleの場合には下記で検索しました。このようにすることでaaa.exampleへのリンクを含んだexample.comのページを調査できます。 site:example.com link:aaa.example 今回はこの手法で複数の残存リンクが存在するページを特定できました。また、Wikipediaなどの編集が可能なサイトについては自ら削除対応しました。 このように残存リンクをインターネット上から減らすことで、ドメイン名廃止後にドロップキャッチされた際のリスクを軽減できます。 まとめ 今回は「 利用終了したドメイン名の終活に向けて 〜観測環境を作った話〜 」で紹介した観測環境から収集したDNSクエリとWebアクセスログを分析し、各利用終了ドメイン名ごとの特性を評価しました。 また、利用終了ドメイン名を管理する上で有効なアクションとして残存リンクの調査方法を紹介しました。 NA4Secプロジェクトについては、このブログの記事  サイバー脅威インテリジェンス(CTI)配信はじめました  をご覧ください。 ↩
アバター
はじめに こんにちは!NTTコミュニケーションズの 2024年夏の現場受け入れ型インターンシップ に参加させていただきました、大学院1年生の 山本 です。 現在はフィッシングサイトの検出をテーマに研究活動を行っています。 本記事では、インターンシップを通して体験させていただいた業務内容のうち、特にフィッシングキットの分析について紹介させていただきます! はじめに 参加チームについて(NA4Sec) インターンシップに参加した経緯 体験内容の概観 フィッシングキットの詳細分析 構成ファイル 分析方法 騙っているブランドについて どんな情報を窃取しようとしているのか どのような処理があるのか 検知に活⽤できそうな情報 攻撃者に関係していそうな情報 おわりに 参加チームについて(NA4Sec) 私はインターンシップの期間中、 NA4Sec というチームに参加させていただきました。 NA4Secの正式名称は「Network Analytics for Security」であり、 「NTTはインターネットを安心、安全にする社会的責務がある」 ということを理念として掲げ、攻撃インフラの解明や撲滅を目指して活動しているチームです! 1 将来的にセキュリティに携わって人々を守りたいと考えている自分にとって、とても魅力的なチームでした。 インターンシップに参加した経緯 私はフィッシングサイトの検出について研究しているのですが、提案手法の有効性を評価するために本物のフィッシングサイトにアクセスして情報収集をすることがあります。 フィッシングサイトの情報源をX(旧Twitter)やフィッシングメール、SMSなどとしており、フィッシングサイトの情報を収集する際に、 Metemcyberアカウント により発信される情報を閲覧したことがありました。 Metemcyber とは、「セキュリティ運用の健全化を提供することを目標として活動しているプロジェクト」 2 で、 以前のインターンシップ でも研究開発が行われていました。 特にXでは、次の投稿のようなフィッシングサイトに関する情報が発信されています。 🚨⚡ #Phishing #フィッシング詐欺 (🇯🇵) Brand: #税務署 #国税庁 IP: 🌍 43.133.6[.]103 (ASN:AS132203) URL: 🎣 hxxps://amaglobal.cn/ 🎣 hxxps://canchuan.cn/ 🎣 hxxps://exterminator.cn/ 🎣 hxxps://hideandseek.cn/ 🎣 hxxps://netwalk.cn/ H/T to Team NA4Sec pic.twitter.com/YpZPMP3SGN — Metemcyber (@Metemcyber) 2024年10月2日 このように情報発信するために、どのようにフィッシングサイトの情報を収集・精査し、発信しているのか興味があり、インターンシップへの参加を希望しました。 また以前のインターンシップ体験記から、フィッシング詐欺に関する業務について体験できると知ったため、さらに意欲が向上しました! 体験内容の概観 今回のインターンシップでは、大きく分けて4種類の業務に参加させていただきました。 脅威調査(Cobalt Strikeとその悪⽤) 脅威探索(Cobalt Strike C2サーバに関して) 脅威情報配信(フィッシングサイトに関して) フィッシングキット分析 脅威調査、脅威探索、脅威情報配信については今回は割愛し、 「フィッシングキット分析」 について詳細に紹介させていただきます。 3 フィッシングキットの詳細分析 まずフィッシングキットについて簡単に説明すると、 「フィッシングサイトお⼿軽作成ツール」 です。 フィッシングキットを利用することで、攻撃者は簡単にフィッシングサイトを用意できます。 このようなフィッシングキットを分析することで、フィッシングサイトのサーバ側での処理や設定ファイルに記載されている内容、さらに攻撃者に関わる情報(窃取した情報の送信先、コードに残したコメント)を入手できる可能性があります。 今回は実際に使用されていたフィッシングキットについて詳細に分析し、その分析レポートを作成することになりました。 以前のインターンシップ体験記 でもフィッシングキットの分析を扱ったものがありましたが、本体験記ではソースコードレベルでの個別機能把握とそれを踏まえた検知の検討に焦点をあてて紹介します。 今回、分析時の観点として以下について教えていただきました。 騙っているブランドはなにか どんな情報を窃取しようとしているのか どのような処理があるのか 検知に活用できそうな情報 攻撃者に関係していそうな情報 構成ファイル 分析対象のフィッシングキットは、NA4Secチームが過去に収集して保存していたzipファイルのうちの1つです。 今回のインターンシップでは、NA4Secのアナリストとして自身が入手したフィッシングキットについて分析レポート作成を依頼されたというシナリオベースで分析に取り組みました。 このzipファイルを展開すると、下図のようにいくつかのファイルとフォルダが確認できました。 分析方法 VS Code でソースコードを読むことで処理を追っていきました。 以下にその手順や結果を記載します。 騙っているブランドについて まず⾃分は、フィッシングキットに含まれる画像からブランドを推測できるのではと考え、画像を探してみました。 すると、「/assets/img」に画像ファイルが存在し、その⼤半は某大手ECサービスに関連しているようでした。 このため、騙っているブランドは某大手ECサービスであると最初は判断していました。 しかし、発見した画像ファイルがどのように呼び出されているのかは不明でした。 そこで「index.php」がまず呼び出されるのではないかと考え、そこから処理を追ってみると、呼び出されているのは「ap/signin.php」や「_ap/signin.php」でした(今回、「ap」はMobile用、「_ap」はDesktop用に用意されたディレクトリ)。 どちらも確認するとログインページのようであり、ともにtitleタグの値に某交通系サービスの名前が記載されていました。 以上から、今回のフィッシングキットによって作成されるフィッシングサイトが騙るブランドは某交通系サービスであると判断しました。 またフィッシングキットに複数のブランド情報があったことから、フィッシングキットは再利用されていること、画像だけ確認して騙っているブランドを判断するのではなく処理を⼀つずつ追うことが重要であることを学びました。 どんな情報を窃取しようとしているのか phpファイルの処理を確認していくと、以下のような情報などを窃取しようとしていることが分かりました。 登録しているメールアドレス、パスワード 名前 生年月日 携帯電話番号 カード番号 ワンタイムパスワード 入力フォームに上記のような情報などの入力を求める記述が存在したため、phpファイルを読むだけで窃取しようとしている情報が判明しました。 どのような処理があるのか クローキング が行われていることが分かりました! クローキングについて 以前のインターンシップ体験記 を参考に紹介すると、「攻撃者が標的とする対象には悪性の挙動を示し、対象以外には悪性でない挙動を示すようにする処理」です(体験記により詳細に記述されていますので、ぜひご覧ください!)。 自身の収集経験からも、最近のフィッシングサイトではよく行われている処理だと思います。 本フィッシングキットでもクローキング処理がphpファイルで確認できました。 次の図の処理では、$bannedに格納されている⽂字列がアクセスを試みるUser Agentの文字列に含まれている場合、__exit()関数によりフィッシングページを非表示にする処理が行われていました。 また、 ipregistry のAPIが利用されていました。 次の図はAPIを利用するためのURLが作成されている箇所を抜粋したものです。 ipregistryのAPIによりフィッシングサイトへのアクセスを試みるIPアドレスに関する情報が取得され、取得した国情報などによるクローキングが行われていました。 クローキング処理以外にも、 窃取したデータの送信処理 も発見しました。 次の図は、データ送信に利用されたと思われる関数です。 $msg には窃取したデータが格納されており、窃取したデータはTelegramのAPIを利用した送信処理が行われていました。 本フィッシングキットでは、 file_get_contents により API が利用されていました。 以上のような処理の分析により、データ送信処理や、普段フィッシングサイトの情報収集時に自身もふれていたクローキング処理がどのように実装されているか知ることができました。 検知に活⽤できそうな情報 「この情報に注⽬すれば、フィッシングサイトと判断できるのではないか」という情報を探しました。 今回は3つほど紹介します。 敬体と常体の混合 :可能性低 フィッシングサイトで⾒られるおかしな⽇本語表現に着⽬しました。 敬体とは「です」「ます」、常体とは「だ」「である」のような語尾で終わる文体です。 フィッシングサイトの中には上図のように敬体と常体が不自然に混ざった文章が登場することがあります。 しかし、おかしな⽇本語表現は正規サイトでも存在するため、フィッシングサイト検知の根拠としては弱いです。 コピーの痕跡 :可能性高 正規サイトのページを保存した痕跡らしきものがフィッシングキットのコード中に残っていました。 通常、正規サイト(特に正規ログインページ)に他サイトからコピーしてきた痕跡があるとは考えにくいので、検知に活⽤できると判断しました。 urlscanによる調査 :可能性高 インターンシップでは、urlscanによる調査方法について指導していただきました。 urlscan とは、指定したURLのスキャンを実行し、スキャンしたURLが安全かどうかなどの情報を確認できるサイトです。 urlscanによりフィッシングサイトを構成するファイルのハッシュ値を確認すると、同様のハッシュ値を持つ、フィッシングサイトと思われるサイトのスキャン結果を得ることができました。 このことから、既知のフィッシングサイトを構成するファイルのハッシュ値を検知に活用できると判断しました。 ただし、一部のハッシュ値を確認すると、正規サイトのスキャン結果が多く得られることもありました。 この理由として、以下の2点が考えられると教えていただきました。 対象ファイルがフィッシングサイトにも正規サイトにも存在するから クローキングによる正規サイトへのリダイレクトもスキャンされ、正規サイトのファイルも記録されるから そのため、検知にハッシュ値を利⽤する場合には⼀つのリソースのハッシュ値だけでなくできるだけ全てのハッシュ値を確認する必要があると考えます。 urlscanによる調査の詳細ついては、 以前のインターンシップ体験記 で紹介されていますので、ぜひご覧ください! 今回の経験から、urlscanの活用方法について知ることができました。 攻撃者に関係していそうな情報 「Capricorn.ini」ファイルに攻撃者に関係していそうな情報が確認できました。 例として、情報送信に使われたであろうTelegramのChatのID情報や、ipregistryのAPIを利用するためのkey情報などが存在しました。 このように、フィッシングキットを確認するだけで攻撃者が利用したサービスの情報についても知ることができました。 おわりに 本インターンシップのカリキュラムで、私は初めてフィッシングキットの分析に挑戦することになりました。 一つ一つの処理を地道に追っていく作業だったので時間がかかりましたが、とても楽しく有意義な経験となりました! 具体的には、フィッシングキット分析関連の業務に多く時間を割いてくださったことで長時間分析に挑戦でき、詳しく知らなかった外部APIサービスについて詳細に調査でき、またメンターの益本さんから知識共有もしていただきました。 加えて分からない箇所についてはアドバイスをいただき(例:urlscanによる調査)、そのアドバイスをもとに調査を行えたことなどから、自身の研究分野であるフィッシングサイトについて知らなかった挙動や検出方法について学ぶことができました。 さらに分析により普段収集していたフィッシングサイトの挙動(例:クローキング)を裏付けることができ、User AgentやIPアドレスを工夫するなど今後どうフィッシングサイトに対応するかについて知見を広げる機会となりました。 今回のインターンシップで得た知識を自身の研究活動の一環であるフィッシングサイトの情報収集に活かしたいです。 上記で紹介した業務以外にも、対面とリモートの両方での業務体験や、NA4Secチームが関わるイベントにも多数参加させていただき、現場の雰囲気も充分に理解できました。 興味のあったフィッシングサイトに関する業務(特にフィッシングサイトの情報収集・精査方法)についても座学や業務体験を通して経験できました。 先述したフィッシング詐欺に関する学びはもちろん、昼休みや夜に行われるイベントでも技術的知識を共有し、チームメンバーの成長を促そうとする現場の上昇志向はぜひとも真似すべきものだと思いました。 現在の自分は研究室に所属しているので、今後研究室メンバーへ色々な知識共有を行うことで、上昇志向的な姿勢を身に着けたいです。 このように、技術面ではフィッシングサイトに関する多くの知識を得たこと、非技術面では現場の積極的な姿勢を学ぶことができたことから、インターンシップへの参加目的を達成できたと思っています。 本当にありがとうございました! 最後に、自分のインターンシップに関わってくださった皆さま、特に上長の神田さん、メンターの益本さん、色々なお世話をしてくださった鮫島さんには本当に感謝しています。 繰り返しになりますが、ありがとうございました! NA4Secに関する記述は「 BSides登壇のBサイド ~なんで、私が海外セキュリティカンファレンスに!?~ 」という記事を参考にしました。最近のNA4Secに関する活動も執筆されていますので、ぜひご覧ください! ↩ 引用元は「 日本を狙ったフィッシングサイトの情報配信はじめました 」という記事です。XでのMetemcyberアカウントによるフィッシングサイトの情報発信について紹介されています。 ↩ 脅威調査・脅威探索については、 以前のインターンシップ体験記 が参考になると思います!ぜひご覧ください。 ↩
アバター
NTTコミュニケーションズ(以下、NTT Com) イノベーションセンター(以下、IC)の加藤( @katomasa23 )です。 個人的にちょうど良いタイミングということもあり、新卒でエンジニアを始めて約3年半を振り返り、考えたことをまとめたいと思います。タイトル的に退職エントリみたいですが、退職しません、というお断りだけ最初に入れておきます。 自己紹介 私のキャリアの話を書いていくので、最初に背景情報として自己紹介させてください。 2021年4月にNTT Comに新卒入社 大学は文系学部(商学部)出身 現在のメイン業務はローカル5GやWi-Fiなど各種無線技術を用いたユースケースの開拓 この記事が、文系・新卒でエンジニアというキャリアを考えている就活生や、NTT Com含め、IT系企業に就職が決まり、希望部署や職種に悩んでいる方の参考になれば幸いです。 文系出身でなぜエンジニアへ? 理由を書くだけで1つの記事として完結できそうなテーマではありますが、なるべく簡単に振り返ってみます。 NTT Comインターンシップへの参加 私は就職活動の頃、幅広い業界(IT・通信・金融・商社・マスコミ)を見ていました。その中でNTT Comに関心を持ったのは、経理の専門職エントリーができるからでした。先述した通り、私は商学部出身で、簿記2級も取得していたことから、経理の仕事に興味がありました。そこでNTT Comのインターンシップに第1希望経理・第2希望営業で応募しました。 インターンシップでは第1希望の経理ではなく、第2希望の営業の仕事を経験しました。そこではICTでお客さまの可能性を引き出せるのではないか?というやりがいに惹かれ、非常にワクワクしたのを覚えています。 また、インターンシップ中にIOWN構想についても聞き、「 日本からゲームチェンジを起こしたい! 」という思いを持って本選考への応募を決意しました。 入社までの想い 採用が決まり、2月の内定者面談で初期配属の希望を聞かれました。当時は、IOWNを広める、という思いに一番近そうなのはマーケティングかなと思っていました。ただ、マーケティングをやる前に技術的な凄さやアピールポイントを自分なりに腹落ちさせておきたいという考えもあり、まずはエンジニアとして経験を積みたいと希望を出しました。 また、NTT Comのお客さまは主に法人で、情報システム部など、お客さまの担当者もエンジニアである場合が多いのをインターンシップで知っていました。そのため、将来的に営業をすることになってもエンジニアとしての共通言語を学んでおきたかったという思いもありました。 そして、入社後の初期配属はソリューションサービス部(以下、SS部)で、エンジニアとしての配属が決まりました。 文系・未経験だけれど… 私自身、ITに全く関心がなかったわけではありません。小学校低学年の頃から、帰宅したらPCにずっと張り付いてラジオを聴きながらWikipediaを徘徊するような生活をしていました。小学校高学年ぐらいになると、動画共有サイトが盛り上がってきて、友人と一緒に動画制作をしたり、Podcastを配信したりしていました。また、大学ではR言語を使ったデータ分析も経験しており、文系とはいえ免疫(?)はあった方だと思います。 NTT Com(現在、新卒はドコモグループとして採用し、入社は全員NTTドコモ)は新入社員研修で手厚いICT研修を受けられます。また、私の初期配属部署のSS部では、ネットワークからクラウド、アジャイル開発などの研修を受けました。研修期間中は同期内で自主的に研修テキストの輪読会を実施するなど、結構楽しかったことを覚えています。 SS部での研修後は、ICに10ヶ月間のOJTとして派遣されました。ここで、いいチーム・トレーナーとの出会いがありました。私の能力を上手く見定めて、「この資格はどう?」といった感じでスキルアップするヒントを貰っていました。そのサポートや、社内の資格取得制度も相まって、この3年半で10数個の資格を取りました。(実証実験で1週間出張した週末に応用情報技術者試験を受けたのは今でもいい思い出です。笑) 経験した業務 3年半の間で、私は2つの部署を経験しました。通常はあまりないケースですが、SS部(入社研修)→IC(OJT)→SS部→ICという異動でした。経験した業務の一部を列挙すると、以下のようなものがあります。 他社の協力を得て実施したローカル5Gの実証実験 全国各地でのモバイル計測 自社商材( Arcstar Universal One , Flexible InterConnect )を利用した閉域網からクラウドにアクセス可能な検証網の構築 商用案件の運用自動化開発 グループ内コミュニティイベント( dcc Engineer Day )の運営 社内向け技術広報ページの作成 「全国各地でのモバイル計測」時の写真。画面の反射を抑えるために日傘を使い、不審者味が増した。 見えてきた景色 この3年半、エンジニアとしてキャリアを進める中で悩んだこと、思ったこと、そして次へのアクションを書いていきます。 思い描いていたエンジニア像 皆さんが思い描くエンジニアはどういった人でしょうか? 私はコードをカリカリ書いて、土日は個人開発やハッカソンに勤しむ、そんな人物像を描いていました。 そんな人物像と裏腹に、3年経っても、そうなれていない自分について悩んだ日々もあります。アプリよりも、インフラ寄りの技術を扱う部署だったのもあるかもしれません。また、仕事とは別にやりたいことも多く、土日に個人開発やハッカソンへの参加をしたことはありません。4年目になった今でも、同じ会社のエンジニアの皆さんに限らず、他社のTechBlogで拝見するエンジニアの皆さんの背中は大きく見えます。 では自分はダメなのか? もちろん、エンジニアとしてのキャリアを積み、「スーパーエンジニア」を目指すのはアリだと思います。自分もスーパーエンジニアを目指すんだ!と思い込んだ時期もありましたが、一旦初心に返ってみました。すると、将来はサービス企画やマーケティング、営業といった仕事もしたいという希望を思い出しました。また、自分の性格的に、スペシャリスト型よりもジェネラリスト型のキャリアを望んでいる節もありました。 そこで、まずは元々興味があった情報発信や広報活動に、今の業務から関われないかと考えました。2年目の夏頃から、社内報で自らの部署のアピールをしたり、たまたま見かけたグループ内のエンジニアイベントの運営に手を挙げてみたりしました。環境にも恵まれ、結果として、チーム内外の色々な方々からこの動きを評価していただきました。 「エンジニア×◯◯」という発想 このように色々と動く中で、自分なりのエンジニア像を言語化できるようになってきました。それは、 エンジニアとしての技術理解を、情報発信や広報活動という自らの興味関心と組み合わせる というものでした。つまり、エンジニアとして技術の成果物を出すだけでなく、自分の得意分野や興味関心と組み合わせて、「エンジニア×何か」という複数の軸を持つという考え方です。 自分の中でこの方向性をイメージし始めてからは、何をすべきか?という迷いが減ってきました。今年は、今携わっている無線技術の社内向け広報ページをPJメンバーと共に作成する営みを通して、このエンジニア像に一歩近づくことができました。 別のことにトライしてみる エンジニアとして進んできた約3年半。 「新しいことを学んで身につけていくゲーム感覚」や、「未経験のことをする中で自分の強みを認識して生きる術を見つけること」、「目標を持って進むことの大切さ」など、ここでは書ききれないほどの学びを得ながら、エキサイティングな日々を送ってきました。 そんな中、「日本からゲームチェンジをしたい!」という入社当時の初心を思い返し、技術開発から、実際のお客さまにより近い立場での仕事に挑戦したいと思うようになりました。年明けの1月からはドコモグループ内で異動し、エンジニアとしての技術知識を活かしながら、ドコモのベニュービジネス 1 に携わる仕事をする予定です。 まとめ 写真やイラストがほとんどない記事でしたが、最後までお読みいただきありがとうございました!異動先でも何か発信するかもしれないので、見つけたら「あ、あの時の」と思い出していただけると幸いです。 スタジアムやアリーナ全体の運営ビジネスのこと。詳しくはリンク先を参照。 https://information.nttdocomo-fresh.jp/career/smart_life/service_list/venue/ ↩
アバター
この記事は、 NTT Communications Advent Calendar 2024 25日目の記事です。 はじめに プロダクトオーナーへのジョブチェンジの経緯 準備期間 稼働の移行 プロダクト全体像の把握 書籍による学習 引き継ぎとステークホルダーの理解 研究チームとの連携 本番期間 初期のフィードバック Howの介入を避けるための工夫 スプリントゴールの設定 開発者のモチベーション促進 開発者との協力体制 おわりに はじめに イノベーションセンターの杉本(GitHub: kaisugi )です。 私は現在、ノーコードAIモデル開発ツール Node-AI のプロダクト開発に携わっています。Node-AI は「AI を使って自社の課題を自分たちで解決できる会社を1社でも増やす」ことをビジョンに、スクラムによる内製開発を進めているプロダクトです。Node-AI の開発体制や技術スタックについては、Engineers' Blog の過去の記事でもいくつか紹介していますので、ぜひ以下の記事も合わせてご覧ください! engineers.ntt.com engineers.ntt.com engineers.ntt.com 今年度からの新たな取り組みとして、岩手大学と共同で、Node-AI を活用した「データサイエンス実践基礎」講義を開始しました。私も講師として、「第4回: 特徴量エンジニアリング」と「第8回: 生成AI」 1 の講義を担当しています。 www.ntt.com さて、私は新卒入社以来 Node-AI に開発者として携わってきましたが、最近、開発者からプロダクトオーナー(PO)へジョブチェンジしました。本記事では、元々開発者だったメンバーがプロダクトオーナーを担当してからの振り返りを紹介したいと思います。 プロダクトオーナーへのジョブチェンジの経緯 まず、なぜ開発者からプロダクトオーナーへのジョブチェンジを決めたのかお話しします。 私は開発者として Node-AI に携わる中で、エンジニアリングそのものよりも、AI を活用したビジネスをどうすれば上手く成功させられるかという部分に関心が移っていきました。特に昨今の生成 AI ブームで AI のビジネスへの適用範囲がさらに広がり、また同時に、エンジニアリングそのものが GitHub Copilot などの AI ツールに侵食され始めています。 エンジニアリングにおいて取り立てて強いスキルがない自分のキャリアとしては、AIのビジネス適用について頭を使う時間を増やした方が有益なのではないかと考え始めていました。そのような中で、先月にチーム体制の変化があったため、それに合わせて手上げでプロダクトオーナーを担当することにしました。 とはいえ、私はこれまでプロダクトオーナーを経験したことがなく、始めるまでは不安も当然ありました。特に、以前のプロダクトオーナーは強いオーナーシップでチームを牽引していたため、自分がうまく引き継げるのだろうかという点が心配でした。そのような不安を和らげるために、十分な準備期間を設けることにしました。 準備期間 稼働の移行 プロダクトオーナーは開発者とは全く異なるスキルが必要な仕事です。例えば、プロダクトオーナーはユーザーのフィードバックに毎日耳を傾けながら、プロダクトの成長戦略や開発の優先順位を考え、意思決定を行う必要があります。そのため、いきなり仕事を開発者からプロダクトオーナーに100%切り替えるのは難しいでしょう。 私の場合、プロダクトオーナーになる直前の2スプリント程度は、開発者としての稼働を段々と落としていくことにしました。 プロダクト全体像の把握 開発をしない代わりに浮いた時間で、プロダクトの全体像の把握を改めて自分で行いました。特に念入りに行ったこととして、Node-AI におけるプロダクトの4階層(Core, What, Why, How)を改めて自分の中で整理し、その中で直近行われている開発がどのような価値をもたらすものかを再確認しました。 書籍による学習 以前のプロダクトオーナーに勧められた本の中でも、『 ユーザーストーリーマッピング 』は特に腹落ちする内容が多い本でした。この本の中に「 岩を砕く 」という比喩がありますが、プロダクトオーナーの仕事のあらゆる部分でこの感覚が重要になります。ビジネスサイドにとってのプロダクト開発のストーリー(大きな岩)と、開発者にとってのプロダクト開発のストーリー(小石)は粒度の全く異なるものであり、これらを素早く行き来しながらコミュニケーションを取れることが必要です。 開発者として仕事をしていると、どうしても後者のストーリーにばかり目を向けがちですから、根本的な思考の切り替えが求められました。 引き継ぎとステークホルダーの理解 書籍による座学だけでは難しい部分もあるため、以前のプロダクトオーナーの発言や行動を観察しながら、そのプロダクトオーナーの脳内を自分でもトレースできるように努めました 2 。 プロダクトオーナーになる上では、プロダクトそのものだけでなく、プロダクトの外のさまざまな ステークホルダー についても理解する必要があります。個人的には、この部分が複雑で、一番難しいと感じました。その点において、以前のプロダクトオーナーからは、十分に時間をかけてステークホルダーについて解説していただいたので、大変感謝しています。 研究チームとの連携 Node-AI チーム特有の話として、Node-AI に搭載される技術の要素技術である時系列分析の研究チーム(先端AI数理プロジェクト)が隣で活動している点があります。研究チームは我々のようなスクラムで活動しているわけではないため、研究成果を Node-AI に搭載していくためには一種の調整が必要になります 3 。チーム間の連携の仕方は正直に言って現状ベストなものではなく、試行錯誤の最中であり、プロダクトオーナーから課題を引き継ぐ形になりました。 本番期間 初期のフィードバック プロダクトオーナーを担当し始めてから最初の2スプリント程度は、レトロスペクティブとは別に、スクラムマスターからフィードバックを受ける時間を設けていただきました。自分1人で振り返りを行うと、反省ばかり先に頭に浮かんでしまうものですが、スクラムマスターは客観的にポジティブフィードバックも行なってくれるのでありがたい存在です。個人的には、スクラムマスターからのフィードバックは初期にしっかりもらうと良いと思います。 Howの介入を避けるための工夫 開発者からプロダクトオーナーになる上で一番危惧していたのは、開発者の頃の癖で、開発の細かいHowにまで自分が突っ込みたくなってしまうことでした。機能の詳細や仕様の議論に時間を割くのは、 プロダクトオーナーのアンチパターン の1つです。そのため、プロダクトオーナーになってからは、しきりに「Howは皆さんにお任せする」ということを口癖のように繰り返していました。結果、今のところ、この部分は問題なく進められているように感じます。 スプリントゴールの設定 プロダクトオーナーとして日々難しいと感じているのは、毎週のスプリントゴールに何を立てるか、どんな価値を見せていくかというところです。機能は作れば作るだけいいというものではありません。むしろ、 機能は作った瞬間から負債になる ので、本当に価値をもたらさない限り機能は作らない方が良いです。 一方で、開発者からすると、新機能を作るPBIではなく細かな修正やアップデートのPBIばかりこなしていると、プロダクトが前に進んでいるのか分かりづらく、モチベーションを上げづらいという問題もあります。そのためプロダクトオーナーは、今はこういうことに注力している、だからこのスプリントゴールを立てているのだ、という思想を語り続ける必要があります。 開発者のモチベーション促進 Node-AIの開発チームでは現在、運用系のタスクにこれまで以上にしっかりと取り組んでいくことにモチベーションが向かっています。これは、Node-AI のユーザー数が以前よりも増えており、以前のプロダクトフェーズでは後回しにしていたタスク(例: メトリクス・ログ・トレースの集計や SLO の追跡など)の必要性が高まったためです。 運用系タスクはステークホルダーに価値を直接見せられるものではないので、プロダクトオーナーとして配分には熟慮が必要ですが、なるべく毎スプリントコツコツと積んで開発者の中でも習慣化できるようにしたいと考えています。 開発者との協力体制 私は、PBI の優先順位やその積み方について疑問がある場合、すぐに 開発者に相談する ように心掛けています。これは、引き継ぎの際に、以前のプロダクトオーナーが「開発者の中でも開発の進め方そのものをもっと議論できるようにしたい」と言っていたからです。以前のプロダクトオーナーにはカリスマ性があり、「何でも任せて大丈夫」という信頼感が生まれていた反面、開発者の間で議論があまり行われていなかったことを課題感として持っていたようです。 プロダクトオーナーとして、最終的な責任を持つことは重要ですが、全てを一人で決めるのではなく、開発者が自主的に議論できる雰囲気を作ることも大切だと考えています。もちろん、全てを開発者任せにしてしまうと負担が大きくなり、リファインメントが難しくなることもあるため、適切な線引きは必要です。 おわりに この記事では、開発者からプロダクトオーナーになった私の体験談を赤裸々に紹介させていただきました。当初は不安もありましたが、今は少しずつ走り出せているという感触です。 本記事が、新米プロダクトオーナーとして苦労されている誰かの力になれば幸いです。 それでは皆さん、メリークリスマス! 生成 AI といえば、余談ですが、私は日本語に特化した LLM に関する情報を集めるのが趣味で、「 日本語 LLM まとめ 」という GitHub リポジトリを日々メンテナンスしています。今年は GitHub のスター数が 1,000 を超えたので嬉しいです! ↩ このあたりの引き継ぎの仕方は、チームの方針によって最適な方向があるかと思います。私自身は、まずは以前のプロダクトオーナーの方針を踏襲して進めていくことをスクラムマスターに宣言していました。 ↩ Node-AI というプロダクト起点でストーリーを考えた場合、Node-AI というプラットフォームに、研究成果であるさまざまな AI モデルが搭載されていきます。一方で、Node-AI には適さないが有用な研究成果の場合、研究成果を起点に新たなプロトタイプを作成することもあります。チーム全体でのこれらの活動の進め方の配分をどのように行っていくかは難しい問題であり、マネージャー層の方々が苦労される部分ではあります。 ↩
アバター
この記事は、 NTT Communications Advent Calendar 2024 24日目の記事です。 システムを運用していると日々のアラートメールへの対応の手間を減らしたいと感じることはありませんか? 例えばセキュリティアラートに日々対応している運用者の方は、アラートの中に含まれる誤検知・過検知への対応に負担を感じている方も多くいらっしゃると思います。 この記事では、そのような誤検知・過検知対応の負担を削減するためにサーバーの脆弱性通知メールの一次切り分けを、マイクロソフト社が提供しているローコードツールであるPower Automateを使って自動化した話を紹介します。 はじめに 脆弱性通知メールの一次切り分けを自動化したいと思った背景 作成したPower Automateのフロー フロー作成において大変だった点 NVDのAPIが採用しているCPE(ソフトウェア名やバージョンの識別子)を利用した脆弱性の突合が難しい フローのアクションの実行回数に制限がある フローを作成した結果 まとめ はじめに こんにちは。ソリューションサービス部の牧です。 普段はセキュリティソリューションの開発やプリセールスの業務を行っています。 この記事では、私が所属しているチームで管理しているLinuxサーバーの脆弱性通知メールの一次切り分けを、マイクロソフト社が提供しているローコードツールであるPower Automateを使って自動化した話を紹介します。 脆弱性通知メールの一次切り分けを自動化したいと思った背景 私が所属しているチームでは、検証用にLinuxサーバーを運用しています。社内の規定に従って、ソフトウェアなどで発見された脆弱性の対策状況を管理するシステムにサーバーのOSなどの情報を登録しており、ほぼ毎日2通~5通ほどの新規の脆弱性の通知メールを受信しています。 新規の脆弱性が発見された場合、脆弱性の深刻度に応じて対策完了までの期限が定められているため、その期限までに対策を完了させる必要があります。 そのため定期的に脆弱性通知メールの内容を確認し、サーバーにログインして脆弱性の発見されたソフトウェアがインストールされているかどうかを確認して、必要であればパッチ適用を実施しています。 脆弱性通知メールの中にはサーバーにインストールしていないソフトウェアのものも多く含まれており、毎回サーバーにログインして切り分けをするのは大変なので、Power Automateを活用することでこの確認作業の手間を減らしたいと考えました。 作成したPower Automateのフロー 作成したPower Automateのフローの処理の流れは以下の通りです。 脆弱性通知メールを読み取る メール本文からCVE-IDを抜き出す CVE-IDが含まれない場合、「CVD-IDなし」フォルダにメールを振り分ける Canonical社が公開しているUbuntu Security APIからCVE-IDを使って脆弱性のあるパッケージ名とバージョンを取得する 予め保存しておいたインストール済みのパッケージ一覧に脆弱性のあるパッケージがあるか突合する パッケージ名とバージョンがどちらも一致した場合、「パッチ適用が必要」フォルダにメールを振り分ける パッケージ名のみ一致した場合、 「パッチ適用済み」フォルダにメールを振り分ける パッケージ名とバージョンがどちらも一致しない場合、「該当なし」フォルダにメールを振り分ける 実際に作成したPower Automateのフローは以下の通りです。 フロー作成において大変だった点 フローの作成において大変だった点は以下の2点です。 NVDのAPIが採用しているCPE(ソフトウェア名やバージョンの識別子)を利用した脆弱性の突合が難しい 当初は脆弱性のあるパッケージの突合にCanonical社が公開しているUbuntu Security APIではなく、NVD(National Vulnerability Database)という最も広く利用されている脆弱性情報データベースのAPIを利用しようとしていました。 NVDでは、脆弱性情報データベース内の脆弱性識別子CVEと結びつけられたCPEという識別子がソフトウェアと脆弱性を突合させるために利用されています。 例えば、Microsoft社のInternet Explorer 8.0.6001 BetaをCPEで表現すると、 cpe:/a:microsoft:internet_explorer:8.0.6001:beta となります。 しかし、一般的に全てのソフトウェアに対して普遍的な識別子は存在せず、ソフトウェアを一意に特定することは難しいと言われています。 OSSのTrivyも、CPEを使わず各ベンダーが出している脆弱性情報を使いマッチングを行っています( 参考 )。 そのため、今回は複雑なスクリプト実行ができないこともあり、CPEではなくaptコマンドで取得できるソフトウェアの名前とバージョンと同じ形式で脆弱性のあるソフトウェアの名前とバージョンを取得できるCanonical社が公開しているUbuntu Security APIを利用することにしました。 フローのアクションの実行回数に制限がある クラウド版の場合のフローの開発は、主に「①フロー作成画面で一連のアクションを設定する」→「②フローを実行してテストする」→「③実行結果を確認してエラーを修正する」→①に戻るという流れで進めると思いますが、開発が進んでアクションの数が増えるに従ってフローのアクションの実行回数をたくさん消費してしまっていたようで、実行回数の制限の80%に到達したところで警告メールが送られてきました( 参考 )。 制限を超えるとアクションの実行が制限されたり、遅くなったりする可能性があるそうなので、制限を超えないように気を付ける必要がありました。 フローを作成した結果 フローを作成した結果、下記の画像のように脆弱性の突合結果に応じて自動でメールのフォルダが振り分けられるようになり、毎回サーバーにログインしたり脆弱性のあるソフトウェアがインストールされているかどうかを確認する必要がなくなりました。 パッチを適用する際にはサーバーにログインする必要はあるのですが、特に誤検知・過検知への対応の手間を減らすことができました。 まとめ 今回はサーバーの脆弱性通知メールの一次切り分けをマイクロソフト社が提供しているローコードツールであるPower Automateを使って自動化した話を紹介しました。 最後までご覧頂き、ありがとうございました!明日の記事もお楽しみに。
アバター
この記事は、  NTT Communications Advent Calendar 2024  23 日目の記事です。 本記事では、防衛や重要インフラなどで利用されることがある、データダイオード(片方向の通信のみを許可する装置)の動作と原理を理解するために、シンプルなデータダイオードを作成します。 具体的には、メディアコンバータ等の手軽に入手できる市販のネットワーク機器を使ってデータダイオードを作成し、実際に動作することを確認します。 データダイオードとは? 想定される利用シーン 可用性を重視するシステムを保護したい場合 機密性を重視するシステムを保護したい場合 データダイオードを作ってみる メディアコンバータ3台を利用したデータダイオード つくってみる 動作確認 光ファイバースプリッターを利用したデータダイオード つくってみる 動作確認 おわりに こんにちは! 最近、データダイオードにはまっている上田です。 普段はOT(制御システム)セキュリティ製品の検証や、NTT Comが内製開発している OsecT の開発に関わっています。 この記事は、市販されているネットワーク機器を利用して、データダイオード(ハードウェア部分)を作れないか試してみたものになります。 あくまでも検証用として作成したものなので、実務レベルのシステムではありません(業務環境で利用したことも、利用する予定も今のところありません)。本記事の情報を参考にされる場合は、自己責任でお願いします。 なお、タイトルに「その1」とつけましたが続編は未定です。筆者のやる気が出たら出せる範囲で出します。 この記事でやること・やらないことは下記のとおりです。 やること ハードウェアの仕組みを利用したデータダイオードの作成 動作確認 やらないこと ソフトウェアの作成 パフォーマンステスト 電子工作 データダイオードとは? データダイオード(Data Diode)は片方向の通信のみ許可(強制)する装置です。 一般に、ハードウェアを利用して片方向通信を強制するものをさすことが多い印象です。 このため、脆弱性や設定ミス、管理者権限の窃取などにより突破される可能性があるファイヤーウォール(FW)などと比べて、(設置方法を間違えなければ)強固なセキュリティを確保できるようです。 ちなみに、データダイオードは、Unidirectional Gatewayと呼ぶこともあるようです。 ただ、場合によってはData DiodeとUnidirectional Gatewayそれぞれ使い分けることもあるようです。 データダイオードとUnidirectional Gatewayの定義は組織によって異なることもあるようですが、アメリカ国立標準技術研究所のOTセキュリティガイドである NIST SP 800-82r3 によると、下記のように定義されていました。 data diode A network appliance or device that allows data to travel only in one direction. Also referred to as a unidirectional gateway, deterministic one-way boundary device, or unidirectional network. 1 unidirectional gateway Unidirectional gateways are a combination of hardware and software. The hardware permits data to flow from one network to another but is physically unable to send any information at all back to the source network. The software replicates databases and emulates protocol servers and devices. 2 上記の定義によると、データダイオードは片方向の通信のみを許可する機器全般のことをさし、Unidirectional Gatewayは、ハードウェアによって片方向通信を強制しつつソフトウェアによって通信相手のデバイスやサーバをエミュレートする機能などを持つ機器のことをさすようです。 実際にWeb上を検索してみると、Unidirectional Gatewayと銘打っている製品は、TCPのようにコネクション型のプロトコルをはじめ、さまざまなプロトコルに対応している製品が多い印象です。 なお、今回作成するのはUnidirectional Gatewayではなく(原始的な?)データダイオードになります。 想定される利用シーン データダイオードが利用される分野としては、防衛や重要インフラなどの分野で使われることが多いようです。 最近の例では、アメリカのマイアミ港のクレーン管理システムを保護するために、データダイオードを導入するようです 3 。 データダイオードの設置方法は、可用性と機密性という観点に着目すると次の2つの場合に分けることができそうです。 可用性を重視するシステムを保護したい場合 1つめの例は、制御ネットワークなど、攻撃されると大きな事故につながる可能性があるネットワークを外部の攻撃から守りたい場合です。 そもそも、他のネットワークと接続しなければ良いのかもしれません。しかし、どうしても重要度の高いネットワークの外にネットワーク経由で情報を送りたいといった需要が発生することもあります。 そのような場合に、FWよりも強固なセキュリティを確保できるデータダイオードを採用することがあるようです。 この例では、可用性を重視するネットワーク外からの攻撃をブロックしつつ、外部へデータを送信することが可能になります。 機密性を重視するシステムを保護したい場合 2つめの例は、重要なデータを保管したり分析するためのネットワークからの情報流出を阻止したい場合です。 こちらも、他のネットワークと接続しなければ良いのかもしれません。しかし、必要なデータは他のネットワークから適宜取得できるようにしたいといった需要が発生することもあります。 このような場合にもデータダイオードを採用することがあるようです。 この例では、機密性を重視するネットワーク外への情報流出をブロックしつつ、外部からのデータ受信が可能になります。 ただ、いずれの場合もただ単にデータダイオードを導入するだけで十分なセキュリティを担保できるわけではないと考えます。たとえば、データダイオードによりネットワークのデータの流れを制限したとしても、ソフトウェアアップデートのために記憶媒体などを利用してデータダイオードによって許可したデータの流れとは逆方向に、データを移動させる必要がある場面などはどうしても出てくると思います。また、保護対象のネットワークが知らないうちに他のネットワークとつながっている可能性や、既存のデータダイオードと新たに導入するデータダイオードを組み合わせると双方向通信が可能になってしまうといったことが無いかなどを確認するといったことも必要になるかと思います。そのため、データダイオードの導入が本当に有効なのかを見極めつつ、記憶媒体の検疫やネットワークの可視化・検知など複数のセキュリティ対策を組み合わせることが重要になると考えます。 データダイオードを作ってみる 前章までは、一般的なデータダイオードに関して説明しました。 この章からは、データダイオードを実際に作ってみます。ただ、あくまでも検証レベルで、実用する際に必要な機能の実装や検証は行いません。 今回は、先行事例を参考にしながら自宅のネットワーク機器を利用して作成を試みます。 メディアコンバータ3台を利用したデータダイオード 1つめの自作データダイオードの先行事例としては、Arnaud Soullié氏らによって2016年のBSides Las Vegas等で発表された DYODE (Do Your Own Diode) があります 4 。 DYODEはDYODE v1とDYODE v2の2つのバージョンがあるようです。v2はフォトカプラを利用しており、電子工作の必要があります。対して、v1はメディアコンバータを利用しており、手軽に作ることができそうです。 そこで、まずはDYODE v1を参考にデータダイオードを作ってみます。 つくってみる 用意したもの下記のとおりです。 メディアコンバータ(DN5810SG2E)3台 LC-LCケーブル:2本 Raspberry Pi 4 Model B 8GB:2台 その他周辺機器:電源、LANケーブル等 配線は下記のようになりました。 DYODE v1と同じように、送信側メディアコンバータINの発光(TX)ポートと、受信側メディアコンバータOUTの受光(RX)ポートを光ケーブルで接続します。 この状態では、受信側のメディアコンバータOUTはリンクアップしますが、送信側のメディアコンバータINはリンクダウンしたままになります。 そこで、送信側のメディアコンバータINの受光(RX)ポートと3台目のメディアコンバータNCの発光(TX)ポートを接続します。こうすることで、3台目のメディアコンバータNCから送信用メディアコンバータINに信号が送られ、送信側メディアコンバータINは対向機器が接続されたと判断し、リンクアップします。 下記の画像は、実際に自宅の壁に設置した際の様子です。 余談ですが、電源やスイッチ、Raspberry Pi、メディアコンバータをDINレールに固定するためのパーツや、DINレールをピクチャーレールに固定するためのパーツは、FreeCADと3Dプリンタを使って自作しました。FreeCADは最近大幅にアップデートされ、以前よりも使いやすくなっているようなので近々アップデートして使ってみたいと思っています。 動作確認 下記の送信デバイスと受信デバイスの双方から、お互いにpingコマンドを打ってみます。 下記画像は、実際にpingコマンドを実行した際のCLIの様子です。 左の上下2つのCLIが送信デバイス(pi4b-8gb-exp01)、右の上下2つのCLIが受信デバイス(pi4b-8gb-exp02)のものになります。 上部にpingコマンドの実行結果、下部にtcpdumpコマンドの実行結果が出力されています。 下部のtcpdumpコマンドの実行結果を確認すると、pingコマンドによる受信デバイスへのARP要求パケットは正常に届いていることが分かります。 対して、受信デバイスからのARP応答パケットやICMPエコー要求パケット、ARP要求パケットは送信デバイスに届いていないことを確認できます。 これにより、データダイオードとして正常に機能していることを確認できました。 パケットの流れを整理すると下記のようになります。 ちなみに、tcpdumpコマンドの出力結果に表示されているARPパケットのサイズ( length )が送信時は28なのに対して、受信時は46と増えていますが、こちらはEthernetの仕様(Ethernetフレームのデータ部分は最小46byte)を満たすためにパディングが追加された結果と思われます。 光ファイバースプリッターを利用したデータダイオード DYODE v1は手軽に構築できるのですが、メディアコンバータを3台用意しなければならないというデメリットがあります。 そこで、このデメリットを解消する方法が無いかと、データダイオードについて調べたところ、 OSDD というオープンソースプロジェクトを見つけました。 OSDDはデータダイオードの作り方が複数用意されているようです。複数ある作り方の1つに、光ファイバースプリッターを利用する方法がありました 5 。 こちらの方式は、光ファイバースプリッターさえ用意できれば手軽にデータダイオードをつくることができそうです。そこで、今回はこちらの方法を試してみます。 つくってみる 用意したもの下記のとおりです。 メディアコンバータ(DN5810SG2E)2台 1対2光ファイバースプリッタ―:1本 Raspberry Pi 4 Model B 8GB:2台 その他周辺機器:電源、LANケーブル等 配線は下記のようになりました。 参考文献と同じように、送信側メディアコンバータINの発光(TX)ポートと、光ファイバースプリッターを接続します。そして、2つに分岐したケーブルを各メディアコンバータの受光(RX)ポートに接続します。 こうすることで、送信側メディアコンバータINと受信側のメディアコンバータOUTの両方がリンクアップします。 下記の画像は、実際に自宅の壁に設置した際の様子です。 動作確認 下記の送信デバイスと受信デバイスの双方から、お互いにpingコマンドを打ってみます。 下記画像は、実際にpingコマンドを実行した際のCLIの様子です。 左の上下2つのCLIが送信デバイス(pi4b-8gb-exp01)、右の上下2つのCLIが受信デバイス(pi4b-8gb-exp02)のものになります。 上部にpingコマンドの実行結果、下部にtcpdumpコマンドの実行結果が出力されています。 下部のtcpdumpコマンドの実行結果を確認すると、pingコマンドによる受信デバイスへのARP要求パケットは正常に届いていることが分かります。 対して、受信デバイスからのARP応答パケットやICMPエコー要求パケット、ARP要求パケットは送信デバイスに届いていないことを確認できます。 これにより、データダイオードとして正常に機能していることを確認できました。 メディアコンバータ3台を利用した DYODE v1 との差分は、送信デバイス側で2倍のARP要求パケットが観測されている点です。これは下記動画のように、スプリッタ―を経由して送信したパケットが再度、送信デバイス側に送られてくるためです。 このため、同一のブロードキャストドメインに「メディアコンバータIN」が2台以上存在してしまった場合など、 構成によってはブロードキャストストームが発生してしまいます(止まって困るようなネットワーク機器には接続しないことをおすすめします) 。 なおこちらもEthernetの仕様により、tcpdumpコマンドの出力結果に表示されているARPパケットのサイズ( length )が送信時は28なのに対して、受信時は46とパディング分が増えています。 おわりに 最後まで読んでくださりありがとうございました。 今回は、メディアコンバータと光ファイバースプリッタ―を利用したデータダイオード(ハードウェア部分)を作ってみました。 動作がシンプルなだけに使いどころが難しいデータダイオードですが、自宅ネットワークに導入するなどして遊べたらなと考えています。 もし機会があれば、ソフトウェアの部分まで踏み込んだ続編を(可能な範囲で)書きたいと思います。 それでは、明日のアドベントカレンダーもお楽しみに。 NIST SP 800-82r3 161頁 より。 ↩ NIST SP 800-82r3 168頁 より。 ↩ Waterfall社のニュースリリース「 Waterfall and GoCloud Forge Powerful New Partnership to Secure North-America’s Largest Maritime Port 」より。 ↩ 発表の様子(YouTube): DYODE: Do Your Own DiodE for Industrial Control Systems - AryKokos, Arnaud Soullie ↩ OSDD: Example data-diode hardware setups ↩
アバター
この記事は、 NTT Communications Advent Calendar 2024 22日目の記事です。 こんにちは、イノベーションセンターの鈴ヶ嶺です。普段はAI/MLシステムに関する業務に従事しています。 本記事では、LLMのRetrieval Augmented Generation(RAG)などで用いられる近似最近傍探索(ANN)手法の1つとして最近注目されているDiskANNについて紹介します。 DiskANNはbillionクラスの大規模なデータセットに対してスケーラブルに機能し、SSDなどのDiskを利用可能なことからコスト効率の良い点が特徴です。 本記事ではまず、グラフベースの近似最近傍探索と従来手法の課題点について説明します。次にDiskANNについて、中核となるアルゴリズムであるVamana AlgorithmやDiskへのデータ保存の詳細、検索方法、利用方法について説明します。さらに、DiskANNベースの手法を採用しているクラウド・ベクトルデータベースベンダーの対応状況を紹介します。 グラフベースの近似最近傍探索について DiskANN Vamana Algorithm Diskへのインデックス 派生手法 FreshDiskANN Filtered-DiskANN 利用方法(diskannpy) クラウド・ベクトルデータベースベンダーの対応状況 Azure DiskANN Vector Index in Azure Database for PostgreSQL DiskANN for Azure Cosmos DB Timescale pgvectorscale Zilliz Milvus Weaviate まとめ グラフベースの近似最近傍探索について 近似最近傍探索は与えられた検索対象のクエリから、類似される(距離が近い)データを効率的に見つけることが目的です。 その中で、グラフベース手法はデータセットをノードとエッジにより構成されたグラフで表現して探索するものになります。 例えばグラフベース手法で有名なHierarchical Navigable Small World(HNSW) 1 は、次のように階層的なグラフ構造となります。 上層では疎なグラフを探索して、徐々に階層を重ねることでより密なグラフの探索をします。 引用: https://arxiv.org/abs/1603.09320 このような階層性や探索におけるランダムアクセス性の要件からHNSWのグラフはin-memoryに保存することが望まれます。 一方で大規模なデータセットをメモリに展開するのはコストが高く、利用が難しい状況にあります。 また、その他グラフベース手法の詳細については説明を割愛しますが、以下の松井先生の資料などがわかりやすいため補足としてご覧いただければと思います。 speakerdeck.com DiskANN HNSWなどのグラフベース手法の課題を背景に、Microsoft Researchの研究チームはbillionクラスの大規模なデータに対してスケーラブルに機能し、さらに低コストなSSDなどのDiskを用いることが可能な手法であるDiskANNを考案しました。 この手法は2019年のNeural Information Processing Systems(NeurIPS)で採択されています。 2 実装は、オープンソースとして公開されています。 https://github.com/microsoft/DiskANN コアはC++で実装されており、Pythonの diskannpy からも利用可能です。 一部Rustによる実装も進められていますが、コミッターの回答からは明確なロードマップがあるわけではないようです。 We do not have a strong roadmap yet. https://github.com/microsoft/DiskANN/issues/409 Vamana Algorithm このセクションではDiskANNのグラフ作成アルゴリズムであるVamana Algorithmについて説明します。 Vamana Algorithmはグラフの走査を高速化するためのもので、そこには2つのアルゴリズムが寄与しています。 Vamanaのグラフはフラットな単一のレイヤーからなるグラフで構成されます。 最初にランダム接続された初期グラフを改善することによってクエリを探索可能なグラフとして構成します。 引用: https://proceedings.neurips.cc/paper_files/paper/2019/file/09853c7fb1d3f8ee67a61b6bf4a7f8e6-Paper.pdf Algorithm 1のGreedySearchでは、入力されたクエリにより距離が近いノードを探索します。 始点ノードであるsから、クエリx_qにより近い隣接ノードを探索して候補に加えて、さらにその候補から隣接ノードを探索するというような形で、よりクエリx_qとの距離を縮める方向で貪欲的に探索を進めます。 探索中に候補数がL以上になった場合、上位Lのノードだけ残して探索を進めます。 この処理は、後に説明するAlgorithm 3のグラフ構築時にも、クエリの検索時にも利用されます。 引用: https://proceedings.neurips.cc/paper_files/paper/2019/file/09853c7fb1d3f8ee67a61b6bf4a7f8e6-Paper.pdf Algorithm 2のRobustPruneではノードのエッジの刈り込みを行いグラフ探索の効率を向上させます。 まず、特定のノードpを起点として、候補ノードの中から最も距離が近いノードp*を選択し、pとp*の間にエッジを新規に追加します。 次に候補から任意のノードp'において、追加されたノードp*からp'の距離をパラメータαの乗数で制御して、特定のノードpからp'の距離よりも小さい場合、p'を削除します。 この処理で、ある程度疎なグラフとなり、長距離のエッジも形成されます。 最終的にノードあたりのエッジ数はR個になるように調整されます。 上図に、RobustPruneにおけるパラメータαによる違いを例示します。 α=1の場合、ノードp'は削除されます。一方、α=2の場合、削除されず長距離のエッジ追加に貢献します。 ちなみに、HNSWやNSG 3 では、この調整可能なパラメータαを持っておらず、暗黙的にα=1を利用しているため長距離のエッジが作成されにくい傾向にあります。 引用: https://proceedings.neurips.cc/paper_files/paper/2019/file/09853c7fb1d3f8ee67a61b6bf4a7f8e6-Paper.pdf グラフ構築のインデックス処理はAlgorithm 1, 2を組みわせて行われます。 まず、ランダムに設定されたノードをデータセットのmedoid(全てのノードからの距離の合計が最小)からGreedySearchを行い探索で訪れたノードを記録します。 それらのノードは長距離のエッジ構築を促進する目的で、次のRobustPruneの候補ノードとして活用され、エッジの刈り込みがされます。 これらの処理を行いエッジが刈り込まれて、探索の効率が向上します。 次の画像は、実際にエッジが刈り込まれる様子を図示されたものになります。 1回目にα=1として処理され、次の2回目に長距離エッジを導入するためにユーザ定義のα>1で処理されます。 引用: https://proceedings.neurips.cc/paper_files/paper/2019/file/09853c7fb1d3f8ee67a61b6bf4a7f8e6-Paper.pdf Diskへのインデックス billionスケール規模のデータセットにおいて、例えばfloat32の100次元データとして考えるとインデックス構築時には4Byte x 100 x 1000000000 = 約373GBほど必要となります。 先述の通り、これをメモリに展開することはコストが高く、小規模な計算環境では現実的ではありません。 DiskANNではクラスタリングによる分割によってこの問題の解決を図ります。 k-meansを利用してk個(例 k=40)のクラスタに分割して各データセット点はl個(例 l=2)のクラスタに属するように設定します。 次に、各クラスタに割り当てられたデータセットでVamamaインデックスを構築します(データ数はNl/kとなり、例 4Byte x 100 x 1000000000 x 2 / 40 = 約 18.6GB)。 最終的に各クラスタで構築したグラフのエッジを単純に結合させて1つのグラフにマージします。 最終的に作成したグラフを全てメモリに載せることは難しいので、DiskANNではProduct Quantization 4 を利用した圧縮ベクトルをメモリに格納して、フル精度のグラフはSSDなどのDiskに保存します。Diskへの保存のレイアウトは各ノードiについてフル精度のベクトルとR個の近傍ノードのIDを記録します。その際にノードの次数がRより小さい場合は0埋めしてオフセットの計算を容易にします。 クエリ検索時には圧縮ベクトルを用いてまず大まかな計算をして、実際の距離を計算してランク付けする処理はDiskにあるフル精度のものを利用します。検索の様子は次のMicrosoftが公開している動画が非常にわかりやすく表現されているのでおすすめです。 www.youtube.com 派生手法 DiskANNを提案したMicrosoft Researchの研究チームはDiskANNを改良した派生を活発に研究しています。 FreshDiskANN DiskANNはランダムな初期グラフから刈り込みをすることでグラフを生成するため、新しいデータを追加して再インデックス化するコストがかかっていました。 その課題に対してFreshDiskANN 5 では、リアルタイムにデータを更新してインデックスに反映可能な手法を提案しています。 Filtered-DiskANN Filtered-DiskANN 6 は日付、価格帯、言語などでラベルによってフィルタリングされたインデックス内の探索を効率化した手法を提案しています。 利用方法(diskannpy) DiskANNのPythonでの実装、 diskannpy の利用方法は次のようになります。 sample_diskann.py import numpy as np import diskannpy as dap from pathlib import Path rng = np.random.default_rng( 1234 ) rows = 512 dim = 100 data = rng.random((rows, dim), dtype=np.float32) index_directory = "index" Path(index_directory).mkdir(exist_ok= True ) # Build Disk Index dap.build_disk_index( data=data, distance_metric= "l2" , index_directory=index_directory, graph_degree= 16 , complexity= 32 , vector_dtype=np.float32, search_memory_maximum= 0.00003 , build_memory_maximum= 1 , num_threads= 0 , pq_disk_bytes= 0 ) index = dap.StaticDiskIndex( distance_metric= "l2" , vector_dtype=np.float32, index_directory=index_directory, num_threads= 16 , num_nodes_to_cache= 10 , ) # Search queries = rng.random(( 5 , dim), dtype=np.float32) identifiers, distances = index.batch_search(queries, k_neighbors= 5 , complexity= 5 , beam_width= 2 , num_threads= 1 ) 実行方法は次のようになり、indexディレクトリにメタデータやインデックスが保存されます。 python sample_diskann.py tree index/ # Diskに保存されたメタデータやインデックス # index/ # ├── ann_disk.index # ├── ann_metadata.bin # ├── ann_pq_compressed.bin # ├── ann_pq_pivots.bin # ├── ann_sample_data.bin # ├── ann_sample_ids.bin # └── ann_vectors.bin クラウド・ベクトルデータベースベンダーの対応状況 このセクションではDiskANNベースのアプローチをとり実装している各種クラウド事業者やいくつかのベクトルデータベースベンダーの対応状況を記載します。 Azure Microsoftで考案された手法であるため、クラウドにおいてはAzureでの利用が先行している印象です。今年2024年のMicrosoft Build 2024やMicrosoft Ignite 2024でAzure Database for PostgreSQL - Flexible ServerとAzure Cosmos DBの対応が発表されました。 DiskANN Vector Index in Azure Database for PostgreSQL 引用: https://techcommunity.microsoft.com/blog/adforpostgresql/introducing-diskann-vector-index-in-azure-database-for-postgresql/4261192 Azure Database for PostgreSQL(Flexible Server)において pg_diskann 拡張を有効化することで利用可能となりました。 次のような例でDiskANNを使用可能です。 -- pg_diskannのextension有効化 CREATE EXTENSION IF NOT EXISTS pg_diskann CASCADE; -- インデックスをdiskannを利用して作成 CREATE INDEX my_table_embedding_diskann_idx ON my_table USING diskann (embedding vector_cosine_ops); DiskANN for Azure Cosmos DB 引用: https://devblogs.microsoft.com/cosmosdb/diskann-for-azure-cosmos-db-now-in-open-public-preview/ Azure Cosmos DBでもDiskANNが利用可能です。Cosmos DBの水平スケーリング機能と相乗効果で多くのクエリをコスト効率を最適化しながら処理することが可能となります。 次のように EnableNoSQLVectorSearch を設定することで利用可能です。 az cosmosdb update \ --resource-group <resource-group-name> \ --name <account-name> \ --capabilities EnableNoSQLVectorSearch Timescale pgvectorscale Timescaleはpostgresql拡張として pgvectorscale をOSSとして公開しています。 内部ではStreamingDiskANNというDiskANNにインスパイアされたアルゴリズムを使用しています。 余談ですがpgvectorscaleはRustでPostgresql拡張を実装する PGRX framework を用いてRustで実装されています。 TimescaleはいくつかDiskANNに関する技術ブログを公開しているため参考におすすめです。 https://www.timescale.com/learn/hnsw-vs-diskann https://www.timescale.com/blog/understanding-diskann Zilliz Milvus Zillizのベクトルデータベース Milvus はDiskANNに対応しています。インデックスタイプを DISKANN と設定することで利用可能です。 https://milvus.io/docs/ja/disk_index.md ZillizはDiskANNに関する技術ブログを多数公開しています。 https://milvus.io/blog/2021-09-24-diskann.md https://zilliz.com/learn/DiskANN-and-the-Vamana-Algorithm https://zilliz.com/blog/diskann-a-disk-based-anns-solution-with-high-recall-and-high-qps-on-billion-scale-dataset Weaviate ベクトルデータベース Weaviate はVersion 1.18からDiskANNベースの処理を組み合わせています。 More specifically, in 1.18 we implemented the solution proposed in DiskANN whereby we combined our HNSW indexing with vectors that have been compressed using product quantization (PQ). 引用: https://weaviate.io/blog/weaviate-1-18-release WeaviateもDiskANNに関する技術ブログを公開しています。HNSWとのRecallやLatencyなども比較検証結果を公開しています。 https://weaviate.io/blog/ann-algorithms-vamana-vs-hnsw まとめ 本記事ではDisk-friendlyで低コストにスケール可能な近似最近傍探索手法 DiskANNのグラフ構築アルゴリズムVamanaやその利用方法を紹介しました。また、各クラウド・ベクトルデータベースベンダーの対応状況を紹介し低コストで社会実装を視野に入れた取り組みが活発化している印象を感じています。大規模な検索システムを検討している方にこちらの内容を参考にしていただければ幸いです。 明日のアドベントカレンダーもお楽しみに。 Malkov, Yu A., and Dmitry A. Yashunin. "Efficient and robust approximate nearest neighbor search using hierarchical navigable small world graphs." IEEE transactions on pattern analysis and machine intelligence 42.4 (2018): 824-836. ↩ Jayaram Subramanya, Suhas, et al. "Diskann: Fast accurate billion-point nearest neighbor search on a single node." Advances in Neural Information Processing Systems 32 (2019). ↩ Fu, Cong, et al. "Fast approximate nearest neighbor search with the navigating spreading-out graph." arXiv preprint arXiv:1707.00143 (2017). ↩ Jegou, Herve, Matthijs Douze, and Cordelia Schmid. "Product quantization for nearest neighbor search." IEEE transactions on pattern analysis and machine intelligence 33.1 (2010): 117-128. ↩ Singh, Aditi, et al. "Freshdiskann: A fast and accurate graph-based ann index for streaming similarity search." arXiv preprint arXiv:2105.09613 (2021). ↩ Gollapudi, Siddharth, et al. "Filtered-diskann: Graph algorithms for approximate nearest neighbor search with filters." Proceedings of the ACM Web Conference 2023. 2023. ↩
アバター
この記事は、 NTT Communications Advent Calendar 2024 21日目の記事です。 本記事では、メンバーそれぞれの個性が強すぎるが故に衝突して空中分解寸前だったチームの状態と、それを解決するツールとして 「わたしたちのウェルビーイングカード」 を活用し、チームの相互理解が進んだ話をしていきたいと思います。 はじめに こんにちは。イノベーションセンター IOWN推進室のつかごし( @22nu_n )です。昨年に続き、今年も12/21を担当します。 昨年のアドベントカレンダー では、イノベーションセンターのValuesである「『枠』を越えよう」にちなみ、提案資料改善を通して、個人としての視点だけに頼らず、チームとして複数の視点を持って新たな価値観を得たことで、“わかりやすく伝える”ことにつながったというお話をしました。 イノベーションセンターのValuesは残り2つの要素からなります。今年はそのうちの「Implement First」にちなみ、チーム内での衝突や食い違いが起きるフェーズをどうしのいだか、課題意識を持っていたチームの状態に対し、自分なりに仮説を立てて、まずは行動をしてみたという経験を綴りたいと思います。新規事業開発組織に属し、同様の状況下にある方の励みや一助になれば幸いです。 なお、内容は個人の見解にもとづくものであり、所属組織の総意ではないことをご了承ください。 チームに訪れた“混乱期” 組織が結成されて1年。メンバーはある程度揃いプロジェクトを推進する体制が整った!みんなで頑張っていくぞ!と思っていたのに…… 意見は対立するし、認識は食い違うし、ミーティングはいつも延長戦に突入する、あちこちで不満の声が出ている。そうこうしていたら、プロジェクトが遅延している!あのプロジェクトでも、このプロジェクトでも…… 例えば、Aさんが必要だと思っているプロセスに対して、Bさんは不要だと思っているため、協力体制を築くことができず、議論は平行線を辿り、プロジェクトの進捗は遅々として進みませんでした。 どうしてこのような状況に陥ってしまったのか。原因を探ってみました。 いくつか原因はありましたが、特に以下の3点がボトルネックになっていました。 メンバーが忙しい:他部署と兼務している方が多く、結果としてそれぞれの部署での打ち合わせ予定とこちらの部署での打ち合わせ日程が重なってしまったり、それによって打ち合わせに最初から最後までフル参加が難しいことが増えていた チーム体制の頻繁な変更:プロジェクトの状況に応じて、メンバーの入れ替わりが頻繁に発生していた 信頼関係の構築不足:さまざまな組織から人を集めたにもかかわらず、勤務形態がフルリモートで顔を合わせる機会が少なく、信頼関係を築く時間が不足していた 心理学の知見を借りれば、これは「タックマンモデル」の「混乱期」に当てはまります。 「タックマンモデル」とは、心理学者のブルース・W・タックマンによって提唱されたチームビルディングに関する考え方で、組織は体制を整えただけで完了ではなく、さまざまな問題の解決を行って理想の組織にしていく必要があると説いています。 形成期、混乱期、統一期、機能期、散会期の5段階を辿るのですが、「混乱期」ではメンバー間の対立や混乱が生じやすい時期とされ、まさに私たちのチームはこの渦中にあるといえました。 相互理解を深める機会の必要性 このような「混乱期」を乗り越えるために、まずはチームの相互理解を深める機会が必要なのではないかと思いました。 例えば、物事がうまく進まない時、足を引っ張っていると感じた人を糾弾したくなってしまうことがあります。しかし、“足を引っ張っている”と感じた行動は、その人の価値観や経験によって醸成された固有な考えに基づいています。そのため、チームとして仕事をするためには、お互いの価値観や経験を共有し尊重していくことが大切です。 お互いの価値観や経験を共有する手段があれば、円滑なコミュニケーションや共通認識の形成を図ることができ、今の状況から脱することができるのではないかという仮説を持っていたところ、 偶然にも「わたしたちのウェルビーイングカード」を使う機会に恵まれたので実践してみることにしました。 「わたしたちのウェルビーイングカード」を用いたチームビルディング 「わたしたちのウェルビーイングカード」 は、NTT社会情報研究所 well-being研究プロジェクトで制作された“自身や周囲の人々のウェルビーイングに意識を向け、対話をうながすツール”です。 これにより、気軽な相互理解の場を持つことができ、各自が秘めていた大切にしていることを認識できます。 今回は、“自分にとって大切なことを3つ選び、それぞれ選んだ理由やエピソードを共有する”という使い方をしました。 ある方は「挑戦」という言葉を挙げ、「常に新しいことに挑戦したい」と語り、一方で、別の方は「社会貢献」という言葉を選び、「社会貢献につながる活動をして誰かの役に立ちたい」と話したり… また、力強いリーダシップを大切にしていると感じていた方が実は「平和」を大切にしていたり… 全く違うタイプだと思っていた方々が実はほとんど同じ言葉を選んでいたり… 発表するたびにどよめきが起き、活発な対話が生まれました。 このように、普段同じチームで働いていても仕事をする上で大切にしていることは異なります。しかも、個人が最も大切だと思っていることを、周囲はほとんどわかっていないことがわかりました。 これでは、相手を思いやって発言・行動したつもりが、かえって相手の価値観を否定していたということもありえます。このような状態が日常頻繁に起こっている可能性が高いことを、発表の時の皆さんの「どよめき」が示しているのではないかと考えています。 これまでのことを思い返してみると、とある方がさまざまなアドバイスをかけてくださっていたのですが、私はそのアドバイスが理解できず苦しいといった状況に陥ったことがありました。 当時は「あの人は私のことを考えて相談に乗ってくれているのに、何故私は素直に受け止められないのだろうか?」と悩みましたが、今回の経験で自分の価値観と相手の価値観が全く異なることが根本的な原因だったのではないかと気づきました。 相手にとってよいとされる状態が私にとってはそうではなかっただけで、お互いに価値観の共有ができたら寄り添い協働していくことができるのだと実感しました。 メンバーの心の根底にある大切にしていることを、外から観察・類推するのではなく、本人から語る機会を作り、認識することで、チームメンバー一人ひとりの心を繋ぎ、協働して行けるのではないかと思います。 効果や反響 まだ全ての物事がスムーズに進んでいると言える状況ではないですが、最悪の膠着状態からは脱することができたと思います。 「このように対面で顔を合わせてお互いの価値について話す時間はとても良かった」とメンバーから大変好評でした。 この経験を経て、メンバー同士が相手の価値観を理解し、互いの価値観を尊重することで、チームが前に進むことに気づいた人が増えていたら嬉しいです。 今後に向けて チームで抱える課題を解決することは並大抵のことではありません。今後もチームの相互理解を継続的に行い、これからも次々に来るであろう「混乱期」の波を、みんなで乗りこなしていきたいと考えています。 いつか「あの期間があったから、チームとして強くなれた」と振り返る時がくることを願い、これからも様々なことを試し、よりよいチームの状態を追求してみたいです。 おわりに 今回は「わたしたちのウェルビーイングカード」を活用したワークを通して、各々の「ウェルビーイング」を共有し対話をしたことで相互理解が進み、チームが前進するきっかけになったというお話をしました。 「混乱期」のメンバー間の対立や混乱は、メンバー間で価値観の共有ができておらず、協働体制が構築できていないことに起因します。メンバーそれぞれ価値観が違うということを前提に仕事を進めていくことが大切です。 自分自身だけでなくチームメンバーの「ウェルビーイング」に目を向け、チームとして最大限の成果を上げていきましょう。 最後まで、ご覧頂きありがとうございました!それでは、明日の記事もお楽しみに!
アバター
この記事は、 NTTコミュニケーションズ Advent Calendar 2024 20日目の記事です。 国産OT-IDSであるOsecTの新機能、自動遮断機能についてご紹介します。 はじめに OsecTとは OsecTの役割 AMF-SEC連携機能の概要 不審な通信を検知した場合の自動遮断の流れ 開発の背景と今後の展望 アライドテレシス社との協業について おわりに はじめに こんにちは、イノベーションセンターの石禾(GitHub: rhisawa )です。 このたび、OsecTの新機能として、自動遮断機能を2024年12月にリリースします。今回はこの自動遮断機能と、NTT Comとアライドテレシス社との協業についてご紹介します。 OsecTとは OsecTとは、工場、プラント、ビル、船舶、社会インフラなどの制御機器を運用するOTシステム(OT; Operational Technology)のセキュリティリスクを可視化・検知するサービスです。 多様化するOTシステムのセキュリティ脅威に対して、パケット解析するセンサー機器を設置するだけで、OTシステムへの影響なく、ネットワークの可視化と脅威・脆弱性検知ができます。早期にリスク感知できる状態を作り、工場停止による損失を未然に防ぐことができます。 詳しくは過去のブログ記事に書いているので、興味がある人は是非ご覧ください。( OsecTリリース ・ OsecT前編 ・ OsecT後編 ) OsecTの役割 OTシステムのセキュリティ対策は基本、機器の接続構成などを明確化する「可視化」、異常を認識する「検知」、検知された異常に対応する「対処」からなります。これまで、OsecTはOT環境のデータを収集・蓄積・分析することで、可視化と検知の機能を提供するものでした。(参考: OsecT提供開始ニュースリリース ) そこに、「対処」に値する自動遮断機能ができたことで、一連のセキュリティ対策を講じることが可能となり、対応範囲が一段と広がりました。 AMF-SEC連携機能の概要 自動遮断機能は、アライドテレシス社AMF-SECとの連携により実現します。 AMF-SEC連携機能を使用すると、不審な通信をOsecTで検知した際、AMF-SECによって通信の自動遮断ができるようになります。アライドテレシス社は、AMF(Autonomous Management Framework)-SECを通じてネットワーク全体の一元管理を提供しています。AMF-SECによって提供される通信の自動制御機能を使用して、不審な通信を遮断します。 不審な通信を検知した場合の自動遮断の流れ AMF-SEC連携機能による自動遮断の流れは次のとおりです。 攻撃を受ける OsecTが不審な通信を検知する OsecTが検知メールを送信する 検知メールを受信する AMF-SECがメール記載の不審な通信を自動遮断する 1 通信遮断は、不審な通信のIPアドレスもしくはMACアドレスをトリガーとして行われます。IPアドレスもしくはMACアドレスの情報が含まれたメールをSyslogに変換することによって、AMF-SECが不審な通信を遮断できます。 開発の背景と今後の展望 ITにおけるセキュリティ対策として一般的に実施されている自動遮断は、OTにおいては誤遮断によるシステムの誤作動・誤停止への懸念から、これまで避けられてきました。背景には、ITとOTでセキュリティの三要素「機密性」「完全性」「可用性」の優先順位の違いがあります。 ITにおいては、個人情報や企業の機密情報などのデータが漏洩しないことを重視することから、機密性が最重要とされますが、OTにおいては、設備が安全に安定して動作し続けることを重視することから、可用性が最重要とされています。このように考え方が違うため、セキュリティ対策のアプローチも、ITとOTによって異なってきます。 しかし、ITとOTが融合する環境の増加に伴い、近い将来OTの一部領域においては自動遮断による対処を実施せざる得ない状況が出てくると考えています。また、医療系では完全性が重視されるなど分野ごとの特色に対応する必要があります。こうした考えから、OsecTは自動遮断機能を開発しました。 この新機能はOsecTにとって初めての他社連携機能となります。これからOsecTは、市場ニーズに応じてさまざまなネットワーク製品やセキュリティ製品と連携を図り、更なる展開を目指してまいります。 アライドテレシス社との協業について NTT Comは、アライドテレシス社と産業サイバーセキュリティビジネスの協業を開始しました。今回ご紹介したOsecT AMF-SEC連携 自動遮断機能は、多岐に渡る協業内容の1つです。 これまで、アライドテレシス社は、ITインフラ向けのネットワーク製品やセキュリティソリューションを提供してきました。一方、NTT Comは制御システム向けのセキュリティ対策「WideAngle OsecT」を展開し、ネットワークの可視化や脅威検知を行っています。 今回、NTT Comとアライドテレシス社が協業し、両社の製品を連携させた産業向けサイバーセキュリティ対策機能を開発・提供します。この連携により、「WideAngle OsecT」の再販や機能統合を進め、社会インフラ、医療分野、中小製造業や海外拠点工場へのセキュリティソリューション普及を目指します。 ニュースリリースについては こちら をご覧ください。 おわりに 今回は、国産OT-IDSであるOsecTの自動遮断機能を紹介しました。OsecT 自動遮断機能は、NTT Comとアライドテレシス社との協業にて実現されています。 本記事の内容が、ご検討のお役に立ちましたら幸いです。 ご興味がある企業さまは、 こちら からお問い合わせをお願いいたします。直販のお問い合わせだけでなく、販売パートナーも募集中です。 お問い合わせお待ちしております。 本システム連携にはアライドテレシス社の特許技術を使用 ↩
アバター