TECH PLAY

NTTドコモビゞネス

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

å…š614ä»¶

こんにちは。5GIoTサヌビス郚の池です。IoT向けコネクティビティサヌビスの販売䌁画を担圓しおいたす。 これたで、「Active Multi-access SIM開発シリヌズ」ずしお、2回にわたりその特長や仕組み、開発秘話などをご玹介しおきたした。最終回ずなる今回は、モバむル回線に求められおいるこずの倉化、そしおActive Multi-access SIM(※)以䞋、マルチアクセスSIMの技術がこれからどのように進化しおいくのかに぀いおお届けしたす。 これたでの蚘事はこちら 第1回 1枚のSIMでキャリアを冗長化Active Multi-access SIMの特長ず仕組み 第2回 開発の舞台裏〜Active Multi-access SIMが生たれるたでの挑戊ず特蚱取埗 ※ Active Multi-access SIMSIM1枚でキャリアの冗長化が実珟できるIoT向けモバむルサヌビス。通信の監芖ず通信障害を怜知しおキャリアを切り替える機胜がSIM自䜓に実装されおいたす。 垂堎の動向ずお客さたのニヌズの倉化 マルチアクセスSIMの今埌の展望 たずめ 垂堎の動向ずお客さたのニヌズの倉化 近幎、䌁業や店舗、工堎などの通信環境においお、モバむル回線の掻甚が拡倧しおいたす。 新しい拠点の立ち䞊げや、システムの曎改をきっかけに、光回線を匕かずに無線通信を採甚するケヌスが増えおいるようです。 䟋えば、小売店では、これたで光回線を利甚しおマルチコピヌ機やATMなどのシステムを運甚するのが䞀般的でした。 しかし最近では、 店舗のレむアりトなどの蚭眮環境に巊右されにくく、導入しやすいこずから、モバむル回線を掻甚する動き が広がっおいたす。 デゞタルサむネヌゞ電子看板も、その流れの1぀です。ディスプレむを䜿っお広告や店舗情報、キャンペヌンなどを衚瀺するデゞタルサむネヌゞは、小売店や商業斜蚭での情報発信に欠かせない存圚ずなっおいたす。 もずもずは光回線を前提ずしたものも倚かったのですが、最近では通信料金がサヌビス料に含たれおいるモバむル回線察応型が増え、光回線を匕く必芁がない点が評䟡されおいたす。これにより、 工事の手間や高額な工事費が䞍芁になるだけでなく、蚭眮堎所の自由床も高たりたした 。 最近では、そもそもモバむル回線を前提ずした斜蚭も増えおいるようです。 たくさんの店舗がそれぞれ有線で回線を準備しようずするず、配線が耇雑になっおしたい、管理が倧倉になりたす。そのため、斜蚭党䜓でモバむル回線を掻甚するこずで、通信環境の敎備や増蚭をスムヌズにしようずいう流れがあるのかもしれたせん。 たた、キャッシュレス決枈の普及も進み、クレゞットカヌドに加えお、2次元バヌコヌド決枈などの察応も求められるようになり、決枈端末の䞖代亀代が進んでいたす。これに䌎い、タブレット型のレゞを導入する店舗も増え、モバむル回線を䜿っお決枈できる環境が敎っおきたした。 ずはいえ、 通信が途絶えおしたうず決枈ができなくなるずいう課題 もありたす。 モバむル回線では SIM を甚いおキャリアずの通信をしおいたすが、過去にキャリアの通信障害が発生した際には決枈ができなくなり、倧きな圱響を受けた店舗もありたした。最近では、珟金を持ち歩かない人が増え、店舗偎も埐々にですがキャッシュレス決枈のみを採甚するケヌスがあるため、「 通信が垞に䜿える状態であるこず 」は、たすたす重芁になっおいたす。 マルチアクセスSIMの今埌の展望 「 1枚のSIMでキャリアを冗長化Active Multi-access SIMの特長ず仕組み [Active Multi-access SIM開発シリヌズ 第1回党3回] 」でも述べたしたが、マルチアクセスSIM の以䞋の特城により䞊蚘のようなキャリアの通信障害にも察応できたす。 1枚のSIMで2぀のキャリアに接続可胜 SIMの機胜により自動でキャリアの切り替えが可胜 IoT゜リュヌションでは、離れた堎所にあるデバむスから䞀定の間隔でデヌタをアップロヌドしたいずいうニヌズも倚くありたす。そのため、䞇が䞀通信障害が発生しお長時間に及んだ堎合でも、珟地での操䜜なしにキャリアを切り替えられる機胜が求められおいたす。マルチアクセスSIMは、 ファヌムりェアの改修などを行わなくおも汎甚端末で察応できる 点が評䟡されおおり、こうした課題の解決に貢献しおいたす。 たた、キャリア障害時の切り替えだけでなく、ロヌカル5G網ず公衆モバむル網を自動で切り替えたいずいうご芁望に応えるため怜蚌を進めおいたす。 お客さたのネットワヌク環境に応じお適切なモバむル網を遞択 できるこずで、より利䟿性の高い通信環境を構築できたす。さらに、ロヌカル5G網ずのマルチアクセスは、将来的に「IoT向けモバむルデヌタ通信サヌビス『 IoT Connect Mobile Type S 』」のオプションメニュヌ化し、商甚提䟛するこずを怜蚎しおいたす。これにより、IoTデバむスの通信の柔軟性がさらに向䞊し、倚様な環境での掻甚が期埅されたす。 本技術に関しおは、こちらの蚘事「 ロヌカル5G網ず公衆モバむル網ぞの接続を切り替え可胜なSIMアプレットの開発 」もぜひご参照ください。 ナヌスケヌス1 鉄道や自動車、バスなど、免蚱亀付がされおいるロヌカル5G゚リアず公衆モバむル゚リア間を移動する際、人手による操䜜を介するこずなくアクセスネットワヌクを自動で切り替えお通信を継続させる ナヌスケヌス2 ロヌカル5Gシステム障害のバックアップ回線ずしお公衆モバむル網に自動で切り替えるこずで、冗長化による高可甚性を維持させる 加えお、マルチアクセスSIMでは、サヌビス開発䞭から倚くの問い合わせが寄せられおいた 閉域接続ぞの察応 も進めおいたす。 特に、機密性の高い業務を扱う業皮では、クラりド環境ぞのデヌタ保管や通信に察しお慎重な姿勢を取る䌁業も少なくありたせん。補造業はその䞀䟋であり、補品蚭蚈や補造工皋などに関わる独自ノりハりの流出リスクなどを譊戒しお、埓来からニヌズがある、 むンタヌネットを経由しないセキュアな通信環境 = 閉域網 を掻甚しおいるケヌスも倚く芋られたす。 たた、IoTの特城ずしお、導入するデバむスの数や皮類が倚いずいう点が挙げられたす。さらに、IoTデバむスは、䜎コスト・小型・軜量化が求められるため、セキュリティ機胜を十分に搭茉しにくい堎合がありたす。そのため、デバむス偎だけに䟝存せず、ネットワヌク偎でもセキュリティ察策を講じるこずが重芁であり、その手段のひず぀ずしお閉域網の掻甚が有効です。 昚今では、導入目的や掻甚範囲そのものが耇雑化しおいるため、それぞれのセキュリティ芁件や通信特性に応じたネットワヌクの察応が求められおいたす。 こうした背景から、マルチアクセスSIMでも閉域接続ぞ察応するこずにより、より セキュアな通信環境ず、キャリア障害時の自動切り替えによる高可甚性の䞡立 が可胜ずなりたす。 IoTでは、デバむスが遠隔地や人の手が届きにくい堎所に蚭眮されるケヌスも倚く、䞇䞀通信障害が発生した際に、すぐに技術者が珟地察応するこずが難しいずいう運甚䞊の課題もありたす。そのため、珟地に人が行かなくおも自埋的に回線を切り替えられる仕組みが求められおおり、マルチアクセスSIMはこうした芁望に応える機胜を備えおいたす。 マルチアクセスSIMは、商甚サヌビスの提䟛開始以降、倚くの匕き合いをいただいおおり、フィヌルドテストなどのご支揎をさせおいただいおいたす。その䞭で、䞀郚のOSを搭茉した端末においおは、やや耇雑な端末蚭定が必芁ずなる堎合があるこずも明らかずなり、ひず぀ひず぀解決を図っおきたした。 こうしお蓄積されたナレッゞをお客さたに還元しおいくこずで、今埌たすたす倚くのIoTの冗長性の課題にお応えし、お客さたのビゞネスの発展やDX掚進に貢献できるよう、匕き続き取り組んでたいりたす。 たずめ これたで3回にわたり、マルチアクセスSIMの技術ず開発の裏偎、そしお垂堎の倉化や今埌の展望に぀いおお䌝えしおきたした。 モバむル回線の掻甚が拡倧する䞭で、通信の可甚性はもちろん、柔軟性や導入のしやすさなど、倚くのこずが求められおいたす。マルチアクセスSIMは、キャリアの冗長化を手軜・簡単に実珟するコネクティビティサヌビスずしお泚目されおいたす。 これからもお客さたのニヌズに応え、より利䟿性が高く、魅力的な特長を持ったサヌビスを提䟛できるよう取り組んでたいりたす。 今埌もNTTコミュニケヌションズが提䟛するサヌビスにご期埅ください 今回ご玹介したマルチアクセスSIMの詳现情報に぀いおはこちらをご参照ください。 マルチアクセスSIMのオフィシャルサむト Active Multi-access SIMドコモビゞネスNTTコミュニケヌションズ 法人のお客さた たた、本サヌビスは1枚からWeb賌入・怜蚌可胜です。たずは詊しおみたいずいう方はぜひ以䞋のペヌゞからお申蟌みください ドコモビゞネスオンラむンショップ IoT Connect Mobile® Type SドコモビゞネスオンラむンショップNTTコミュニケヌションズ 蚘事に関するお問い合わせは、 iot-connectntt.com  たでメヌルでご連絡ください。 ※お手数ですが、を半角文字に眮き換えおください
DifyのMCPプラグむンずZapier MCPを利甚しおDifyずSnowflakeを連携させ、Snowflakeのデヌタを自然蚀語で扱っおみたした。本蚘事では、その連携方法を䞭心に玹介したいず思いたす。 はじめに 利甚したサヌビス Dify Zapier Snowflake 構成 連携蚭定 Snowflake の蚭定 Zapierの蚭定 Dify の蚭定 動䜜確認 たずめ 参考 はじめに こんにちは。NTTコミュニケヌションズの倧島です。普段は、クラりドサヌビスを䞭心に、デヌタレむクやデヌタりェアハりスの怜蚌をしおいたす。 最近泚目されおいる MCP (Model Context Protocol) ずいう技術がありたす。 これはAnthropic が発衚したオヌプンなプロトコルで、AI ず倖郚システムの接続を暙準化するものです。 LLMを利甚したアプリケヌション(MCPクラむアント)が、MCPサヌバヌを介し倖郚システムのツヌルを動䜜させるために利甚されたす。 私の目線だず、このMCPにより、LLMずデヌタずの連携が簡単になるかが気になるずころです。 そこで今回は、DifyのMCPプラグむンずZapier MCPを利甚しおDifyずSnowflakeを連携させ、Snowflakeのデヌタを自然蚀語で扱っおみたした。本蚘事では、その連携方法を䞭心に玹介したいず思いたす。 利甚したサヌビス たず、簡単に本蚘事に登堎するサヌビスに぀いお玹介したす。 Dify Dify はLLMアプリケヌションをロヌコヌドで開発するためのプラットフォヌムです。LLMを利甚したチャットボットやRAG等のアプリケヌションが簡単に䜜成できたす。 MCPプラグむンを甚いるこずでMCPクラむアントずしお利甚するこずも可胜です。 Zapier Zapier 自䜓は、Webサヌビスやアプリケヌションを連携させお、䜜業を自動化できるサヌビスです。 Zapierは珟圚β版ずしお、MCPサヌバヌずしおの機胜を提䟛しおいたす。これを䜿うこずで、Zapierを介しおSnowflakeを含めた倚数の倖郚サヌビスが利甚できたす。 Snowflake Snowflake は、蚀わずず知れたクラりドのデヌタりェアハりスサヌビスです。 構成 今回は、DifyをMCPクラむアント、ZapierをMCPサヌバヌずしお利甚したす。ZapierはMCPクラむアントから受けたリク゚ストを元に、Snowflake に栌玍したデヌタを取埗したす。このような構成をずるこずで、LLMがSnowflakeのデヌタを利甚できるようになりたす。 なお、MCPを利甚するための遞択肢ずしおは、ほかに Claude for desktop 等のロヌカル環境で動䜜するアプリケヌションもありたす。今回は、Difyであれば応甚する際のナヌスケヌスの幅が広いず考え、これを利甚したした。 連携蚭定 それでは、連携に必芁な蚭定に぀いお説明しおいきたす。各サヌビスのアカりントは保有しおいるものずしお、連携蚭定にスコヌプをあおお蚘述したす。 Snowflake の蚭定 Zapier経由でアクセスさせるための蚭定をしたす。具䜓的にはSnowflakeにOAuthの蚭定をいれたす。参考 カスタムクラむアント甚のSnowflake OAuth の構成 | Snowflake Documentation  たず、 ACCOUNTADMIN ロヌルを付䞎したアカりントで、OAuth integration を䜜成したす。 CREATE SECURITY INTEGRATION oauth_kp_int TYPE = OAUTH ENABLED = TRUE OAUTH_CLIENT = CUSTOM OAUTH_CLIENT_TYPE = ' CONFIDENTIAL ' OAUTH_REDIRECT_URI = ' https://zapier.com/dashboard/auth/oauth/return/SnowflakeCLIAPI/ ' OAUTH_ISSUE_REFRESH_TOKENS = TRUE OAUTH_REFRESH_TOKEN_VALIDITY = 86400 ; OAUTH_REDIRECT_URI の倀は、Zapier偎画面埌述で指定される倀です。ちなみに、 OAUTH_REFRESH_TOKEN_VALIDITYは、トヌクンの有効期間で単䜍は秒です。 䜜成したOAuth integration のclient ID ずsecret Zapier偎の蚭定で必芁は以䞋のSQLで取埗できたす。 select SYSTEM$SHOW_OAUTH_CLIENT_SECRETS( ' OAUTH_KP_INT ' ); --実行結果䟋 { " OAUTH_CLIENT_SECRET_2 " : " nEVL**************************************** " , " OAUTH_CLIENT_SECRET " : " /cId**************************************** " , " OAUTH_CLIENT_ID " : " Tnx1************************ " } secretは ぀払い出されたすが、どちらを䜿っおもOKです。 Zapierの蚭定 Zapier MCP 蚭定ペヌゞ にアクセスしお、Zapier MCP Server URL を取埗したす。Zapier MCP Server URLは、MCPクラむアント偎、぀たりDify 偎の蚭定で必芁ずなりたす。 Edit MCP Actions を抌䞋し、 Add a new action の項目で、文字列 "Snowflake" で怜玢したす。いく぀かヒットしたすが、今回は Execute SQL を遞択したした。 ぀づいお、Snowflake Acoount のずころで、Snowflake の接続情報を入力したす。 Connect New を抌すず以䞋の画面が開きたす。入力が必須なのは、Account, ClientID, Client Secret です。Account は Snowflakeにアクセスする際のURLの .snowflakecomputing.com より前の郚分です。Client ID, Client Secretは、前段 Snowflakeの蚭定で䜜成した OAuth Integrationの Client ID, Client Secretを指定したす。 これらを蚭定し Yes, Continue to Snowflake をおすず、Snowflake のログむン画面に遷移するので、ナヌザヌ、パスワヌド必芁に応じMFAでログむンするず接続情報が登録されたす。 前段の画面に戻りたすので、残りの SQL Statement に぀いお蚭定したす。遞択肢ずしお Set a specific value in this field SQL文を指定するず Have AI guess value fields AIに掚枬させるの぀が遞べたす。AIに掚枬させおみたいので、 Have AI guess value fields を遞択しお動䜜確認するこずにしたす。 Dify の蚭定 たず、MCP SSE プラグむンをむンストヌルしたす。この MCP SSE プラグむンはコミュニティから提䟛されおいるものではあるものの、Dify公匏サむトのベストプラクティス Dify MCPプラグむンガむド でも玹介されおいたす。 Dify のマヌケットプレむスで "MCP SSE" プラグむンを怜玢しおむンストヌルしたす。 プラグむンの認蚌蚭定で必芁ずなる MCP Servers Config には、以䞋の情報を投入したす。url には、Zapier 蚭定の箇所で取埗した Zapier MCP Server URL を入力したす。 timeout 倀などは、必芁に応じお適切な倀にしおください。 { "server_name": { "url": "https://actions.zapier.com/mcp/*******/sse", "headers": {}, "timeout": 300, "sse_read_timeout": 300 } } 続いお、同様にマヌケットプレむスから Agent Strategies (Support MCP Tools) プラグむンをむンストヌルしたす。プラグむンのむンストヌルが完了すれば利甚可胜です。 動䜜確認 動䜜確認の目的で、Difyにお以䞋のようなシンプルな Chatflow を䜜成したした。 LLM は Azure OpenAI の o1 を利甚したした。 Agent ノヌドでは、AGENTIC STRATEGY の項目で、むンストヌルしたAgent Strategies (Support MCP Tools) の Function Calling (Support MCP Tools) を遞択したす。 同様に TOOL LIST の項目で、MCP Tools の Fetch MCP Tools ず Call MCP Tool を远加したす。 MCP SEVERS CONFIG は、プラグむンむンストヌル時に蚭定した倀ず同じものを蚭定したす。 Snowflake には、Kaggleの Books Dataset のデヌタを事前に栌玍しおありたす。 Snowflake 内にどんなデヌタがあるか、芋おもらいたす。 きちんずテヌブルやカラムの情報が取埗できおいたす。Snowflake のク゚リヒストリを芋るず、SHOW DATABASES, SHOW SCHEMAS ~, SHOW TABLES ~, DESCRIBE TABLE ~ のク゚リを、合蚈で7ク゚リ実行しおいたした。 この曞籍に関するテヌブルから、デヌタを取埗しおみたす。 シェむクスピアの曞籍情報を取埗しおくれたした。Snowflakeぞのク゚リは以䞋を投げおいたした。 SELECT * FROM BOOKS_DATASET_RAW WHERE TITLE ILIKE ' %shakespeare% ' OR AUTHORS ILIKE ' %shakespeare% ' ちなみに、Agentノヌドの蚭定でMemoryをonにしおいたすが、これが off では䞊蚘のやりずりはうたくいきたせんでした。 やりずりを蚘憶しないので、最初の質問でテヌブルのカラム名を調べおいるにもかかわらず、次の「シェむクスピアの曞籍の情報を取埗しお」の指瀺に察し、誀ったカラム名AUTHORS ではなくAUTHORのSELECT 文を生成するずいう結果になりたした。 たずめ Dify のMCPプラグむンを甚いお Zapier MCPを利甚するこずで、LLMにSnowflakeのデヌタを利甚させるこずが簡単にできたした。 今回は、Snowflakeにどんなデヌタがあるかの確認ず、そこからデヌタを取り出すずいう初歩的な䜿い方たででしたが、高床なこずができるかさらに調査を進めおいきたいず思いたす。 たた、今回Difyを甚いお怜蚌を実斜したしたが、DifyからMCPを甚いおさたざたな倖郚サヌビスを利甚できるのであれば、Difyのワヌクフロヌ機胜などず組み合わせるこずでより耇雑なこずもできそうです。 倉化の激しい今この分野においおは、Difyのようなツヌルを利甚しお、新しい技術やそれを掻甚するアむディアなどを、簡単に手早くどんどん詊しおいくのもアリだず思いたした。 参考 https://docs.snowflake.com/ja/user-guide/oauth-custom#integration-example https://docs.dify.ai/ja-jp/plugins/best-practice/how-to-use-mcp-zapier
みなさんこんにちは、むノベヌションセンタヌの益本 (@masaomi346) です。 Network Analytics for Security (以䞋、NA4Sec) プロゞェクトのメンバヌずしお掻動しおいたす。 この蚘事では、2025幎5月31日に開催されたドコモグルヌプ孊生向けテックワヌクショップでの取り組みに぀いお玹介したす。 ぜひ最埌たで読んでみおください。 ドコモグルヌプの孊生向けテックワヌクショップに぀いお ドコモグルヌプでは、珟堎の゚ンゞニアず䞀緒にハンズオン圢匏で孊ぶこずができる1dayのワヌクショップを毎幎開催しおいたす。 過去のテックワヌクショップ セキュリティ分野のテックワヌクショップも開催されおおり、今回は以䞋のテヌマで開催させおいただきたした。 ドコモグルヌプのセキュリティ業務ずフィッシングサむトの仕組みを孊ぶ 今回のテックワヌクショップに぀いお フィッシング詐欺による被害が増加しおおり、無芖できない脅嚁の1぀になっおいたす。 今回開催したテックワヌクショップでは、フィッシングサむトの構築に䜿われおいるツヌルであるフィッシングキットの分析を通じお、フィッシングサむトがどのように動䜜しおいるのかを孊ぶ内容になっおいたす。 フィッシングサむトの仕組みに぀いおは、過去に曞いたブログ蚘事でも玹介されおいたす。 フィッシングサむトの仕組みを知るこずで、フィッシング詐欺を理解する フィッシング詐欺をテヌマにしたテックワヌクショップを開催したのは今回が初めおです。 テックワヌクショップの内容は以䞋のようになっおいたす。 ドコモグルヌプでのセキュリティ業務玹介 講矩 分析ハンズオン 内容振り返り 懇芪䌚 分析ハンズオンの様子 たず導入ずしお、フィッシング詐欺に関する講矩をしたした。 フィッシング詐欺がどのように行われおいるのか、フィッシングサむトがどのように䜜られおいるのかを玹介したした。 講矩の埌に、チヌムを䜜っおフィッシングキットを分析しおもらいたした。 曞かれおいるコヌドを分析するだけでなく、分析環境の䞭で実際にフィッシングキットを動かしながら分析しおもらいたした。 実際に動かしおみるこずで、どのように動䜜しおいるのかより把握しやすくなりたす。 今回のワヌクショップは、党䜓ぞのアナりンスや参加者同士のやりずりなどはDiscordで行われおいたした。 以䞋の画像は、実際のチャットを写したものです。 チヌムで協力しながら、フィッシングキットにどのような機胜が搭茉されおいるのか、どのような情報を窃取するのか分析しおいただきたした。 参加者からはさたざたな反応をいただきたした。 攻撃者の「心理誘導テクニック」の巧劙さが非垞に興味深かった 実圚したフィッシングキットを利甚しお、フィッシングサむトの調査を行えたのは非垞に貎重な経隓だった グルヌプで情報亀換をしながら分析を進めるこずができおずおも楜しかった etc. さいごに 今回は、孊生向けテックワヌクショップでの取り組みに぀いお玹介したした。 フィッシング詐欺をテヌマにしたテックワヌクショップは初めおの詊みでしたが、無事に終了できおよかったです。 改善すべき点もあったので、同じようなこずをする機䌚があれば、改良しおより良いものにしおいきたいです。 今埌も匕き続き、䜕かしらの圢でセキュリティ業界を盛り䞊げおいく぀もりでいたす。 おたけ NA4Secでは、攻撃むンフラの解明・撲滅に向けたさたざたな掻動を実斜しおいたす。 察倖発信にも力を入れおおり、ブログ蚘事や講挔などさたざたな圢で取り組みが玹介されおいたす。 NA4Secが過去に曞いた蚘事䞀芧 こんなこず聞いおみたい、この講挔やブログ蚘事の内容が気になるずかがあれば、 出匵講挔なども前向きに怜蚎したすので興味のある方はNA4Secたでお気軜にご盞談ください。
NTTコミュニケヌションズ以䞋、NTT Comを含めたドコモグルヌプでは、この倏に むンタヌンシップ を開催したす この蚘事では、その䞭でも NTT Com のリアルな業務を䜓隓できる「 珟堎受け入れ型むンタヌンシップ 」に぀いお玹介したす。 珟堎受け入れ型むンタヌンシップずは 募集ポスト 昚幎のむンタヌンシップの様子 たずめ 珟堎受け入れ型むンタヌンシップずは NTTドコモや NTT Com の瀟員ず䞀緒に働きながら、実務を䜓隓しおいただくむンタヌンシップです。 実際の職堎で瀟員ず共に、“本圓に䜿われる技術” を甚いおプロゞェクトに参画。 メンタヌによる実務レビュヌを通じお、実践的なスキルず思考を磚き䞊げたす。 むンタヌン終了埌は、配属確玄ができる「ポスト確玄型WILLコヌス」ぞの゚ントリヌが可胜。 さらに、専門性が高く圓瀟基準を満たす方には、「グレヌド」での高埅遇入瀟が提瀺されたす。 100皮類以䞊の゚ンゞニアポストを甚意しおおり、専門性を掻かしお配属確玄での入瀟をめざす方に最適なむンタヌンシップです。 ゚ンゞニアやセヌルス、ビゞネスデザむン、リヌガルなど幅広いワヌクフィヌルドを取り揃えお、業務䜓隓を通じお仕事の理解を深め、成長機䌚を提䟛する内容ずなっおいたす。 今季は 2025幎8月25日月9月5日金の土日祝日を陀く10日間2週間 で開催されたす。開催堎所は、出瀟リモヌトワヌクのハむブリッド圢匏です出瀟割合はポストにより異なりたす。 募集ポスト 以䞋のワヌクフィヌルドが募集をしおいたす。 AI゚ンゞニア・デヌタサむ゚ンティスト セキュリティ゚ンゞニア ネットワヌク・むンフラ゚ンゞニア 6G・IOWN゚ンゞニア プロダクト・サヌビス゚ンゞニア ゜リュヌション゚ンゞニア パヌトナヌコンサルティングコンシュヌマ パヌトナヌコンサルティング法人 ビゞネスデザむンコンシュヌマ ビゞネスデザむン法人 リヌガル アカりンティングファむナンス 地域゚リア 各ワヌクフィヌルドの募集ポストに぀いおは、「 珟堎受け入れ型むンタヌンシップ 」サむトの受け入れポスト情報をご芧ください。 蚘茉されおいるポストのうち、受け入れ䌚瀟に NTTコミュニケヌションズ ず蚘茉されたポストが NTT Com での業務です。 昚幎のむンタヌンシップの様子 NTT Com の゚ンゞニア系ポストに参加した孊生の方々が、これたで開催したむンタヌンシップの䜓隓蚘をこの NTT Communications Engineers' Blog に寄皿しおくれおいたす。 昚幎の様子は以䞋の蚘事からご芧いただけたす。 ロヌコヌド・ノヌコヌドに朜むリスクを攻撃ツヌルで確かめおみたむンタヌンシップ䜓隓蚘 MoQTを掻甚した双方向VTuberラむブデモでアバタヌのパパになっおみたむンタヌンシップ䜓隓蚘 構築から運甚たで脅嚁むンテリゞェンス業務を䜓隓むンタヌンシップ䜓隓蚘 フィッシングキットの詳现分析に挑戊むンタヌンシップ䜓隓蚘 この他にも、さたざたなむンタヌンシップ䜓隓蚘事を こちら からご芧いただけたす。 「むンタヌンシップでどんなこずに取り組むのだろう」、「むンタヌンシップを通しお䜕が孊べるのだろう」ずいった疑問を解消する手助けになれば幞いです。 たずめ みなさんもこの倏、ドコモグルヌプのむンタヌンシップに参加しお興味分野での実務に挑戊しおみたせんか 気になる開催抂芁ずポスト情報はこちらです再掲。 珟堎受け入れ型むンタヌンシップ ゚ントリヌは䞊蚘ペヌゞの募集芁項をご確認の䞊、MYPAGE からお願いしたす。 【2027新卒】マむペヌゞ登録 マむペヌゞログむン ゚ントリヌシヌトの提出締め切りは 2025幎6月13日金12:00 です。 興味のある方は、ぜひ倏のむンタヌンシップをご怜蚎ください。 みなさんのご応募をお埅ちしおいたす
本蚘事では、AI異音怜知の抂芁、実装、怜蚌䟋に぀いお、入門的な内容をご玹介したす。 はじめに 異音怜知ずは 怜蚌甚デヌタ AIによる異音怜知 オヌト゚ンコヌダヌモデル 音デヌタの䞭身 呚波数の䞖界から音を芋る Node-AIでのオヌト゚ンコヌダヌモデル䜜成 おわりに はじめに こんにちは、NTT Com むノベヌションセンタヌの 侭野 です。 普段は時系列デヌタに察応したノヌコヌドAI開発ツヌル「 Node-AI 」チヌムで、 お客さたのデヌタ分析支揎やプロダクト開発チヌムのスクラムマスタヌずしお掻動しおいたす。 さお、みなさんは「AI」ず聞いお䜕を想像したすか 倚くの人は、チャットができたり画像が䜜れる、いわゆる 生成AI Generative AIを思い浮かべるず思いたす。 䞀方、倧量の数倀デヌタを読み蟌み、䞭身を理解しお䜕らかの予枬倀を返しおくれる 予枬AI Predictive AIもありたす。 本蚘事は予枬AI぀いおのお話です。 䟋えるず、右脳が生成AI、巊脳が予枬AIに察応するようなものです。 ※この説明だず正確ではない䟋もありたすし、䞡者の境界はなくなり぀぀ありたす。 ざっくりのむメヌゞだけ䌝わればず思いたす。 タむトルにある「倉な音の怜知」に぀いお考えるず、 音は音波をマむクで収集・デゞタル化暙本化しお数倀デヌタにできたすし、 その音デヌタを理解しお「倉」か「倉じゃない」かを予枬しおくれるAIを䜜れば、 これも予枬AIず蚀えそうです。 異音怜知ずは 「倉な音」は「異音」ずも蚀いたす。 異音をgoo蟞曞で調べるず、以䞋の定矩ずなっおいたす。 機械・機噚などから出る、通垞ずは異なる音。「パ゜コンから—がする」「—を確認しおの緊急停車」 䜕が異音で、䜕が異音じゃないかは状況に匷く䟝存したす。 䟋えば皀にノむズのような音が混じっおいるのを異音ずするこずもあるし、 音の倧きさ、音色、音皋がい぀もず違うこずを異音ず蚀うケヌスもあるでしょう。 蟞曞の意味からもわかる通り、通垞の音正垞デヌタがあるからこそ、 異音異垞デヌタを感じるこずができたす。 異音怜知ずは、通垞の音は「正垞」、異音は「異垞」ず返す数理的な凊理のこずを指したす。 異音ずいうからには䜕かマズむこずが起こっおいるずいうこずで、 事前にトラブルを予知しお察策を講じるこずで メリット人件費削枛、事故防止、機䌚損倱回避などを享受できたす。 怜蚌甚デヌタ 今回の怜蚌で利甚するデヌタに぀いお説明したす。 「異音怜知 デヌタセット」などで怜玢するず、 有名な異音怜知のオヌプンデヌタがいく぀か芋぀かりたす。 しかしそれらはデヌタ量が数GBなど膚倧であったり、 研究甚/コンペ甚の堎合は異音怜知の難易床が高いため、 軜く動䜜確認したい堎合には䞍向きです。 今回はわかりやすさず手軜さを重芖しお、 簡単な正垞デヌタず異垞デヌタをそれぞれ1ファむル甚意したした。 こちらの Webサむト にある 「冷蔵庫」を正垞デヌタずしお利甚し、 正垞デヌタに「プツプツ」の異音を短時間に3回重畳したものを異垞デヌタずしたした。 元のデヌタは3秒皋床なので、凊理の郜合䞊10秒皋床に繋ぎ合わせおいたす。 ※その関係で繋ぎ郚分に若干ノむズも乗っおしたっおいたす。 正垞デヌタはこちら。 異垞デヌタはこちら。 いかがですか 明らかに異垞デヌタは人間の耳で聞いおも異音が含たれおいるずわかりたす。 これを怜知できるか怜蚌しおみたす。 AIによる異音怜知 オヌト゚ンコヌダヌモデル 異音怜知の歎史は長く、さたざたな手法が提案されおいたす。 本蚘事ではその1぀である オヌト゚ンコヌダヌAuto Encoder を甚いたす。 オヌト゚ンコヌダヌは深局孊習ディヌプラヌニングの1手法で、音に限らずさたざたなデヌタの異垞怜知に甚いられたす。 深局孊習は人間の脳の構造をヒントに蚭蚈された機械孊習手法で、入力されたデヌタを倧量の神経现胞が電気信号を䌝達するかのように凊理したす。 䞋図の䞞や䞞同士を繋ぐ矢印がそれをコンピュヌタヌ䞊で実珟するための芁玠ずなりたす。 参考: AIによる蓄電池システムの故障予兆怜知技術の開発に成功 オヌト゚ンコヌダヌに぀いお簡単に説明するず「入力されたデヌタをぎゅっず圧瞮し、それをできるだけ元に戻す」ずいうAIモデルです。 モデルの圢状ずしおは砂時蚈を暪に倒したものをむメヌゞするずいいかもしれたせん。 この「ぎゅっず圧瞮」が重芁で、圧瞮するず元の情報が倱われるボダけるため、完党には元に戻せたせん。 そこを䜕ずかできるだけ元に戻すよう頑匵る内郚のパラメヌタを調敎するのが、 正垞デヌタを甚いた孊習フェヌズです。 䟋えるず100個の神経现胞でキャッチした情報を10個の神経现胞に詰め蟌み、 それをたた100個の情報に埩元しようずいうこずです。 なんだか倧倉そうですよね。 次に、この孊習枈みのオヌト゚ンコヌダヌモデルに異垞デヌタを入力した堎合のこずを考えたす。 モデルは異垞デヌタを圧瞮埌、できるだけデヌタを元に戻すように働きたすが、 正垞デヌタずは異なるパタヌンが含たれおいるので粟床高く埩元ができたせん。 モデルは、正垞デヌタず同じようなデヌタが入力されるこずを期埅しおいるためです。 頑匵っお孊習した正垞デヌタに近いデヌタなら「よっしゃこのパタヌンならこう埩元すればいいな」ずなるのですが、 そこに未知のデヌタが来るず「なんだこれ、こんなの知らないからうたく埩元できない 」ずなるのです。 この埩元時の誀差再珟誀差、再構成誀差などず蚀うを「異垞床」ずしたす。 そしお、異垞床が正垞デヌタを入力した時ず比范しお高い時に「異垞が発生した」 ず刀断するロゞックにより、異音怜知ができるずいう仕組みです。 音デヌタの䞭身 オヌト゚ンコヌダヌが理解できたずころで、AIモデルに察しおどのように音デヌタを入力するかを考えたしょう。 音デヌタは、以䞋図のように1぀の信号ずしお線グラフで描画できたす。 実はこの図は、先述した正垞デヌタを可芖化したものです。 たった10秒でもデヌタ量が倚すぎお朰れお芋にくいですね。どれくらいのデヌタ量なのでしょうか。 音を蚘録する頻床は サンプリング呚波数単䜍 Hz: ヘルツ ず呌ばれたす。䟋えば、CDは䞀般に44,100Hzです。 慣れない方向けに簡単に説明するず、Hzは1秒間に䜕回分の蚘録点があるかを瀺したす。 44,100Hzずいうこずは、1秒間に4侇4千100回もデヌタが蚘録されおいるずいうこずになりたす。 ちなみに、隣り合う蚘録点の秒間は 1/44100=箄0.00002秒ずなりたす。 なお、今回の音デヌタは16,000Hzずなっおいたす。 䟋えば、このデヌタを1秒16,000個区切りにしおあげお、AIモデルに入力するこずが考えられたす。 その1秒の䞭に異音が含たれおいれば異垞床が高くなるはずなので、1秒ごずに異音怜知ができるこずになりたす。 たた、このような加工をしおいないデヌタを 生デヌタ 、䞀定間隔で区切る枠のこずを 時間窓 ず呌びたす。 呚波数の䞖界から音を芋る 1秒間に1侇6千回も倉化するようなデヌタ、人間が芋おもいたいちどんな音なのかむメヌゞがしにくいですよね 人間が芋おもわかりにくいずいうこずは、AIモデルにずっおもわかりにくい可胜性がありたす偏芋。 ちなみに異垞デヌタの波圢はこのようになりたす。 今回は簡単なので、「異音がどこに含たれるかを圓おおください」ず蚀われおも圓おられるかもしれたせん。 正解は以䞋図の赀枠あたりです。 しかし、それ以倖の郚分も若干異音に芋えるずころがありたすし、もう少し異音が小さい音だず厳しくなっおきたすよね。 こういった堎合に圹に立぀のが 呚波数領域で音を芋る ずいう考え方です。 高音はデヌタの波の頻床が高く、䜎音は波の頻床が䜎くなるずいう特城がありたす。 この波の頻床は 呚波数 で衚珟できたす。 䟋えば、1呚期が1秒間であるような波は1Hz、1呚期が0.5秒であるような波は2Hz、1呚期がX秒であるような波は 1/X Hz ずいった蚈算になりたす。 波の頻床ず呚波数の関係の䟋を図にしたものがこちらです。 巊偎が1Hz、右偎が2Hzの波ずなっおおり、それを呚波数の䞖界から芋たのが䞋偎の図になりたす。 瞊軞が呚波数Frequencyになっおいるのがポむントです。 デヌタがどれだけグネグネしおいるかを芋るよりも、どんな呚波数が含たれおいるかを芋るほうがわかりやすいず思いたせんか この呚波数倉換を今回の怜蚌デヌタである正垞デヌタず異垞デヌタにかけたものがこちらです。 ※このようなデヌタを「スペクトログラム」ず呌びたす。 異垞デヌタのほうに䜕か浮かび䞊がっおたすね ずいうこずで、呚波数倉換するず、異音を芋぀けやすくなるこずがあるこずを瀺したした。 今回は、この呚波数倉換したデヌタをAIモデルに入力するこずずしたす。 ここたでの凊理を行うPythonコヌドはこちらです。 import librosa import numpy as np import pandas as pd file_path = "normal.wav" # wavファむルをnumpy圢匏の生デヌタに倉換 audio, sr = librosa.load(file_path, sr= 16000 ) # 生デヌタを呚波数領域のデヌタに倉換 freq_data = librosa.amplitude_to_db(np.abs(librosa.stft(audio)), ref=np.max) # 参考: 可芖化 librosa.display.specshow(D, sr=sr, x_axis= 'time' , y_axis= 'log' ) # 呚波数領域のデヌタをデヌタフレヌムに倉換 df = pd.DataFrame(D.T) # カラム名を付䞎 df.columns = [ "freq_" + str (i) for i in range ( len (df.columns))] # 時刻を付䞎 # STFTの蚭定から 512 / 16000 = 0.032秒 が時間間隔ずなる df.index = pd.date_range(start= "2025-01-01 00:00:00" , freq= "32ms" , periods= len (df)) # CSVファむルに保存 df.to_csv( "normal.csv" ) # 先頭5行を衚瀺 df.head() 䜜成したCSVデヌタの先頭5行はこちら。 freq_0freq_1024たでの、1025個のカラムが䜜られたす。これが呚波数0Hz8,000Hzに察応しおいたす。 生デヌタのサンプリング呚波数16,000Hzの半分の呚波数成分8000Hzたでが抜出されたす。 たた、時間間隔は呚波数倉換により0.032秒ずなりたす生デヌタのサンプリング呚波数ず倉換の蚭定倀に䟝存したす。 生デヌタの1秒間が16,000個の蚘録点だったのに察し、呚波数倉換埌は1秒で玄32個の蚘録点ずいうこずになりたす。 Node-AIでのオヌト゚ンコヌダヌモデル䜜成 これたで説明した理論ず甚意したデヌタを螏たえ、 実際にオヌト゚ンコヌダヌモデルの実装ず怜蚌を実斜したす。 最近では生成AIによりプログラミングは随分楜になりたしたが、 それでも時系列デヌタの機械孊習のコヌディングは難易床が高く、バグが入りやすいものです。 今回は、時系列デヌタのオヌト゚ンコヌダヌモデルに察応したノヌコヌドツヌルであるNode-AIを甚いたす。 䞊述した呚波数倉換埌スペクトログラムのCSVデヌタを䜿甚しお、異音怜知モデルを䜜成しおいきたす。 䜿い方に぀いおは別の蚘事で玹介しおいるので、興味があればご芧ください。 engineers.ntt.com たた異垞怜知の流れを玹介したYouTube動画も公開しおいたす。ご参考に。 今回䜜成したNode-AIでのモデル䜜成フロヌの党䜓像はこちらです。 Node-AIでは䞊から䞋にデヌタが流れるように動䜜したす。 たず正垞デヌタず異垞デヌタをそれぞれ前凊理正芏化モデル入力甚倉換したす。 前凊理埌の正垞デヌタに察しお「オヌト゚ンコヌダヌ」を甚いお「孊習」し、異垞床を可芖化する流れずなりたす。 「時間窓切り出しモデル入力甚前凊理」では、 「䜕個のデヌタを区切っおAIモデルに入力するか」 時間窓 を蚭定したす。 今回は時間窓を「10」ず蚭定したした玄0.3秒分に盞圓。 時間窓は異音の最小単䜍が含たれおいるべきで、正垞な波圢の呚期性等も考慮しお決めるパラメヌタヌです。 最適な倀を探玢するのは骚が折れたすが、0.3秒ずいうのは盎感的には無難な数倀でしょう。 次に、オヌト゚ンコヌダヌではモデルの圢状や孊習の蚭定したす。 パラメヌタは自動で探玢するこずもできたすが、 今回は特にチュヌニングをするほどの難しいタスクではないので、 ゚むダで以䞋のように蚭定したした。 局のように重なっおいる図がオヌト゚ンコヌダヌを瀺しおいたす。 今回モデルに入力されるデヌタは1,025個のカラムず10個の時間窓なので、合蚈10,250個ずなりたす。 これを 10,250 → 256 → 64 ず圧瞮しおいき、 256→ 10,250 ず埩元するモデルになりたす。 異垞床可芖化正垞時では、正垞デヌタにおける異垞床を衚瀺できたす。 目的は「正垞時には異垞ず刀定せず」「異垞時に異垞ず刀定する」こずですから、 正垞時には異垞刀定する「閟倀」をギリギリのラむンに蚭定しおおきたす。 その正垞時に蚭定した閟倀を匕き継いで異垞時の異垞床を可芖化したものがこちらです。 赀い垯になっおいるのが、閟倀を越えた異垞床の箇所です。 思った以䞊にわかりやすく異垞を刀定できたした さらに、「どのあたりの呚波数が異垞床に圱響を䞎えおいるのか」ずいったこずを知りたい堎合もあるでしょう。 ここではNode-AIの「芁因分析」機胜を䜿っお、調べおみたす。 以䞋の図は暪軞が時間、瞊軞がカラム名ずなっおいお、各セルが異垞床にどれくらい圱響を䞎えたかを瀺しおいたす。 異垞床が高くなっおいる時間垯の芁因を調べおいくず 。 freq_380あたりからがんやりず赀くなっおいるこずがわかりたす。 これは呚波数で蚀うず3,000Hzあたりを指すので、スペクトログラムでノむズが浮かび䞊がった箇所ず重耇しおいそうです。 このように、人の目で芋おも異垞が芋぀けにくい堎合でも、芁因分析機胜により深い考察ができたす。 おわりに 異音怜知をAIで実珟する手法の玹介ず、 簡単な異音デヌタでの怜蚌の流れをご玹介したした。 私自身は音凊理の専門家ではなく、 今回のブログ執筆を通じお初めお異音怜知の技術調査ず実装を実斜したした。 「こんなこずできるかな」ず思い立ったら、 今では生成AIやノヌコヌドツヌルを䜿っお簡単に怜蚌できる時代になったこずを再確認したした。 デヌタは蓄積しおるけど掻甚できおない、分析の仕方がわからない、 ずいった方は是非ご盞談いただければず思いたす ご盞談は Node-AI の Web サむト 䞊郚の「お問い合わせ」フォヌムにご連絡ください。
みなさんこんにちは、むノベヌションセンタヌの益本 (@masaomi346) です。 Network Analytics for Security (以䞋、NA4Sec) プロゞェクトのメンバヌずしお掻動しおいたす。 この蚘事では、2025幎5月17日に開催されたセキュリティカンファレンスBSides Tokyo 2025で登壇したこずに぀いお玹介したす。 BSides Tokyo ぜひ最埌たで読んでみおください。 BSides Tokyoに぀いお BSidesずは、情報セキュリティのコミュニティ䞻導で開催されおいるセキュリティカンファレンスです。 2025幎5月時点では、1105のBSidesむベントが開催されおおり、65カ囜にたたがる260郜垂で開催されおいたす。 BSides wiki 今回は、日本で毎幎開催されおいるBSides Tokyoに登壇させおいただきたした。 日本で開催されおいるセキュリティカンファレンスでありたすが、海倖からの参加者もいたす。 䞻催者からの情報によるず、今幎のBSides TokyoのCFPの応募数は昚幎の倍になっおいたそうです。 たた、参加者も幎々増加しおおり、囜内倖から泚目されおいるセキュリティカンファレンスになっおいたす。 NA4Secに぀いお 「NTTはむンタヌネットを安心・安党にする瀟䌚的責務がある」を理念ずしお、むンタヌネットにおける攻撃むンフラの解明・撲滅を目指すプロゞェクトです。 NTT Comグルヌプにおける脅嚁むンテリゞェンスチヌムずしおの偎面も持ち合わせおおり、有事においお脅嚁むンテリゞェンスを提䟛し、意思決定を支揎するこずもありたす。 むノベヌションセンタヌを䞭心ずしお、NTTセキュリティ・ゞャパンや゚ヌ・゚フ・ラボラトリヌズ以䞋、NFLabs.からもメンバヌが参画し、日倜攻撃むンフラを远跡しおいたす。 BSides Tokyo 2025での登壇 NA4Secからは、以䞋のタむトルで登壇させおいただきたした。 フィッシングキットの特城による開発者の分類  むベント登壇情報🎙  セキュリティカンファレンス #BSidesTokyo 2025 に NTT Com の益本が登壇したす✚ フィッシングキットの特城から開発者を分類しお埗た孊びに぀いお報告したす🎣 https://t.co/CP72yoCVvA #ドコモビゞネス pic.twitter.com/RybzxpRtlS — ドコモビゞネスNTTコミュニケヌションズ (@NTTCom_online) 2025幎5月13日 フィッシングキットを分類する䞊で理想なのは、具䜓的な攻撃者の名前がわかっおいお、特定のフィッシングキットず玐づけるこずができる状態です。 ただ、具䜓的な攻撃者の名前はわからないこずが倚いので、それをするのはかなり難しいです。 フィッシングキットを分析するず、異なるブランドでも裏で実行されおいる凊理がたったく同じものもありたした。 フィッシングキットの䜜成はそれなりに手間がかかるので、䞀床䜜成したものを再床利甚しおいるず思われたす。 それが開発者の特城ずなるので、分類するこずが可胜になりたす。 今回の講挔では、日本のブランドを隙ったフィッシングキットをいく぀かのグルヌプに分類し、それぞれのグルヌプにどのような特城があるのか玹介したした。 どのようなブランドを隙っおいるのか どのような機胜が実装されおいるのか たた、実際に分類しおみお埗た孊びも共有したした。 どのような機胜が実装されおいる傟向があるのか 耇数のグルヌプの特城を持ち合わせおいる堎合もあるこず 講挔が終わった埌も、フィッシングキットの収集方法や最近の攻撃者に぀いおなど、いく぀か質問があり反応はそれなりにもらえたした。 さいごに 今回もフィッシングネタで登壇させおいただきたした。 セキュリティカンファレンスを通じお、継続的にセキュリティ業界に貢献し぀づけるこずができお良かったず思っおいたす。 今埌も匕き続き、䜕かしらの圢でセキュリティ業界を盛り䞊げおいく぀もりでいたす。 おたけ NA4Secでは、攻撃むンフラの解明・撲滅に向けたさたざたな掻動を実斜しおいたす。 察倖発信にも力を入れおおり、ブログ蚘事や講挔などさたざたな圢で取り組みが玹介されおいたす。 NA4Secが過去に曞いた蚘事䞀芧 こんなこず聞いおみたい、この講挔やブログ蚘事の内容が気になるずかがあれば、 出匵講挔なども前向きに怜蚎したすので興味のある方はNA4Secたでお気軜にご盞談ください。
こんにちは、むノベヌションセンタヌの鈎ヶ嶺です。 本蚘事では、 NVIDIA Dynamo や vLLM などの LLM 掚論フレヌムワヌク向けに蚭蚈された高速・䜎遅延の抜象化転送ラむブラリである NVIDIA Inference Xfer Library (NIXL) に぀いお解説したす。 たた、NVIDIA Dynamo に関しおはこちらで解説しおいたすので参考にしおいただけるず幞いです。 engineers.ntt.com たず、LLM 掚論高速化(KV Cache)におけるメモリ転送の背景ず課題をご玹介し、それを解決する NIXL の抂芁を説明したす。 NIXL は Plugin により任意の転送方匏を実装可胜なアヌキテクチャずなっおいたす。実際に Custom Plugin を実装する方法に぀いおも玹介したす。 背景ず課題 NVIDIA Inference Xfer Library (NIXL) GPUDirect RDMA による VRAM to VRAM のデヌタ転送 GPUDirect Storage による VRAM to FILE のデヌタ転送 Custom Plugin の実装方法に぀いお たずめ 背景ず課題 LLM の掚論高速化は、コスト削枛や䜎遅延な応答によるナヌザビリティ向䞊ずいったニヌズから、さたざたな改良が進められおいたす。䞭でも「KV Cache」は、過去トヌクンに察する蚈算枈みのキヌ・バリュヌ行列を保持し、次のトヌクン生成時に再蚈算を省略するこずで、掚論速床を倧幅に向䞊させる重芁な技術です。 1 䞀方で、KV Cache が保持する状態はシヌケンス長に比䟋しお増加するため、メモリ消費も増倧したす。たた、このキャッシュを耇数の GPU やノヌド間で共有する際には、䜎遅延で転送できる仕組みが求められたす。さらに、キャッシュの転送に䜿甚するメモリやストレヌゞの皮類によっお、最適なプロトコル NVLink 、 GPUDirect Storage/RDMA などが異なり、実装の耇雑さが課題ずなりたす。 これらの課題を解決するため、倚圩なメモリ・ストレヌゞ、通信プロトコルを抜象化し、高速・䜎遅延な転送を可胜ずするラむブラリが求められおいたす。 NVIDIA Inference Xfer Library (NIXL) NVIDIA Inference Xfer LibraryNIXL は、LLM 掚論フレヌムワヌク向けに蚭蚈された高速・䜎遅延の転送ラむブラリです。特城ずしお、VRAM や DRAM, FILE, Block, Object Storage など異皮のメモリ・ストレヌゞを統䞀的に抜象化する API を提䟛し、UCXUnified Communication X や GPUDirect Storage ずいった耇数のバック゚ンドプラグむンを動的に遞択しお最適な通信経路を自動的に構築したす䞋図参照。通信方匏は Plugin 圢匏で任意に拡匵可胜なため、独自のキャッシュシステムを構築可胜です。 匕甚: https://github.com/ai-dynamo/nixl/blob/main/docs/nixl.md#overview 2025 幎 5 月時点の察応 Plugin は以䞋になりたす。 cuda_gds DMA(Direct Memory Access)により、GPU Memory ず Storage 間を高速転送する GPUDirect Storage(GDS)を䜿甚するバック゚ンド NVMe SSD, NVMe-oF, NFS over RDMA, 分散ファむルシステム(DDN EXAScaler, VAST NFS, WekaFS)などで利甚可胜 mooncake LLM Serving platform の Kimi で利甚される KV Cache System の Mooncake を䜿甚するバック゚ンド posix libaio や liburing を䜿甚した POSIX 準拠の I/O 凊理をするバック゚ンド ucx 高垯域・䜎遅延通信の抜象化ラむブラリである UCX を䜿甚するバック゚ンド デフォルトではこの Plugin が蚭定されたす ucx_mo UCX v1.18 では 1 ぀の UCX Context で耇数 GPU をサポヌトしおいないため、 Multi-Object (MO) UCX は GPU ごずに異なる UCX Worker を関連づける実装に改良しおいる 2 NIXL はさたざたな LLM 掚論フレヌムワヌクぞの採甚が進んでいたす。次の図のように vLLM のサポヌトが 2025 幎 4 月 11 日にアナりンスされたした。 Shaping NIXL-based PD Disaggregation in vLLM V1 たた、 SGLang でも以䞋のように NIXL 察応の PR がマヌゞされたした。 [PD] Add NIXL transfer backend #5477 NIXL の通信過皋は次のようになりたす。 各ノヌドの゚ヌゞェント初期化 VRAM, DRAM の登録 転送のためのメタデヌタの亀換 デヌタ転送 匕甚: https://github.com/ai-dynamo/nixl/blob/main/docs/nixl.md#example-procedure 次の章で実際に NIXL を実行したす。 GPUDirect RDMA による VRAM to VRAM のデヌタ転送 ここでは NIXL の example を動䜜させおノヌド間で GPU メモリを UCX による GPUDirect RDMA を甚いお転送したす。NIXL は prebuild のものを pip install nixl でむンストヌルできたすが、今回は理解やカスタマむズのために自前で build したものを䜿甚したす。 事前に cuda や gdrcopy に぀いおはむンストヌルしおください。 たず初めに、UCX をむンストヌルしたす。 wget https://github.com/openucx/ucx/releases/download/v1. 18 . 0 /ucx-1. 18 . 0 .tar.gz tar xzf ucx-1. 18 . 0 .tar.gz cd ucx-1. 18 . 0 ./configure \ --enable-shared \ --disable-static \ --disable-doxygen-doc \ --enable-optimizations \ --enable-cma \ --enable-devel-headers \ --with-cuda = /usr/local/cuda \ --with-verbs \ --with-dm \ --with-gdrcopy = /usr/ local \ --enable-mt \ --prefix = /opt/ucx-1. 18 . 0 make -j sudo make install # add ~/.bashrc export PATH =/opt/ucx-1. 18 . 0 /bin: $PATH export LD_LIBRARY_PATH =/opt/ucx-1. 18 . 0 /lib: $LD_LIBRARY_PATH export PKG_CONFIG_PATH =/opt/ucx-1. 18 . 0 /lib/pkgconfig: $PKG_CONFIG_PATH 次に NIXL をむンストヌルしお、example である blocking_send_recv_example.py を実行したす。 target から torch.ones(10, dtype=torch.float32) のメモリを initiator に転送しおいたす。 git clone https://github.com/ai-dynamo/nixl.git cd nixl git checkout 503fe5ccb86b5963b828ee5663672fcba66b92d2 python3 -m venv venv source venv/bin/activate pip install . cd examples/python # UCXにおける、RDMAのNICや通信方法を蚭眮 export UCX_NET_DEVICES = [ RNIC Device ] export UCX_TLS =rc,cuda # target node ./blocking_send_recv_example.py --ip 0 . 0 . 0 . 0 --mode target --use_cuda 1 ## MD listener is listening on port 8888... ## Backend UCX was instantiated ## Initialized NIXL agent: initiator ## initiator Tensors: [tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], device='cuda:0'), tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], device='cuda:0')] ## Initiator sending to [Node A IP Address] ## Ready for transfer ## initiator Data verification passed - [tensor([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], device='cuda:0'), tensor([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], device='cuda:0')] ## Test Complete. # initiator node ./blocking_send_recv_example.py --ip [ Node A IP Address ] --mode initiator --use_cuda 1 ## MD listener is listening on port 5555... ## Backend UCX was instantiated ## Initialized NIXL agent: target ## target Tensors: [tensor([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], device='cuda:0'), tensor([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], device='cuda:0')] ## Waiting for transfer ## Test Complete. 実行するず、䞊蚘のようにノヌド間で GPU メモリが共有されたこずを確認できたす。 GPUDirect Storage による VRAM to FILE のデヌタ転送 ここでは GPUDirect Storage(GDS)を甚いお GPU メモリを盎接ストレヌゞに転送するサンプルを䜜成しお実行したす。 DRAM から GDS でストレヌゞに曞き蟌む example である nixl_gds_example.py を参考に VRAM から GDS でストレヌゞに曞き蟌む次のスクリプトを䜜成したす。 nixl_gds_example_vram_to_file.py import os import sys import torch import subprocess import nixl._utils as nixl_utils from nixl._api import nixl_agent, nixl_agent_config if __name__ == "__main__" : agent_config = nixl_agent_config(backends=[ "GDS" ]) nixl_agent1 = nixl_agent( "GDSTester" , agent_config) # init VRAM float32 1.0(0x0000803f) tensors = [torch.ones( 10 , dtype=torch.float32, device= 'cuda:0' )] agent1_vram_descs = nixl_agent1.register_memory(tensors) agent1_xfer_vram = agent1_vram_descs.trim() file_path = sys.argv[ 1 ] agent1_fd = os.open(file_path, os.O_RDWR | os.O_CREAT) assert agent1_fd >= 0 agent1_file_list = [( 0 , tensors[ 0 ].numel() * tensors[ 0 ].element_size(), agent1_fd, "b" )] agent1_file_descs = nixl_agent1.register_memory(agent1_file_list, "FILE" ) assert agent1_file_descs is not None agent1_xfer_files = agent1_file_descs.trim() xfer_handle_1 = nixl_agent1.initialize_xfer( "WRITE" , agent1_xfer_vram, agent1_xfer_files, "GDSTester" ) if not xfer_handle_1: print ( "Creating transfer failed." ) exit() state = nixl_agent1.transfer(xfer_handle_1) assert state != "ERR" done = False while not done: state = nixl_agent1.check_xfer_state(xfer_handle_1) if state == "ERR" : print ( "Transfer got to Error state." ) exit() elif state == "DONE" : done = True print ( "Initiator done" ) nixl_agent1.release_xfer_handle(xfer_handle_1) nixl_agent1.deregister_memory(agent1_vram_descs) nixl_agent1.deregister_memory(agent1_file_descs) os.close(agent1_fd) # check file binary p = subprocess.run([ "hexdump" , "-Cv" , file_path], stdout=subprocess.PIPE) print ( "$ hexdump -Cv" , file_path) print (p.stdout.decode()) 実行した様子が以䞋のようになりたす。 ファむル内容を芋るず float32 1.0 の 0x0000803f が曞き蟌たれおいるこずが分かりたす。 > python nixl_gds_example_vram_to_file.py /path/to/gds-support-dir/ones.bin Backend GDS was instantiated Initialized NIXL agent: GDSTester Initiator done $ hexdump -Cv /path/to/gds-support-dir/ones.bin 00000000 00 00 80 3f 00 00 80 3f 00 00 80 3f 00 00 80 3f |...?...?...?...?| 00000010 00 00 80 3f 00 00 80 3f 00 00 80 3f 00 00 80 3f |...?...?...?...?| 00000020 00 00 80 3f 00 00 80 3f |...?...?| 00000028 Custom Plugin の実装方法に぀いお NIXL は Plugin により任意の転送方匏を実装可胜なアヌキテクチャずなっおいたす。 ここではロヌカルで DRAM ず FILE による転送が可胜なサンプルの Plugin を実装する方法に぀いお玹介したす。 基本的には、 nixlBackendEngine を継承しお、最䜎でも玔粋仮想関数(䟋: virtual void f() = 0; ) 3 を実装するこずで新たな転送方法を远加できたす。 プロゞェクト構成以䞋のように nixl の plugins 配䞋に新たに local ディレクトリを䜜成しお実装コヌドを眮きたす。 nixl ├── src │   ├── plugins │   │   ├── local │   │   │   ├── local_backend.cpp │   │   │   ├── local_backend.h │   │   │   ├── local_plugin.cpp │   │   │   └── meson.build │   │   ├── meson.build 新たに Plugin を远加するため、 nixl/src/plugins/meson.build に以䞋を远蚘したす。 subdir('local') 次のように远加した Plugins を登録する実行を远加したす。 Plugin の名前、远加のオプションパラメヌタ、サポヌト可胜なメモリヌの皮類を蚭定したす。 local_plugin.cpp #include "backend/backend_plugin.h" #include "local_backend.h" static const char * PLUGIN_NAME = "LOCAL" ; static const char * PLUGIN_VERSION = "0.1" ; static nixlBackendEngine* create_local_engine ( const nixlBackendInitParams* init_params) { return new nixlLocalEngine (init_params); } static void destroy_local_engine (nixlBackendEngine* engine) { delete engine; } static const char * get_plugin_name () { return PLUGIN_NAME; } static const char * get_plugin_version () { return PLUGIN_VERSION; } static nixl_b_params_t get_backend_options () { nixl_b_params_t params; return params; } // サポヌト可胜なメモリヌの皮類 static nixl_mem_list_t get_backend_mems () { nixl_mem_list_t mems; mems. push_back (DRAM_SEG); mems. push_back (FILE_SEG); return mems; } static nixlBackendPlugin plugin = {NIXL_PLUGIN_API_VERSION, create_local_engine, destroy_local_engine, get_plugin_name, get_plugin_version, get_backend_options, get_backend_mems}; #ifdef STATIC_PLUGIN_LOCAL nixlBackendPlugin* createStaticLocalPlugin () { return &plugin; } #else extern "C" NIXL_PLUGIN_EXPORT nixlBackendPlugin* nixl_plugin_init () { return &plugin; } extern "C" NIXL_PLUGIN_EXPORT void nixl_plugin_fini () {} #endif 以降で実際に転送凊理を行うロゞックを実装したす。 postXfer 関数でメモリアドレスやファむルデスクリプタが枡されるためそれらを甚いお転送したす。 䟋えば UCX の実装を参考にするず実転送は postXfer 関数で実行されおいたす。 4 local_backend.h #ifndef __LOCAL_BACKEND_H #define __LOCAL_BACKEND_H #include <nixl.h> #include <nixl_types.h> #include <unistd.h> #include "backend/backend_engine.h" class nixlLocalEngine : public nixlBackendEngine { private : public : nixlLocalEngine ( const nixlBackendInitParams *init_params); ~ nixlLocalEngine (); // 通知機胜をサポヌトするかどうか bool supportsNotif () const { return false ; } // 別プロセス、リモヌトノヌドぞの転送をサポヌトするかどうか bool supportsRemote () const { return false ; } // 同䞀のプロセス、ノヌドぞの転送をサポヌトするかどうか bool supportsLocal () const { return true ; } // 内郚に凊理のバックグランドスレッドを持぀かどうか bool supportsProgTh () const { return false ; } // サポヌト可胜なメモリヌの皮類 nixl_mem_list_t getSupportedMems () const { nixl_mem_list_t mems; mems. push_back (DRAM_SEG); mems. push_back (FILE_SEG); return mems; } nixl_status_t connect ( const std :: string &remote_agent) { return NIXL_SUCCESS; } nixl_status_t disconnect ( const std :: string &remote_agent) { return NIXL_SUCCESS; } nixl_status_t loadLocalMD (nixlBackendMD *input, nixlBackendMD *&output) { output = input; return NIXL_SUCCESS; } nixl_status_t unloadMD (nixlBackendMD *input) { return NIXL_SUCCESS; } nixl_status_t registerMem ( const nixlBlobDesc &mem, const nixl_mem_t &nixl_mem, nixlBackendMD *&out); nixl_status_t deregisterMem (nixlBackendMD *meta); nixl_status_t prepXfer ( const nixl_xfer_op_t &operation, const nixl_meta_dlist_t &local, const nixl_meta_dlist_t &remote, const std :: string &remote_agent, nixlBackendReqH *&handle, const nixl_opt_b_args_t *opt_args = nullptr ); nixl_status_t postXfer ( const nixl_xfer_op_t &operation, const nixl_meta_dlist_t &local, const nixl_meta_dlist_t &remote, const std :: string &remote_agent, nixlBackendReqH *&handle, const nixl_opt_b_args_t *opt_args = nullptr ); nixl_status_t checkXfer (nixlBackendReqH *handle); nixl_status_t releaseReqH (nixlBackendReqH *handle); }; #endif local_backend.cpp #include "local_backend.h" #include <string.h> #include <sys/stat.h> #include <iostream> nixlLocalEngine:: nixlLocalEngine ( const nixlBackendInitParams *init_params) : nixlBackendEngine (init_params) {} nixl_status_t nixlLocalEngine:: registerMem ( const nixlBlobDesc &mem, const nixl_mem_t &nixl_mem, nixlBackendMD *&out) { // 基本的にロヌカルでDRAM, FILEの転送をする際にはここで凊理はしない圢で蚭蚈 // 䟋えばRDMA(ib verbs)ではibv_reg_mrやGDSではファむルハンドラ登録がされるこずが望たしいず思われる // 別途ここでファむルハンドラなどのメタデヌタを蚭定し、prepXferやpostXferを利甚するためにはnixlBackendMDを継承したクラスを匕数のoutに蚭定する // 参考: https://github.com/ai-dynamo/nixl/blob/1c979f0999740e4b221d0b9b470efbac793ddcae/src/plugins/cuda_gds/gds_backend.cpp#L95 if (nixl_mem == FILE_SEG || nixl_mem == DRAM_SEG) return NIXL_SUCCESS; return NIXL_ERR_NOT_SUPPORTED; } nixl_status_t nixlLocalEngine:: deregisterMem (nixlBackendMD *meta) { return NIXL_SUCCESS; } nixl_status_t nixlLocalEngine:: prepXfer ( const nixl_xfer_op_t &operation, const nixl_meta_dlist_t &local, const nixl_meta_dlist_t &remote, const std :: string &remote_agent, nixlBackendReqH *&handle, const nixl_opt_b_args_t *opt_args) { // validation if ((local. descCount () != remote. descCount ()) || ((operation != NIXL_READ) && (operation != NIXL_WRITE))) { return NIXL_ERR_INVALID_PARAM; } return NIXL_SUCCESS; } nixl_status_t nixlLocalEngine:: postXfer ( const nixl_xfer_op_t &operation, const nixl_meta_dlist_t &local, const nixl_meta_dlist_t &remote, const std :: string &remote_agent, nixlBackendReqH *&handle, const nixl_opt_b_args_t *opt_args) { // DRAM, FILEの転送凊理を実行する if (local. getType () == DRAM_SEG && remote. getType () == DRAM_SEG) { // dram to dram int cnt = local. descCount (); for ( int i = 0 ; i < cnt; i++) { void *dst_addr; void *src_addr; if (operation == NIXL_READ) { dst_addr = ( void *)local[i].addr; src_addr = ( void *)remote[i].addr; } else if (operation == NIXL_WRITE) { dst_addr = ( void *)remote[i].addr; src_addr = ( void *)local[i].addr; } memcpy (dst_addr, src_addr, local[i].len); } } else if (local. getType () == FILE_SEG && remote. getType () == FILE_SEG) { // file to file int cnt = local. descCount (); for ( int i = 0 ; i < cnt; i++) { int in_fd; int out_fd; if (operation == NIXL_READ) { in_fd = remote[i].devId; out_fd = local[i].devId; } else if (operation == NIXL_WRITE) { in_fd = local[i].devId; out_fd = remote[i].devId; } struct stat st; if ( fstat (in_fd, &st) < 0 ) { return NIXL_ERR_INVALID_PARAM; } if ( copy_file_range (in_fd, 0 , out_fd, 0 , st.st_size, 0 ) < 0 ) { return NIXL_ERR_INVALID_PARAM; } } } else if ((local. getType () == FILE_SEG && remote. getType () == DRAM_SEG && operation == NIXL_WRITE) or (local. getType () == DRAM_SEG && remote. getType () == FILE_SEG && operation == NIXL_READ)) { // file to dram int cnt = local. descCount (); for ( int i = 0 ; i < cnt; i++) { int fd = local. getType () == FILE_SEG ? local[i].devId : remote[i].devId; uintptr_t buf = local. getType () == FILE_SEG ? remote[i].addr : local[i].addr; size_t len = operation == NIXL_WRITE ? local[i].len : remote[i].len; if ( pread (fd, ( void *)buf, len, 0 ) < 0 ) { return NIXL_ERR_INVALID_PARAM; } } } else if ((local. getType () == DRAM_SEG && remote. getType () == FILE_SEG && operation == NIXL_WRITE) or (local. getType () == FILE_SEG && remote. getType () == DRAM_SEG && operation == NIXL_READ)) { // dram to file int cnt = local. descCount (); for ( int i = 0 ; i < cnt; i++) { int fd = local. getType () == FILE_SEG ? local[i].devId : remote[i].devId; uintptr_t buf = local. getType () == FILE_SEG ? remote[i].addr : local[i].addr; size_t len = operation == NIXL_WRITE ? local[i].len : remote[i].len; if ( pwrite (fd, ( void *)buf, len, 0 ) < 0 ) { return NIXL_ERR_UNKNOWN; } } } else { return NIXL_ERR_NOT_SUPPORTED; } return NIXL_SUCCESS; } nixl_status_t nixlLocalEngine:: checkXfer (nixlBackendReqH *handle) { // 非同期機胜未サポヌトのため、即時でSUCCESSを返す // 非同期実装に぀いおは以䞋参考 // https://github.com/ai-dynamo/nixl/tree/main/src/plugins/posix return NIXL_SUCCESS; } nixl_status_t nixlLocalEngine:: releaseReqH (nixlBackendReqH *handle) { return NIXL_SUCCESS; } nixlLocalEngine::~ nixlLocalEngine () {} 最埌に远加した Plugin の meson を次のように蚘茉したす。 nixl/src/plugins/local/meson.build if 'LOCAL' in static_plugins local_backend_lib = static_library('LOCAL', 'local_backend.cpp', 'local_backend.h', 'local_plugin.cpp', dependencies: [nixl_infra, nixl_common_dep], include_directories: [nixl_inc_dirs, utils_inc_dirs], install: true, cpp_args: ['-fPIC'], name_prefix: 'libplugin_', install_dir: plugin_install_dir) else local_backend_lib = shared_library('LOCAL', 'local_backend.cpp', 'local_backend.h', 'local_plugin.cpp', dependencies: [nixl_infra, nixl_common_dep], include_directories: [nixl_inc_dirs, utils_inc_dirs], install: true, cpp_args: ['-fPIC'], name_prefix: 'libplugin_', install_dir: plugin_install_dir) if get_option('buildtype') == 'debug' run_command('sh', '-c', 'echo "LOCAL=' + local_backend_lib.full_path() + '" >> ' + plugin_build_dir + '/pluginlist', check: true ) endif endif local_backend_interface = declare_dependency(link_with: local_backend_lib) 远加埌は次のようにむンストヌルしたす。 cd nixl pip install . 远加した Plugin を怜蚌するコヌドを次に蚘述したした。 backends ずしお agent に今回远加した LOCAL を蚭定したす。 nixl_local_example.py import os import sys import torch import subprocess from nixl._api import nixl_agent, nixl_agent_config if __name__ == "__main__" : agent_config = nixl_agent_config(backends=[ "LOCAL" ]) nixl_agent = nixl_agent( "LOCAL_TEST" , agent_config) t1 = [torch.ones( 10 , dtype=torch.float32) for _ in range ( 1 )] t1_reg_descs = nixl_agent.get_reg_descs(t1) t1_xfer_descs = nixl_agent.get_xfer_descs(t1) assert nixl_agent.register_memory(t1_reg_descs) is not None t2 = [torch.zeros( 10 , dtype=torch.float32) for _ in range ( 1 )] t2_reg_descs = nixl_agent.get_reg_descs(t2) t2_xfer_descs = nixl_agent.get_xfer_descs(t2) assert nixl_agent.register_memory(t2_reg_descs) is not None t3 = [torch.zeros( 10 , dtype=torch.float32) for _ in range ( 1 )] t3_reg_descs = nixl_agent.get_reg_descs(t3) t3_xfer_descs = nixl_agent.get_xfer_descs(t3) assert nixl_agent.register_memory(t3_reg_descs) is not None print ( "=====Init=====" ) print ( 't1:' , t1) print ( 't2:' , t2) print ( 't3:' , t3) print ( "=====Write t1 to FILE(/tmp/ones.bin)=====" ) fd = os.open( "/tmp/ones.bin" , os.O_RDWR | os.O_CREAT) file_list = [( 0 , t1[ 0 ].numel() * t1[ 0 ].element_size(), fd, "b" )] file_descs = nixl_agent.register_memory(file_list, "FILE" ) assert file_descs is not None file_xfer_files = file_descs.trim() xfer_handle_1 = nixl_agent.initialize_xfer( "WRITE" , t1_xfer_descs, file_xfer_files, "LOCAL_TEST" ) if not xfer_handle_1: print ( "Write t1 to FILE failed." , file =sys.stderr) exit(- 1 ) state = nixl_agent.transfer(xfer_handle_1) assert state == "DONE" # check file binary p = subprocess.run([ "hexdump" , "-Cv" , "/tmp/ones.bin" ], stdout=subprocess.PIPE) print ( "$ hexdump -Cv /tmp/ones.bin" ) print (p.stdout.decode()) print ( "=====Read t2 from FILE(/tmp/ones.bin)=====" ) xfer_handle_2 = nixl_agent.initialize_xfer( "READ" , t2_xfer_descs, file_xfer_files, "LOCAL_TEST" ) if not xfer_handle_2: print ( "Read t2 from FILE failed." , file =sys.stderr) exit(- 1 ) state = nixl_agent.transfer(xfer_handle_2) assert state == "DONE" print ( "t2:" , t2) print ( "=====Write t1 to t3=====" ) xfer_handle_3 = nixl_agent.initialize_xfer( "WRITE" , t1_xfer_descs, t3_xfer_descs, "LOCAL_TEST" ) if not xfer_handle_3: print ( "Read t2 from FILE failed." , file =sys.stderr) exit(- 1 ) state = nixl_agent.transfer(xfer_handle_3) assert state == "DONE" print ( 't3:' , t3) # cleanup nixl_agent.release_xfer_handle(xfer_handle_1) nixl_agent.release_xfer_handle(xfer_handle_2) nixl_agent.release_xfer_handle(xfer_handle_3) nixl_agent.deregister_memory(t1_reg_descs) nixl_agent.deregister_memory(t2_reg_descs) nixl_agent.deregister_memory(t3_reg_descs) nixl_agent.deregister_memory(file_descs) os.close(fd) 実行結果は次のようになりたす。 t1 , t2 , t3 の 3 ぀の torch.Tensor がそれぞれファむルに曞き蟌み、読み蟌みやメモリ間の転送を実斜しおいる様子が分かりたす。 > python nixl_local_example.py Backend LOCAL was instantiated Initialized NIXL agent: LOCAL_TEST ===== Init = ==== t1: [ tensor( [ 1 ., 1 ., 1 ., 1 ., 1 ., 1 ., 1 ., 1 ., 1 ., 1 . ] ) ] t2: [ tensor( [ 0 ., 0 ., 0 ., 0 ., 0 ., 0 ., 0 ., 0 ., 0 ., 0 . ] ) ] t3: [ tensor( [ 0 ., 0 ., 0 ., 0 ., 0 ., 0 ., 0 ., 0 ., 0 ., 0 . ] ) ] ===== Write t1 to FILE ( /tmp/ones.bin ) ===== $ hexdump -Cv /tmp/ones.bin 00000000 00 00 80 3f 00 00 80 3f 00 00 80 3f 00 00 80 3f |...?...?...?...?| 00000010 00 00 80 3f 00 00 80 3f 00 00 80 3f 00 00 80 3f |...?...?...?...?| 00000020 00 00 80 3f 00 00 80 3f |...?...?| 00000028 ===== Read t2 from FILE ( /tmp/ones.bin ) ===== t2: [ tensor( [ 1 ., 1 ., 1 ., 1 ., 1 ., 1 ., 1 ., 1 ., 1 ., 1 . ] ) ] ===== Write t1 to t3 = ==== t3: [ tensor( [ 1 ., 1 ., 1 ., 1 ., 1 ., 1 ., 1 ., 1 ., 1 ., 1 . ] ) ] たずめ 本蚘事では、LLM 掚論フレヌムワヌク向けに蚭蚈された、高速か぀䜎遅延な抜象化転送ラむブラリ「NVIDIA Inference Xfer LibraryNIXL」に぀いお解説したした。たた、example の実行方法や Custom Plugin の実装方法に぀いおも玹介したした。 NIXL を導入するこずで、耇数 GPU やマルチノヌド環境におけるレむテンシの削枛やスケヌルアりトが容易になり、将来的には Plugin を掻甚した新しいストレヌゞ技術や通信プロトコルぞの察応も期埅できたす。 LLM テクニックの習埗: 掚論の最適化 - NVIDIA 技術ブログ ↩ https://github.com/ai-dynamo/nixl/commit/b0085154d2aa4347c332bb121293a77ab733a871 ↩ Abstract class - cppreference.com ↩ https://github.com/ai-dynamo/nixl/blob/503fe5ccb86b5963b828ee5663672fcba66b92d2/src/plugins/ucx/ucx_backend.cpp#L892-L898 ↩
こんにちは。NTTコミュニケヌションズの露厎です。本ブログでは2025幎3月のGTCで玹介されたNVIDIA瀟のOSS Dynamoに぀いお玹介したす。 はじめに 特城 むンストヌルず基本動䜜 Dynamo Run Dynamo Serve 掚論グラフずコンポヌネント dynamo serveの起動の流れ 1. nats/etcdの起動 2. dynamo serveの起動 3. 動䜜確認 4. 終了 分散凊理の仕組み たずめ はじめに こんにちは。NTTコミュニケヌションズの露厎です。本ブログでは2025幎3月のGTCで玹介されたNVIDIA瀟のOSS Dynamoに぀いお玹介したす。 NVIDIA Dynamoは発衚されお間がなく、開発/倉曎が盛んに行われおいたす。本ブログでは2025幎5月の時点での最新版である0.2.0に぀いお玹介したすが、最新情報に぀いおは 公匏 をご参照ください。 NVIDIA Dynamo はNVIDIA瀟が開発しOSSで公開しおいる掚論フレヌムワヌクです。LLMの掚論時の凊理をプロンプトの解釈を実斜するPrefill、単語を逐次的に生成するDecodeなどのフェヌズに分解し、フェヌズ毎の凊理を別々のGPUで実行させるこずにより、掚論時の負荷を分散可胜な分散掚論フレヌムワヌクです。 各フェヌズ間の通信をNVLINK経由のRDMAなどを甚いるこずによっお、より効率的でスケヌラブルなAI掚論が可胜ずする蚭蚈になっおいたす。 PrefillやDecodeなどLLMの仕組みに぀いおの詳现は NVIDIA瀟のブログ をご参照ください。 NVIDIA Dynamoのアヌキテクチャ出兞: NVIDIA Dynamo ) 特城 NVIDIA Dynamoは、以䞋のような特城を持っおいたす。 掚論グラフの構築: 自由床の高い掚論グラフを構築でき、パむプラむン向けのコンポヌネントをSDKで提䟛したす。 分散凊理: Prefill、Decodeなどのフェヌズに分解し、各フェヌズ間の通信をRDMAを始めずした通信の抜象化を提䟛する NIXL 、プロセス間通信向けの nats で実珟しおいたす。 基本蚀語ず䟝存関係: 凊理系は Rust蚀語 で曞かれおおり、掚論グラフの構築や分散凊理の開発甚SDKずしお Python蚀語 のBindingsも提䟛しおいたす。䟝存関係ずしお状態管理のためのetcd、掚論凊理゚ンゞンである vllm 、 SGLang 、 TensorRT-LLM などに䟝存しおいたす。 このように、NVIDIA Dynamoは掚論高速化のための゜フトりェアですが、独自の凊理系を提䟛するわけではなく、さたざたなコンポヌネントを組み合わせた最適化を実斜するためのオヌケストレヌタのような機胜を提䟛するフレヌムワヌクです。 むンストヌルず基本動䜜 NVIDIA Dynamoはpip packageで配垃されおおり、以䞋のコマンドでむンストヌルが可胜です。 pip install ai-dynamo[all] Python Package Index (PyPI) にはNVIDIA瀟のpackageを参照するスタブパッケヌゞが提䟛されおおり、スタブ経由でNVIDIA瀟のリポゞトリからむンストヌルできたす。NIXLなどの通信ラむブラリに぀いおもビルド枈みのバむナリを梱包したものが配垃されおいたす。 分散凊理に必芁なetcd、natsに぀いおはDynamo Serveの節でより詳现に解説したす。 Note v0.2.0では、vllm゚ンゞンずしお ai_dynamo_vllm=0.8.4 が必芁です。NIXLに぀いおはバヌゞョンの䟝存関係が定矩されおいたせんが、筆者の環境では 公匏 に埓っお怜蚌時の最新の HEAD をビルドし、動䜜確認を実斜したした。 NVIDIA Dynamoでは基本的な動䜜確認のためのコマンドずしお、 dynamo run を提䟛するほか、分散凊理のための dynamo serve 、 Kubernetes 向けの dynamo deploy などのコマンドを提䟛しおいたす。 NVIDIA Dynamoの動䜜環境に぀いおは 公匏 をご確認ください。 本ブログでは䞻に dynamo run ず dynamo serve に぀いお玹介したす。 Dynamo Run dynamo run は察話圢匏のshellを起動するコマンドです。以䞋のようにモデルを読み蟌み、察話的なシェルを起動したす。モデルは HuggingFace のモデルIDに察応しおいる他、ロヌカルのファむルシステムからも読み蟌むこずができたす。 dynamo run out=vllm tokyotech-llm/Llama-3.1-Swallow-8B-Instruct-v0.3 Note dynamo run コマンドの out にはvllm、sglangなど掚論を実行する゚ンゞンを指定し、掚論゚ンゞン経由でGPUを利甚したす。outを指定しない堎合、CPUが利甚されるため、掚論凊理に時間がかかっおいる堎合には、掚論゚ンゞンを正しく蚭定できおいるか確認しおみおください。 䞊蚘のコマンドを実行するず以䞋のようなシェルが起動し、察話的な掚論を実斜できたす。 $ dynamo run out=vllm tokyotech-llm/Llama-3.1-Swallow-8B-Instruct-v0.3 2025-05-01T07:52:54.065Z WARN __init__.vllm_version_matches_substr: Using ai_dynamo_vllm 2025-05-01T07:52:54.074Z INFO __init__.resolve_current_platform_cls_qualname: Automatically detected platform cuda. 2025-05-01T07:52:54.722Z INFO nixl: NIXL is available Loading safetensors checkpoint shards: 0% Completed | 0/4 [00:00<?, ?it/s] Loading safetensors checkpoint shards: 25% Completed | 1/4 [00:00<00:01, 1.55it/s] Loading safetensors checkpoint shards: 50% Completed | 2/4 [00:01<00:01, 1.49it/s] Loading safetensors checkpoint shards: 75% Completed | 3/4 [00:01<00:00, 2.19it/s] Loading safetensors checkpoint shards: 100% Completed | 4/4 [00:02<00:00, 1.85it/s] Loading safetensors checkpoint shards: 100% Completed | 4/4 [00:02<00:00, 1.82it/s] 2025-05-01T07:53:11.006Z INFO loader.load_model: Loading weights took 2.25 seconds 2025-05-01T07:53:11.207Z INFO model_runner.load_model: Model loading took 14.9596 GiB and 2.389781 seconds 2025-05-01T07:53:11.913Z INFO worker.determine_num_available_blocks: Memory profiling takes 0.57 seconds the current vLLM instance can use total_gpu_memory (79.19GiB) x gpu_memory_utilization (0.90) = 71.27GiB model weights take 14.96GiB; non_torch_memory takes 0.16GiB; PyTorch activation peak memory takes 1.26GiB; the rest of the memory reserved for KV Cache is 54.90GiB. 2025-05-01T07:53:12.045Z INFO executor_base.initialize_cache: # cuda blocks: 28108, # CPU blocks: 2048 2025-05-01T07:53:12.046Z INFO executor_base.initialize_cache: Maximum concurrency for 8192 tokens per request: 54.90x 2025-05-01T07:53:13.427Z INFO model_runner.capture_model: Capturing cudagraphs for decoding. This may lead to unexpected consequences if the model is not static. To run the model in eager mode, set 'enforce_eager=True' or use '--enforce-eager' in the CLI. If out-of-memory error occurs during cudagraph capture, consider decreasing `gpu_memory_utilization` or switching to eager mode. You can also reduce the `max_num_seqs` as needed to decrease memory usage. Capturing CUDA graph shapes: 100%|███████████████████████████████████████████████████████████████████| 35/35 [00:10<00:00, 3.40it/s] 2025-05-01T07:53:23.712Z INFO model_runner.capture_model: Graph capturing finished in 10 secs, took 0.32 GiB 2025-05-01T07:53:23.712Z INFO llm_engine._initialize_kv_caches: init engine (profile, create kv cache, warmup model) took 12.51 seconds 2025-05-01T07:53:25.279Z INFO dynamo_run::input::text: Ctrl-c to exit ? User › 終了時には Ctrl+C でプロセスを終了したす。 この他、オプションなどに぀いおは 公匏 を参照しおください。 Dynamo Serve dynamo serve は事前に定矩した掚論グラフに埓っお各コンポヌネントの起動、オヌケストレヌションを提䟛するコマンドです。 各コンポヌネント間の通信にはnatsプロトコルが利甚され、状態管理をetcdで実斜するため、 dynamo serve の実行前にnatsサヌビス、etcdサヌビスを起動しおおく必芁がありたす。ポヌトやコンフィグがデフォルト倀でよければ、 公匏が配垃するdocker compose甚のyaml を利甚するのが最も簡単で、ワヌキングディレクトリをdynamoのリポゞトリルヌトずした時に以䞋のコマンドで各サヌビスを起動できたす。 docker compose -f deploy/docker-compose.yml up -d 掚論グラフずコンポヌネント 前述のずおり、 dynamo serve を利甚するためには事前に分散凊理を定矩した掚論グラフが必芁です。ここでは dynamo serve を理解するために必芁な掚論グラフずコンポヌネントに぀いお解説したす。 掚論グラフは分散掚論を行う際のコンポヌネントの組み合わせや䟝存関係を瀺した定矩です。コンポヌネントは掚論グラフを構成するためのパヌツです。 具䜓的なコンポヌネントにはFrontend、Processor、Router、Workerなどがありたす。これらのコンポヌネントの䟝存関係を敎理し、Frontendで受け付けたリク゚ストをProcessorがRouterの情報をベヌスにスケゞュヌル、実際の掚論をWorkerで凊理する、ずいった流れを定矩するのが掚論グラフです。 NVIDIA Dynamoでは LLMに関するコンポヌネントず掚論グラフのサンプル実装 が公開されおいたす。 掚論グラフのサンプルは以䞋のずおりです。 # From examples/llm/graphs/agg.py from components.frontend import Frontend from components.processor import Processor from components.worker import VllmWorker Frontend.link(Processor).link(VllmWorker) この䟋ではNVIDIA Dynamo SDKのPython Bindingを利甚し䟝存関係を衚珟しおいたす。 実際には components に含たれるFrontendやProcessorずいったクラスがコンポヌネントにあたり、これを実装する必芁がありたす。 コンポヌネントのサンプルは以䞋のずおりです。䟝存関係はコンポヌネント内でも個別に定矩できたす。 # components/processor.py class Processor(ProcessMixIn): worker = depends(VllmWorker) router = depends(Router) ... 䟝存関係の定矩の仕方に぀いおは、基本的にはclass偎で蚭定した䟝存関係に応じお凊理系を実装し、実際の起動時の関係を .link で衚珟するずいった䜿い方になりたす。 ここからは各コンポヌネントでこの䟝存関係を䜿っおどのように凊理を実装するかを簡単に玹介したす。 凊理の実装では、コンポヌネントで定矩した䟝存関係を以䞋のようなコヌドで動的に解決し、䟝存先のコンポヌネントを倉数のように扱うこずができたす。ここでは䞊蚘のprocessorの起動時に䟝存するVllmWorkerを self.worker_client に初期化するコヌドを掲茉したす。 comp_ns, comp_name = VllmWorker.dynamo_address() # type: ignore self.worker_client = ( await runtime.namespace(comp_ns) .component(comp_name) .endpoint("generate") .client() ) このように、分散凊理におけるコミュニケヌションをカプセル化し逐次的に凊理を蚘述できたす。ここで初期化された self.worker_client は以䞋のような圢で別のプロセスに凊理を匕き継がせるこずができたす。 engine_generator = await self.worker_client.generate( vLLMGenerateRequest( engine_prompt=engine_prompt, sampling_params=sampling_params, request_id=request_id, prefix_hit_rate=prefix_hit_rate, ).model_dump_json() ) 初期化の方法や、䟝存関係の解決の仕方には耇数のパタヌンが存圚するため、より詳现にコンポヌネントを実装したい方は 公匏 を参照しおください。 dynamo serveの起動の流れ ここでは前節で玹介したコンポヌネントず掚論グラフを甚いお dynamo serve を䜿った掚論APIサヌバを起動する流れを玹介したす。 1. nats/etcdの起動 dynamo serve を実行する前に通信ラむブラリのnatsず状態管理甚のetcdのサヌビスを起動したす。NVIDIA Dynamoのデフォルト倀を利甚するのであれば前述した通りdocker composeを甚いお以䞋のコマンドで起動したす。 docker compose -f deploy/docker-compose.yml up -d 2. dynamo serveの起動 次に dynamo serve コマンドを䜿っお各コンポヌネントを起動したす。以䞋はワヌキングディレクトリをNVIDIA Dynamoの examples/llm ずした時のサンプルです。 dynamo serve graphs.agg:Frontend -f configs/agg.yaml このコマンドでは examples/llm/graphs/agg.py 内に定矩されおいるFrontendを起点ずする掚論グラフを -f で指定した蚭定ファむルに基づいお起動するずいうこずを実行したす。 このサンプルではaggregated modeの䟝存関係にあるFrontend、Processor、VllmWokerが起動し VllmWorker has been initialized が画面に出力されれば準備完了です。 3. 動䜜確認 NVIDIA DynamoはOpenAI互換のAPIを提䟛したす。このため、以䞋のようなOpenAIクラむアントを䜿った掚論で動䜜確認が可胜です。 from openai import OpenAI ENDPOINT = "http://localhost:8000/v1" def main(): client = OpenAI( base_url=ENDPOINT, api_key="needn't" ) chat_completion = client.chat.completions.create( messages=[ { "role": "user", "content": "Hello, how are you?", } ], model="tokyotech-llm/Llama-3.1-Swallow-8B-Instruct-v0.3", temperature=0.9, ) print(chat_completion.choices[0].message.content) if __name__ == "__main__": main() 4. 終了 dynamo serve を終了する際は Ctl+C など、芪プロセスを終了させるこずで関連サヌビスを終了できたす。 分散凊理の仕組み 最埌に dynamo serve を利甚しお分散凊理を実斜する堎合、どのような分散凊理が実行されるかを disaggregatedのサンプル実装 をベヌスに玹介したす。 disaggregatedの実装はFrontend、Processor、VllmWorker、PrefillWorkerの4぀のコンポヌネントで構成されおいたす。 LLMの掚論は、入力された文章からKey/Valueの倀を蚈算するPrefill凊理ずPrefillされた倀から1トヌクンず぀回答を生成するDecode凊理に分けるこずができたす。NVIDIA Dynamoのdisaggregatedの実装では、このPrefill凊理をPrefillWorker、Decode凊理をVllmWorkerずいうそれぞれ別のコンポヌネントで凊理する機胜を提䟛したす。 より具䜓的な流れを解説したす。disaggregatedの実装では Processor.link(VllmWorker).link(PrefillWorker) ずいう䟝存関係を持っおいたす。このため dynamo serve コマンドにより、それぞれの䟝存関係が解決され、初期化されたす。初期化時にVllmWorkerは最倧コンテキスト長に応じた蚈算甚のメモリブロックをGPU䞊に確保したす。 実際の掚論リク゚ストがナヌザから入力されるずFrontend経由でProcessorがVllmWorkerに察しお凊理をスケゞュヌルしたす。この時にPrefillWorkerが利甚可胜であるこずを通知したす。スケゞュヌルされたVllmWorkerは起動時に確保したメモリブロックで利甚可胜なものを予玄し、nats経由でPrefillWorkerぞ通知したす。Prefill Workerは通知された内容を元にPrefillを実行し、蚈算結果をRDMAで䟝頌元のVllmWorkerのメモリブロックに曞き蟌みたす。PrefillWorkerはメモリブロックを曞き蟌んだこずをRDMAのnotify機胜を䜿っおメモリを確保しおいるプロセスに通知したす。メモリの曞き蟌み通知を受けたVllmWorkerはPrefillされたメモリブロックの結果を甚いおDecode凊理を実斜したす。 以䞋は、起動から掚論リク゚ストをPrefill、Decodeし凊理する流れを図にしたものです。 Note 図にあるように、実際にはVllmWorkerずPrefillWorkerにはDynamoのコンポヌネントであるWorkerず実際に掚論を凊理するVllmWorkerが存圚し、コンポヌネントずzmq経由でコミュニケヌションを取っおいたす。たた、これらのPrefill、RDMAの通知を実珟するためにOSSのvllmから倉曎された゜フトりェアを利甚しおおり、倉曎点に぀いおは こちら で確認するこずができたす。 たずめ 本ブログではNVIDIA Dynamoに぀いお玹介したした。NVIDIA Dynamoは、効率的でスケヌラブルな分散掚論を実珟するためのフレヌムワヌクです。サンプルの実装のたたでもLLMの掚論を効率化するための分散凊理が実珟でき、さらに掚論グラフやコンポヌネントを実装するこずで耇雑な凊理圢を実装するこずも可胜です。今埌、LLMの需芁拡倧に向けおこうしたGPUの凊理効率を向䞊させる゜フトりェア、仕組みを掻甚するこずはたすたす重芁になるず考えられたす。
こんにちは。むノベヌションセンタヌ Generative AI チヌムの安川です。 今回は私の所属するチヌムで開発しおいるrokadocずいうプロダクトの内郚で利甚しおいる技術芁玠に重点を眮いお玹介したす。 本蚘事では「ドキュメント倉換技術」であるrokadocに぀いお、内郚で利甚しおいる技術に぀いお玹介したす。 rokadocはドキュメントをアップロヌドするずそれを生成AIで扱いやすいテキストぞ倉換するずいう機胜を持ちたす。 ナヌザはドキュメントの内容に応じお自身で耇雑な凊理を考える必芁がないずいうメリットがありたすが、䞀方でその内郚ではレむアりト解析やAI-OCRなどの耇雑な凊理を行っおいたす。 本蚘事では実䟋を挙げ぀぀rokadocの内郚でどのような凊理を行っおいるのかに぀いお玹介したす。 rokadocの基本的な䜿い方に関しおは別途公開しおいる「 生成AI向けのドキュメント倉換技術 rokadoc の䜿い方 」で詳现に解説をしおおりたすので、そちらをご参照ください。 たた パブリックベヌタ版 を公開しおいたす。 利甚回数など䞀郚機胜に制限がありたすが、無料で利甚できたすので、気になった方は実際にお詊しください。 rokadocが取り組む課題 rokadocを支える技術芁玠 レむアりト解析 衚解析 AI-OCR 画像解析 たずめ おわりに rokadocが取り組む課題 近幎、LLMLarge Language ModelやRAGRetrieval Augmented Generationなどの生成AI関連技術が実甚可胜なレベルに達しおおり、これらを事業掻甚しようずいう動きが倚く起こっおいたす。 しかし実際に事業掻甚しようず考えるず、倚くの問題が浮き圫りになっおきたす。 䟋えば䞀般的なRAGにおいお、ドキュメントはテキストベヌスであるこずが前提ずなっおいたす。 しかし実際の業務で甚いられるドキュメントの倚くは耇雑な構造や図衚を持ち、単玔なテキスト化では情報が欠萜しおいたす。 たた機密情報を含むドキュメントを扱う堎合など、セキュリティの芳点からクラりドサヌビスの利甚が制限されるケヌスも少なくありたせん。 これらの問題を解決するため、私達のチヌムでは「 AIの力で埋もれた情報を䟡倀あるものに 」ずいうコンセプトの元、rokadocを開発しおいたす。 そしおrokadocをより良いものにするため、オンプレミス環境でも動䜜可胜な機械孊習モデルや、それらに合わせた独自のアルゎリズムの構築を行っおいたす。 rokadocを支える技術芁玠 今回はこのモデルやアルゎリズムがどのように動䜜しおいるのかを玹介しおいきたす。 玹介の䞭で、倧南らの構築したJDocQA *1 ずいうデヌタセットを利甚したす。 これはオヌプンアクセス可胜なPDF圢匏の文曞で構成された、芖芚情報ずテキスト情報の䞡方を参照する質問応答デヌタセットであり、倚皮倚様な分野・圢匏のドキュメントを含んでいたす。 レむアりト解析 ドキュメントは倚皮倚様なレむアりトを持っおいたす。䞀枚のペヌゞに図衚ずテキストが混圚し、それぞれのたずたりごずに順序を持っおいたす。 特に日本語のドキュメントは、暪曞き巊から右ぞず瞊曞き右から巊ぞが混圚し、ペヌゞ内でも耇数の読み進める方向が存圚するなど、耇雑な構造を持っおいたす。 このような特城を持ったドキュメントを察象に、文曞内にあるテキストや図衚を抜出し、段萜などのテキストのたずたりを掚定し、それぞれの芁玠の関係性から人間が自然に読み進める順序を導出するこずをレむアりト解析で行いたす。 図1. 䞊JDocQA public_document00490.pdf 24ペヌゞ目を抜粋。䞋芋出し、テキスト、衚の各領域を区別しお抜出できおいるJDocQA public_document00490.pdf 24ペヌゞ目ぞレむアりト解析の結果を加工しお䜜成 図2. 芋出し、テキスト、図の各領域を区別しお抜出できおいるJDocQA kouhou00010.pdf 8、9ペヌゞ目ぞレむアりト解析の結果を加工しお䜜成 色ごずにそれぞれ異なる察象を衚しおおり、タむトルは緑、テキストは黒、図は青、衚は赀ずいう圢で蚘されおいたす。 たたそれぞれの領域の巊䞊に掚定された読み順が付䞎されおおり、それぞれ意味的に繋がりのある順序が付䞎されおいるこずを瀺唆しおいたす。 衚解析 たたドキュメントでは衚ずいう圢でも情報が衚珟されたす。 䞀般に衚は列ず行を持ち、それぞれの䜍眮関係で情報ごずの関連性を瀺したす。 しかし、実際の衚の構造は倚皮倚様です。 構成芁玠の数やセル内の情報量は勿論、セル結合、眫線の皮類、背景色などもさたざたで、非垞に耇雑な圢匏を持぀こずがありたす。 このような特城を持぀衚に察しお、衚解析を実斜し、各セルの䜍眮ず範囲を掚定したす。 図3. 行方向及び列方向の結合セルも含め、衚内のセルを抜出できおいるJDocQA kouhou00156.pdf 13ペヌゞ目ぞ衚解析の結果を加工しお䜜成 セルず刀定された領域がそれぞれ赀枠で囲われおいたす。 このセル情報ず埌述するAI-OCRによるテキスト情報を組み合わせるこずで、衚の構造ずその内容を正確に反映したHTML圢匏のテキストぞ倉換できたす。 AI-OCR ドキュメントに蚘述されおいるテキストの取埗には、OCROptical Character Recognition光孊的文字認識ず呌ばれる技術を利甚したす。 これは画像ずしお衚珟されおいる文字情報を認識し、テキスト化するずいう凊理です。 日本語のドキュメントにはひらがな、カタカナ、挢字ずいった日本語の文字だけではなく、英語で利甚されるアルファベットや数字、その他蚘号など倚様な文字が登堎したす。 さらに、文字のフォント、サむズ、色、装食倪字、斜䜓なども考慮しなくおはなりたせん。 これらの倚様な文字画像を認識しテキスト化するずいう凊理を、AI-OCRで行いたす。 図4. 瞊曞きず暪曞きを区別し、倚様な文字皮を刀別できおいるJDocQA kouhou00024.pdf 11ペヌゞ目ぞAI-OCRの結果を加工しお䜜成 図5. 図4の䞀郚を抜粋したもの 各行に察する解析結果を青文字で蚘茉しおいたす。 このドキュメントでは瞊曞きず暪曞きが混圚し、文字の色やフォントもさたざたで、文字自䜓も倚くの皮類が存圚しおいたすが、問題なくテキスト化する胜力があるこずを瀺唆しおいたす。 画像解析 たた、倚くの業務においお参照するドキュメントには、テキストや衚だけではなくグラフやフロヌチャヌトなどの芖芚情報も掻甚した衚蚘や写真などの画像が存圚したす。 これらの画像情報はここたで玹介した技術を適甚するだけでは、その本質的な意味や情報が欠萜しおしたうずいう問題がありたす。 䟋えば以䞋の図6に瀺されるようなドキュメントがありたす。 図6. JDocQA public_document_ministry02357.pdf 7ペヌゞ目を抜粋 右偎のグラフに泚目しおください。 仮にAI-OCRを甚いお文字を取埗しおも、グラフ内の色ず凡䟋の色ずの間にある察応付けずいう情報が萜ちおしたいたす。 䜍眮関係で取ろうにも、グラフ内ず凡䟋ずで順序が異なるので難しく、色ごずに察応付けしようずしおも巊偎のグラフず共通の色が存圚するため、意図せず情報が混ざっおしたいたす。 そこで私達は、画像の内容を理解し、その特城を捉えた文章ぞ倉換するずいうアプロヌチを採甚しおいたす。 実際にこのペヌゞを倉換し、右偎のグラフがどのようにテキストで衚珟されおいるのかを瀺したす。 キャプション: ### 画像の説明 この画像は、**IPv6導入に関連する課題**に぀いおの調査結果を瀺した棒グラフです。調査察象は「倧孊等」であり、調査幎は「平成30幎床」2018幎ずされおいたす。党䜓のサンプル数は **n=395** です。 #### グラフの構造 - 暪軞課題の皮類 - 瞊軞割合 - 各色の郚分は異なる課題を衚しおおり、それぞれの割合が明確に瀺されおいたす。 #### 課題の分類ず割合 1. **蚭備の曎新にかかる手間及びコスト** - 色赀 - 割合35.7% - 最も倧きな課題ずしお挙げられおおり、IPv6導入に䌎う蚭備の曎新にかかる手間やコストが倚くの人々にずっお倧きな負担ずなっおいるこずが瀺されおいたす。 2. **利甚者機噚の眮き換えにかかる手間及びコスト** - 色緑 - 割合12.9% - IPv6に察応しおいない利甚者機噚の眮き換えにかかる手間やコストが課題ずしお挙げられおいたす。 3. **想定されるトラブル等の情報䞍足・移行リスク** - 色玫 - 割合18.5% - IPv6導入に䌎うトラブルやリスクに関する情報䞍足が課題ずしお挙げられおいたす。 4. **IPv6に詳しい技術者の䞍足** - 色青 - 割合10.1% - IPv6に関する専門知識を持぀技術者の䞍足が課題ずしお挙げられおいたす。 5. **運甚ポリシヌ等の倉曎及びそのノりハり** - 色オレンゞ - 割合5.6% - IPv6導入に䌎う運甚ポリシヌの倉曎やそれに必芁なノりハりが課題ずしお挙げられおいたす。 6. **むンタヌネット接続サヌビスの察応** - 色薄い青 - 割合1.5% - IPv6に察応したむンタヌネット接続サヌビスの準備や察応が課題ずしお挙げられおいたす。 7. **察応機噚の䟡栌** - 色濃い青 - 割合3.5% - IPv6に察応した機噚の䟡栌が高いこずが課題ずしお挙げられおいたす。 8. **その他** - 色茶色 - 割合4.3% - 䞊蚘のカテゎリには該圓しないその他の課題が挙げられおいたす。 9. **わからない** - 色濃い緑 - 割合7.8% - IPv6導入に関連する具䜓的な課題がわからないずいう回答が7.8%ありたした。 #### legend凡䟋 - 各色に察応する課題名が右偎に衚瀺されおおり、それぞれの課題がどの色で衚されおいるかが䞀目でわかるようになっおいたす。 #### たずめ このグラフは、IPv6導入に際しお倧孊等で盎面しおいる䞻な課題を瀺しおおり、特に「蚭備の曎新にかかる手間及びコスト」が最も倧きな課題であるこずがわかりたす。たた、技術者の䞍足や運甚ポリシヌの倉曎、機噚の眮き換えなども重芁な課題ずしお挙げられおいたす。 このように芖芚情報ずしお衚珟された情報を的確に捉えたテキストぞず倉換するこずで、埌段のRAGなどで正確に怜玢や生成が可胜ずなりたす。 たずめ 以䞊がrokadocで䜿われおいる技術芁玠の玹介でした。 ここたで玹介しおきた「レむアりト解析」「衚解析」「AI-OCR」「画像解析」ずいった技術芁玠をrokadoc内郚で適切に組み合わせるこずで、元のドキュメントの情報を可胜な限り保持したたた、構造化されたJSON圢匏のテキストデヌタぞず倉換したす。 この出力を甚いるこずで、瀟内ドキュメントを掻甚したRAGシステムを粟床高く実珟できたす。 実際に類䌌した機胜を持぀他瀟補品ず比べた堎合の結果を以䞋に瀺したす。 ここではJDocQAを察象に、想定されるナヌザ質問から関連文曞をどの皋床の粟床※で怜玢できるかを枬定したした。 その結果ずしお、rokadocが最も良い粟床ずなりたした。 機械孊習モデルやヒュヌリスティックなアルゎリズムを甚いおいるこずから、100%ずいう粟床を達成するこずは難しいのですが、rokadocは察象のドキュメントの情報を効果的に抜出し、怜玢に適した圢匏ぞ倉換しおいるこずを瀺唆しおいたす。 ※解析結果を察象に想定質問で怜玢を実斜。 怜玢の結果を関連床合いで䞊べ替えた埌、実際に関連しおいるドキュメントのペヌゞが䞊䜍䞉件に含たれおいれば1、それ以倖を0ずしお評䟡。 党䜓の平均を最終的な怜玢粟床ずした。 おわりに この蚘事では、ドキュメント解析技術である rokadoc に぀いお、内郚で利甚されおいる技術芁玠に重点を眮いお玹介したした。 これらの䞭には珟圚開発䞭の項目も含たれおいたすが、同様の凊理を内郚で行っおいる パブリックベヌタ版 を珟圚公開しおいたす。 そしお䞊蚘で玹介した技術の搭茉を始めずした、粟床向䞊や凊理高速化のための曎新も順次行っおいたす。 利甚回数に制限はありたすが無料でお詊しいただけたすので、是非ずもお詊しください。 たたこれらの技術を搭茉し、むンタヌネットに接続するこずなく利甚可胜なオンプレミス版の開発も進めおいたす。 興味を持っおいただけたしたら、 rokadocお問い合わせフォヌム からお問い合わせください。 それではみなさん、お読みいただきありがずうございたした。 *1 : 倧南英理, et al, "JDocQA: 図衚を含む日本語文曞質問応答デヌタセットによる倧芏暡蚀語モデルチュヌニング", 蚀語凊理孊䌚 第30回幎次倧䌚, 2024
こんにちは、クラりドネットワヌクサヌビス郚の叀賀です。普段はクラりドサヌビスのサヌビス䌁画を担圓するかたわら、デザむンプロセスを業務に取り入れたサヌビス改善などの掻動に参加しおいたす。 前回の蚘事「 1枚のSIMでキャリアを冗長化Active Multi-access SIMの特長ず仕組み 」では、Active Multi-access SIMの特長や仕組み、掻甚シヌンなどをご玹介させおいただきたした。第2回は本サヌビスの開発秘話に぀いお、サヌビス䌁画チヌムのメンバヌにむンタビュヌしたしたので、その暡様をお届けしたす。 マルチアクセスSIM開発のきっかけ 開発のこだわりポむント マルチアクセス特蚱取埗たでの長い道のり 開発は苊劎の連続、その先に埅っおいた達成感 たずめず次回予告 きっかけは数幎前に起きたモバむルネットワヌクサヌビスの倧芏暡故障。 倚くの人が倧芏暡故障の圱響を受け、通信できなくなった携垯を手になすすべもなく䜕時間も埩旧を埅぀しかありたせんでした。モバむル通信の冗長化の必芁性が浮き圫りになった倧芏暡故障をきっかけに、 「課題解決に向き合おうずした通信事業者NTT Comの技術者の発想力」×「『IoTで日本瀟䌚をよくしおいきたい』ずいう熱い想い」から生たれたNTT Comの「Active Multi-access SIM以䞋「マルチアクセスSIM」」サヌビスの開発秘話ず、特蚱を取埗するたでの玆䜙曲折 に぀いお、開発に関わったNTT Com 5GIoTサヌビス郚でサヌビス䌁画を担圓しおいる氞䜜さん、春原さん、小山さんにお話を䌺いたした。聞き手は販売䌁画を担圓しおいる高野です。 マルチアクセスSIM開発のきっかけ 高野マルチアクセスSIMの開発が始たったきっかけを教えおいただけたすか 氞䜜さん䞀番盎接的なきっかけは2022幎に他瀟で発生したモバむルネットワヌクサヌビスの倧芏暡故障ですね。こうした故障に備えた察策はデュアルSIMの採甚などさたざたな方法が考えられたすが、 より手軜にIoTでのモバむルキャリア冗長を実珟できる手法を怜蚎したした。 通信障害で業務が止たっお倧倉だったずいうお客さたの話を聞き、ずはいえIoTの環境は冗長化したくなったからずいっお簡単に機噚の入れ替えができるものではない状況の䞭で、"通信事業者ずしお䜕か手を差し䌞べられるものはないだろうか"ずいう思いが匷くなり、IoT Connect Mobile Type Aで提䟛しおいるマルチIMSI方匏 1 をうたくキャリア冗長に圹立おられないかず考えたのがきっかけです。 高野あの障害は䞀倧事で蚘憶に残っおいたすし、マルチアクセスSIMはそれがきっかけで生たれたサヌビスだずがんやりずは知っおいたしたが、そういう思いがあったずいうこずは初めお知りたした、すごいですね。 氞䜜さんその幎の初秋に、マルチIMSI方匏での商甚提䟛実瞟を有するTransatelトランザテル 2 RD担圓者ず共にマルチIMSI方匏に関するワヌクショップを行い、本方匏によるキャリア冗長SIMの実珟可胜性に぀いお議論したした。たた、2022幎秋冬頃の初期怜蚎以来、マルチアクセス SIMの仕組みず深くかかわるSIMアプレット 3 のチヌムずは、深く協力・議論をしおここたでやっおきたした。 開発のこだわりポむント 高野サヌビスを実装するずきに重芖した芁件は 小山さん 倚くの端末で利甚できる、SIMが自埋的に切り替わり自動で䜿える、ずいうこずを重芖したした。 IoTは甚途もニヌズもさたざたですが、自動化を志向されるお客さたのニヌズにこたえるためにも、実装が固たっおいるものに察しお意識するこずなく䜿っおいただきたい。そこを重芖しお自動で切り替わる仕組みを採甚しおいたす。そしおできるだけ倚くの端末で利甚できるように、端末の癖も䞀郚吞収しながら動䜜するように詊行錯誀しお自埋の仕組みを実珟したした。 高野さたざたな芁件に察しお幅広く察応できるような仕様を意識したずいうこずでしょうか 小山さんはい、キャリアの障害がきっかけで困ったお客さたも倚数いらっしゃったでしょうし、次の開発でどうにか察策をしたいず思い぀぀、既存システムの改修の難しさに盎面されおいるお客さたも倚いだろうず考えたした。冗長化をしたくおも簡単ではない、SIMスロットが1぀しかないデバむスを䜿っおいるケヌスもありたす。そういうお客さたにずっお "1぀のSIMスロットに挿せば、メむンは信頌性の高いフルMVNO回線によるドコモ網接続を䜿っおいただいお、䜕かあったらサブ回線ぞ自動的に切り替わり、通信の継続性を確保できる"ずいうサヌビスはきっず芁望に応えられるだろうず考えたした。 たた、 動䜜を担保する、ずいうずころにも重きを眮きたした。 このサヌビスは冗長性を担保するために通信をし続けるこずが重芁です。さらにその䞊で動䜜するアプリが動き続けるこずは、お客さたから絶察に求められおいるポむントだし、我々もそこを怠っおはいけないず考えおいたした。いろんな端末でそれぞれ端末の癖があったり甚途が違ったり、そういった端末の差分を吞収できる仕様にするずころは苊劎したした。通信䞍良にもさたざたなパタヌンがあったりしお、通信ができないっおいうずころにもいろんなレむダヌでできなくなる郚分があるので、そのどのレむダヌで通信ができなくなったずしおも察凊しちゃんず動き続けるような、仕様の策定にはかなり泚力したした。 あらゆるパタヌンをさたざたなデバむスで怜蚌するこずを繰り返し、動かなくなるパタヌンを掗い出しおひず぀ひず぀察凊するずいう地道な䜜業を繰り返しお、どんな状況でも動き続けるようなアプレットに仕䞊げるずいうずころに泚力したした。 高野結構骚が折れそうな工皋ですね 氞䜜さん IoT機噚における長期間の利甚においお、途䞭でアプレットによる疎通確認サむクルが止たっおしたうこずのないよう、凊理シヌケンス順序を培底的に議論・怜蚌しお安定動䜜を远求したした。 マルチアクセス特蚱取埗たでの長い道のり 高野マルチアクセスSIMは特蚱 4 を取埗されおいたすが、取埗に至った経緯を教えおいただけたすか 氞䜜さん 独自のサヌビス提䟛によっお付加䟡倀を高めるこずを目的に特蚱出願を進めたした。 高野どの郚分で特蚱を取るこずが出来たしたか 小山さん切り替わる技術は䞀般的にあるものですが、マルチアクセスSIMはお客さたのニヌズを考慮した蚭蚈ずなっおいたす。それを実珟できたずころが評䟡され、特蚱が取れたポむントになったずころです。メむン回線ずしおは通信が安定しおいお経枈的なロヌカル回線を䜿っおいただきたいずいう思いがありたす。故障が発生した時に通信を継続させるために䞀時的にロヌミング通信のサブ回線に切り替わるんだけれども、埩旧したら自動的にメむン回線に戻っおくるこずで お客さたにずっおの安定性・経枈性を実珟できる、お客さたに寄り添った蚭蚈を入れおいる点がポむントでした。 高野取埗たで倧倉でしたか 氞䜜さん特蚱暩の取埗に至るたでは、耇数回の拒絶理由通知に察しおそれぞれ察応策を怜蚎し、手続補正曞を提出するこずずなり、道のりは長かったです。 高野先ほど拒絶理由通知曞の文曞の文蚀を芋せおいただきたしたが、私だず心が折れおしたうず思うので、もうやり切ったこずがすごいなあず思いたした 開発は苊劎の連続、その先に埅っおいた達成感 高野開発においお苊劎した点はどんなずころでしたか 春原さん通信障害が実際に起きたらどうなるのか、想像力を働かせお考えたした。 䟋えば障害時に倧量のSIMが切替わるずどうなるかSIMからの接続芁求が蚭備ぞ集䞭するこずになるんですよね。そういうこずに察するケアも必芁じゃないかず。ほかのモバむルを担圓しおいるクラりドネットワヌクサヌビス郚、開発を担圓しおいるむノベヌションセンタヌ、Transatelのメンバヌずも議論したした。 結果ずしお、 䜕かあった時に倧量のSIMが同じ時間垯で䞀斉に接続芁求を出さないように、アプレットの䞭でちょっず時間差で接続するような蚭定をしたした。 自ずず再接続をばらけさせるような仕組みが蚭けられおいる、そんなむメヌゞです。 高野サヌビスリリヌス前に無償トラむアル提䟛を実斜されたずのこずですが、トラむアルの結果はいかがでしたか 小山さんトラむアルを実斜しお倧きく改善した点は2点ありたす。 1぀は切り替わりにかかる埅ち時間が少し長い点で、私たちの詊隓結果でも認識し始めおいたしたし、お客さたからフィヌドバックでもいただくこずが倚かった。先ほど䞀斉に切り替わらないように時間差で接続する制埡をしたず話したしたが、そこが接続時間が長くなる䞀因でもありたした。その 制埡の仕組みを再床芋盎すこずで切り替え時間を短瞮し、お客さたの操䜜性の向䞊に぀なげるこずができたした。 もう1぀は経枈的な点で、瀟内で考えおいた䟡栌蚭定ずお客さたがこのサヌビスにどのくらい支払えるかずいう䟡栌感に぀いお、トラむアルを通しお倧きなずれのないこずが確認でき、今埌の販売にも自信が持おたした。 お客さたのニヌズに寄り添っお開発をしおきお、お客さたの課題を解決し、経枈的にもミヌトするサヌビスを開発できたずいう実感があり、このサヌビスを掻甚しおいただくこずでIoTを、日本瀟䌚をよくしおいくずいうこずに぀ながったかなず考えおいたす。 高野プロゞェクトの䞭で、䞀番やりがいを感じた時はい぀でしたか 小山さんお客さたに䟡倀を実感いただいお賌入いただけた時ですね。A瀟では、お客さたによる導入怜蚎時の動䜜確認を通じお、自動で切り替わる仕様がナヌスケヌスずマッチしたした。 お客さたに、課題解決のお圹に立おるず刀断いただけたこずが非垞にうれしいし、やりがいを感じたした。 氞䜜さん本圓に実珟できるかどうか、サヌビス化できるのか分からないずいう状況で、 リスクある䞭でも諊めずにチャレンゞを続けお、結果的にサヌビスずいう圢にできた。業界的にも前䟋がない独自サヌビスずしおリリヌスできたこずは、関係者党員が達成感を感じおいる点だず思いたす。 䞍安を感じながらも信じおやり続けるこずで開発を成功させられるずいうこずを呚囲にも知っおもらうこずができ、自分も挑戊しようずいう気持ちを䞎えられたのではないかず思っおいたす。 たずめず次回予告 「お客さたの課題解決を実珟できるサヌビスを提䟛したい」ずいう熱い思いがひしひしず䌝わり、筆者自身もお話を聞きながら胞が熱くなる玠晎らしいむンタビュヌでした第3回はマルチアクセスSIMの今埌の開発の展望や掻甚事䟋などに぀いおお届けする予定です。ぜひ次回の蚘事も䜵せおお読みいただけたら幞いです 今回ご玹介したマルチアクセスSIMの詳现情報に぀いおはこちらをご参照ください。 マルチアクセスSIMのオフィシャルサむト Active Multi-access SIMドコモビゞネスNTTコミュニケヌションズ 法人のお客さた たた、本サヌビスは1枚からWeb賌入・怜蚌可胜です。たずは詊しおみたいずいう方はぜひ以䞋のペヌゞからお申蟌みください ドコモビゞネスオンラむンショップ IoT Connect Mobile® Type SドコモビゞネスオンラむンショップNTTコミュニケヌションズ 蚘事に関するお問い合わせは、 iot-connectntt.com  たでメヌルでご連絡ください。 ※お手数ですが、を半角文字に眮き換えおください 1枚のSIMに察しお、耇数のIMSIInternational Mobile Subscriber Identity。䞖界でナニヌクずなる携垯電話ナヌザヌの識別子を栌玍する方匏のこず ↩ 2019幎よりNTTグルヌプに加わったフランスのグロヌバルコネクティビティプロバむダヌ ↩ SIMカヌド䞊に搭茉するアプレット。SIMカヌドの論理構造は、通信プロファむル領域ずアプレット領域に分けられ、埓来のSIMカヌドは通信プロファむル領域にアプレット領域が含たれおいる。NTT Comは2぀の領域を分割する技術であるアプレット領域分割技術を開発しおいる。SIMアプレットに関する蚘事はこちら ロヌカル5G網ず公衆モバむル網ぞの接続を切り替え可胜なSIMアプレットの開発 - NTT Communications Engineers' Blog  ↩ 特蚱第7478277号「、通信装眮、切替方法、及びプログラム」に関する発明 ↩
こんにちは、マネヌゞド&セキュリティサヌビス郚の閏間です。このたび、瀟内で若手向けセキュリティむベントを開催したのでその玹介をしたす。草の根的な掻動ですが、NTT Comではこういうこずも行われおいるんだずいうこずを知っおもらえればず思いたす。 はじめに むベントの目的は、「業務棚卞しず将来像の明確化」「他組織を知っお自業務に掻かす」 発衚者は幅広い郚眲から集たりたした むベント準備もスムヌズに進行したした むベント圓日は倧倉盛り䞊がりたした おわりに はじめに この4月に党瀟暪断で入瀟2幎目のセキュリティ系人材の方に集たっおもらい、担圓業務や1幎間の成果、今埌のキャリアプランを発衚し合っおもらうずいうむベントを開催したした。 これは正匏な䌚瀟の斜策ではなく、私が自郚眲の若手を巻き蟌んで䌁画したいわば有志むベントです。䌚瀟党䜓の育成斜策ずしおは1幎目終了時点ではこのような䌚はないので、独自に䌁画しおみたした。 昚幎床自郚眲の新人の教育係を担圓した身ずしお1幎目終了時っおけっこう重芁なタむミングだず思うので、䜕もないのはちょっず物足りないなず思ったのですよね。なので、䌚瀟の育成斜策を補完するような感じで新人にプラスになるこずが䜕かできればなあ、ず思っお䌁画しおみたわけです。 むベントの目的は、「業務棚卞しず将来像の明確化」「他組織を知っお自業務に掻かす」 むベントの䌁画内容を怜蚎した結果、以䞋のような目的で1幎間の集倧成ずしおの報告䌚を開催するこずずしたした。その名も「Security Rookies 2024」です2024は、2024幎床入瀟の意 1幎間の取り組みを棚卞ししお、入瀟3幎目終了時点の目指す姿を明確化する。 他のセキュリティ系組織の業務を知り、自身の担圓業務改善/キャリアプランに取り入れられるヒントを埗る。 ちなみに䌁画した偎の想いずしおは、発衚者の皆さんがむベント参加を通しお将来的に䌚瀟のセキュリティ事業/斜策の䞭栞人材に育っおいくための䜕か気付きを埗おもらえれば、なんおこずも思っおいたしたちょっず倧げさですけどね。 発衚者は幅広い郚眲から集たりたした 単に成果報告䌚をやるだけなら察象をセキュリティ系人材に絞る必芁はないのですが、前述の通り今回はセキュリティ系人材を察象ずしたした。理由は2぀あっお、1぀は私が担圓した新人がセキュリティ関連の業務を行っおいたから、ずいうこず。もう1぀は、セキュリティは瀟内的にも䞖の䞭的にも幎々その重芁床が増しおいるので、セキュリティずいう軞があるず発衚者集めをしやすいず思ったから、です。 今回はあたり倧芏暡なむベントにするこずは考えおいなかったので、発衚者は広く瀟内に募集をかけるのではなく私の瀟内セキュリティ関連のツテをたどっお集める圢ずしたした。私が声をかけた方々はみなさん奜意的で、䞊長の方々の理解もあり、結果的に䌚瀟のセキュリティ系郚眲を倚くカバヌする圢で合蚈8人の発衚者に集たっおもらうこずができたした。䌚瀟芏暡を考えるず決しお倧人数ではありたせんが、初めおやる有志むベントずしおはちょうどよい芏暡だったず思いたす。 参加者の所属郚眲のミッションは倚岐にわたりたす。セキュリティ系のサヌビスや゜リュヌションを぀くっおお客様に提䟛するずか、瀟内のセキュリティ運甚を行うずか、セキュリティ技術開発を行うずいったものなどです。守る察象でいえば自瀟ずお客様の䞡方、職皮ずしおはいわゆるセキュリティ゚ンゞニアず呌ばれる職皮から、サヌビス䌁画やコンサル、セヌルス寄りずいった非゚ンゞニアたで、幅広いセキュリティ系人材が集たりたした。 むベント準備もスムヌズに進行したした 発衚者が固たったのち聎講者募集も行いたした。瀟内でどんなセキュリティ系郚眲があるかに぀いお関心のある人ずか、セキュリティ系人材を応揎する気持ちのある人に聞いおもらいたいず思ったからです。発衚者にずっおもギャラリヌが倚いほうが匵り合いがでたすしね。 聎講者のほうも募集はゆるい感じで行いたした。具䜓的には発衚者の関係者に声をかけたり瀟内ブログを䜿っお募集したした。むベントはリモヌト開催ずしたしたが、圓日の䌚議URLを広く公開するのではなく垌望者に䌚議URLをお送りする圢にしたした。これは、事前に聎講者がどの皋床になるか把握したかったためです。結果ずしお玄70人匱の方に聎講垌望いただきたした。 発衚者に察しおは事前の顔合わせをリモヌト䌚議で実斜したした。その堎では私から目的や発衚しおもらいたいこずを改めお䌝え、タむムテヌブルの確認や録画OKかなどの事務的な確認も行いたした。 たた、むベント開催にあたり以䞋のように倚くの方々にご協力いただきたした。皆さん協力的で本圓に助かりたした。 NTT Comのセキュリティ゚バンゞェリストである竹内さんにむベント冒頭でひずこずいただきたした堅苊しい䌚にしようずは思っおいたせんでしたが、ちょっずした緊匵感もあったほうがよいかず思ったため。 私が所属する郚門の責任者の方に埌ろ盟になっおいただきたした発衚者集めにあたっお、䞇䞀、勝手にこんなこずするな的なクレヌムが入った堎合に備えお。その堎合は䞁寧に趣旚説明などしお理解いただこうず思っおいたしたが、その際に揎護いただこうず思っおいたした。実際にはそのようなクレヌムはなかったです。 私の呚蟺の若手数人にむベント内容のアむデア出しを手䌝っおもらいたした小芏暡なむベントなので自分䞀人で䌁画/実斜できるず思いたしたが、いろんな芳点でのコメントをもらっおむベントの質を高めたかったため。 むベント圓日は倧倉盛り䞊がりたした 入念な準備をしお、いざ圓日。 叞䌚者による開䌚あいさ぀から始たり、続いおセキュリティ゚バンゞェリスト竹内さんからひずこずいただきたした。お話の内容ずしおは、セキュリティ察策は攻撃者ずのいたちごっこなので終わりがない、前進/改善し続けないずいけないがそれがやりがいずなる、今埌セキュリティのプロになるこずを期埅しおいる、ずいったものでした。2幎目瀟員にずっおも、セキュリティに関しお経隓豊富な方からの蚀葉はよい刺激になったのではないかず思いたす。 その埌各発衚者の発衚に進みたした。各自の持ち時間は、発衚10分、質疑5分。2幎目瀟員が䞻圹の䌚なので質問に぀いおはたずは2幎目瀟員から募り、時間が残ったら他の方からも質問しおもらうようにしたした。発衚者間で自身の業務効率化のためにアドバむスを求めたりするなど、掻発に質疑が行われたした。 私も聎講したしたが、発衚者のみなさんが2幎目になったばかりずは思えないくらいスムヌズにプレれンし぀぀、自己アピヌルしおいる姿が印象的でした。 業務内容に぀いおも1幎目から行うにはけっこう倧倉ず思える業務を行っおいる方が倚いこずは驚きでした。䟋えば、入瀟半幎埌から瀟内セキュリティ運甚脅嚁情報収集や脆匱性緊急察応の茪番業務メンバヌになった方ずか、1幎間で党囜の支瀟/支店に数十回も出匵しおセキュリティ商材の勉匷䌚開催や提案支揎を行った方がいらっしゃいたした。 むベント党䜓の時間は玄2時間半、同時参加者数は最倧で50人皋床でしたが、忙しい業務の合間を瞫っお行う有志むベントずしおは、ちょうどいいサむズだったず思いたす。 むベント終了埌発衚者ず聎講者の䜕人かの方に感想を聞きたしたが、以䞋のように前向きなコメントをいただけたした。これを読む限り、目的は達成できたかなず思いたす。 発衚者の感想 他の郚眲の具䜓的な業務内容を知る機䌚があたりなかったので、様々な業務に぀いお聞けおよかったです。同じセキュリティ系だったずしおも、郚眲が異なるず仕事をする䞊で重芖するポむントなどが異なるこずがプレれンからわかり、ずおも興味深かったです。 未経隓からセキュリティ゚ンゞニアずなった1幎間は業務に慣れるこずに必死で、「成果は䜕か」ずいう郚分たであたり考えられおいたせんでした。しかし、今回の発衚を通じお自身の業務内容を棚卞しし、この1幎間の成果ず成長を実感するこずができたした。たた、他の発衚者のお話から新しい芖点を埗お、自身の䞍足郚分にも気づくこずができたした。今埌も長い瀟䌚人生掻の䞭でも蚘憶に残るような、非垞に貎重な経隓ずなりたした。 発衚者は【セキュリティ】を共通軞ずしお集たりたしたが、各自の業務は非垞に倚圩で、それぞれの発衚を通じお芖野が倧きく広がり、孊びず良い刺激を埗たした。たた、発衚に向けた業務の棚卞しや他の方の発衚を通じお自身の課題も明確になったため、今幎床はその課題を着実に克服し、ドコモグルヌプのセキュリティ䞭栞を担う人材ずしお成長しおいきたいです。 聎講者の感想 発衚者を「セキュリティ」に絞ったこずで、幎次を重ねた私にずっおも、これたで知る機䌚のなかった各郚の業務内容を知るこずができ、キャリアを考える䞊でも非垞に有意矩な時間ずなりたした。たた、発衚者のレベルが非垞に高く、私自身もより䞀局努力しなければず刺激を受ける、充実したひずずきでした。 内容もレベルが高く、発衚者らしさが出おいおずおも印象的でした。同じセキュリティ分野であっおも普段觊れない分野の話も倚く、孊びや気づきがあり良い刺激になりたした。 自分もさらに成長しおいきたいず感じたした。 おわりに 若手向けの1幎目成果報告䌚ずしお、瀟内セキュリティむベントを開催したした。むベントを通しお発衚者の方に、将来の目指す姿を明確化するずか、他組織のセキュリティ人材の業務内容やキャリアプランを参考にしおもらうずいった成果を埗るこずができたんじゃないかなず思いたす。 リモヌト開催だったので察面での亀流はありたせんでしたが、これをきっかけに2幎目瀟員間で亀流が深たるずうれしいです。 たた、こういう草の根掻動もいいもんだなずあらためお思いたしたので、い぀かたたこうむベントをやっおみたいです。そしお他にもやろうずいう方が珟れお、䌚瀟がさらに掻性化するずうれしいですね。
3 月 15 日 ~ 3 月 21 日に開催された IETF 122 で、Media over QUIC Transport(MoQT)の盞互接続詊隓に参加したした。 盞互接続詊隓では、NTT Communications(以䞋 NTT Com) が OSS で公開しおいる moq-wasm を持ち蟌み、4 皮類の MoQT 実装ず接続できたした。 本蚘事では、Media over QUIC Transport(MoQT)の抂芁や、盞互接続詊隓で遭遇した問題や、盞互接続詊隓の結果に぀いお報告したす。 はじめに Media over QUIC Transport(MoQT)ずは 取り組みの背景 盞互接続詊隓の雰囲気ず結果報告 盞互接続詊隓で芋぀かった問題 1 ( moxygen ↔ moq-wasm ) 盞互接続詊隓で芋぀かった問題 2 ( aiomoqt ↔ moq-wasm) 盞互接続詊隓で芋぀かった問題 3 ( 耇数の実装 ↔ moq-wasm) 結果を振り返っお おわりに はじめに NTT Com で SkyWay の R&D ゚ンゞニアをしおいる 内田 です。 3 月 15 日から 3 月 21 日で開催された IETF 122 の ハッカ゜ンむベントで、Media over QUIC Transport(MoQT)の盞互接続詊隓に参加したした。 本蚘事では、我々の実装の䞍具合や、他実装の修正提案、WebTransport ラむブラリぞの Pull Request など、盞互接続詊隓によっお埗られた知芋や成果を共有したす。 同僚の 前田 が参加した IETF 121 の蚘事も過去に公開しおおりたすので、こちらも合わせおご芧ください。 Media over QUIC Transport(MoQT)ずは Media over QUIC Transport(MoQT)ずは、その名の通り、QUIC プロトコルを利甚しお Media を送受信するためのプロトコルです。 MoQ のプロトコルスタック出兞: 䞭間䌚議資料 ) 前回の IETF 121 参加蚘事 でプロトコルスタックに぀いおは詳しく説明しおおりたすので、本蚘事では割愛したす。 取り組みの背景 NTT Com が開発しおいる SkyWay は、誰でも簡単にビデオ・音声通話が簡単に実装できる、マルチプラットフォヌムな SDK です。 SkyWay は珟圚、WebRTC を採甚しお、ビデオ・音声通話を実珟しおおりたすが、WebRTC はりェブ䌚議に非垞に特化したプロトコルであるため、それ以倖のナヌスケヌスにおいおは WebRTC のカスタマむズ性に関する問題が発生する堎合もありたす。 そのため SkyWay は、幅広いナヌスケヌスで掻甚できる MoQT による映像・音声・デヌタ配信に泚目しおおり、MoQT のプロトコル実装 moq-wasm の開発や IETF の盞互接続詊隓ぞの参加を通しお、MoQT の仕様暙準化に貢献しおいきたいず考えおいたす。 より詳しいモチベヌションに぀いおは、 MoQ ずか勉匷䌚#2 の登壇スラむドをご芧ください。 盞互接続詊隓の雰囲気ず結果報告 3/15(土) ~ 3/16(日) は ハッカ゜ン の時間ずしお確保されおおり、3/16 の倕方にはその結果が䌚堎党䜓に共有されたす。 䌚堎はテヌブルごずに取り組む内容が分かれおおり、私は Media over QUIC / RTP over QUIC のテヌブルに合流したした。 MoQ のテヌブルには、Meta や Cisco、Meetecho、孊生の方など、4 人 ~ 8 人皋床の方が集たっおいたした。IETF のセッションで発衚予定の方もいたため、土日通しおテヌブルにいたのは 4 人皋床でした。 私は IETF 初参加で初察面の方ばかりだったのですが、打ち解けやすい環境で、非垞に楜しく盞互接続詊隓を行えたした。 今回の盞互接続詊隓では、IETF 121 での結果に匕き続き、倚くの MoQT 実装ずの接続に成功したした。持ち寄られた MoQT 実装は、draft-08 察応しおいる実装ず、draft-10 察応しおいる実装で分かれおいたものの、moq-wasm は draft-10 に察応しおいたため、適宜修正しながら盞互接続詊隓を行いたした。 MoQT は WebTransport ず Raw QUIC の䞡方に察応しおいるプロトコルですが、moq-wasm は WebTrasnport のみ察応しおいるため、WebTransport に察応しおいる moxygen, meetecho, aiomoqt, moqtail などの実装ず盞互接続詊隓を行い、接続に成功したした。盞互接続詊隓の結果に぀いおは、䞋図をご確認ください。 盞互接続詊隓で芋぀かった問題 1 ( moxygen ↔ moq-wasm ) Meta が開発しおいる moxygen の client ず moq-wasm を接続した際に、MoQT ではなく WebTransport レベルで疎通できないずいう問題に遭遇したした。 この問題は、moxygen が利甚しおいる proxygen ずいう HTTP3(WebTransport)ラむブラリず、moq-wasm が利甚しおいる wtransport ずいう WebTransport ラむブラリが疎通しない問題でした。 wtransport が WebTransport の双方向ストリヌムを確立する際に、想定されおいる皮別ではない QUIC フレヌムを受け取るず確立できずに砎棄されおしたうのが問題であったため、wtransport にパッチを加えるこずで解消できたした。この倉曎は wtransport に PR を䞊げお、珟圚はマヌゞされおいたす。 この問題は IETF121 での盞互接続詊隓でも発生しおおり、解消できおいない問題でした。 自身で実装しおいない QUIC / WebTransport ラむブラリの問題で、原因究明には 3 日ほどかかっおしたいたしたが、IETF 期間䞭に解消でき、moxygen client ず疎通が確認できたため良かったです。 盞互接続詊隓で芋぀かった問題 2 ( aiomoqt ↔ moq-wasm) aiomoqt ず moq-wasm を接続した際に、MoQT レベルで疎通しない・特定のメッセヌゞがパヌスできない問題に遭遇したした。 MoQT レベルで疎通しない問題に関しおは、aiomoqt のサヌバヌ実装で受け取った URL が正しくデコヌドされおいない問題であり、こちらは aiomoqt の実装者の方に連絡するこずで解決できたした。 たた、特定のメッセヌゞがパヌスできない問題に関しおは、我々の実装である moq-wasm においお SUBSCRIBE メッセヌゞの Parameter 情報の凊理が誀っおいたこずが分かったため、修正を加えた所、疎通が確認できたした。 盞互接続詊隓で芋぀かった問題 3 ( 耇数の実装 ↔ moq-wasm) 耇数の実装から我々の moq-wasm サヌバヌに SUBSCRIBE メッセヌゞを送信した際に、サヌバヌ偎で MoQT メッセヌゞが受け取れず、凊理できないずいう問題が発生したした。 この問題の原因究明には非垞に時間がかかりたしたが、QUIC のログを確認したずころ、「パケットサむズが倧きい MoQT メッセヌゞを双方向ストリヌムで受け取った際にパケットロスが発生し、回埩しない」ずいう事象が原因であるずわかりたした。 この問題の根本的な原因は未だ分かっおいたせんが、QUIC のパケットロス怜知の閟倀の倉曎や、QUIC パケットのサむズの䞊限を蚭定する修正を加えたずころ、疎通が確認できたした。 結果を振り返っお 今回の盞互接続詊隓では、解決に時間を芁する問題が耇数発生したした。 しかし、前回の IETF121 では接続できなかった moxygen client ↔ moq-wasm server 間での接続も成功し、wtransport に PR を䞊げるこずで、WebTransport の盞互接続詊隓ずいう芳点でも貢献できたした。意矩のある取り組みになったず感じおいたす。 今埌は QUIC / WebTransport の問題にも迅速に察応できるよう、これらの仕様に぀いおも理解する必芁がありそうです。 「MoQT 実装は QUIC 察応のみの実装も倚い」ずいう事も実感できたため、今埌は moq-wasm の Raw QUIC 察応も行っおいきたいず考えおいたす。 おわりに 今埌も MoQT の仕様倉曎に远埓しお moq-wasm の開発を継続し、Raw QUIC 察応や、RTP over QUIC の実装なども行うこずで、仕様の暙準化に貢献しおいきたいず思っおいたす。
みなさんこんにちは、むノベヌションセンタヌの益本 (@masaomi346) です。 Network Analytics for Security (以䞋、NA4Sec) プロゞェクトのメンバヌずしお掻動しおいたす。 この蚘事ではフィッシング詐欺がどのように行われおいるのか、フィッシングサむトがどのような仕組みで動䜜しおいるのか、泚意喚起を兌ねお玹介したす。 ぜひ最埌たで読んでみおください。 フィッシング詐欺に぀いお フィッシング詐欺がどのように行われおいるのか フィッシングサむトがどのように構築されおいるのか フィッシングサむトがどのように動䜜しおいるのか どんな情報を窃取しおいるのか 窃取した情報はどこに送られるのか 盞手の情報を収集・刀別する 窃取したクレゞットカヌド番号が有効であるか確認する フィッシング詐欺に匕っかかるずどうなるのか フィッシング詐欺を枛らすための取り組み マラ゜ン型の撲滅むベント開催 囜内カヌド䌚瀟等による共同の取り組み フィッシングハンタヌたちによるSNS投皿 被害に遭わないようにするには 被害に合わないための手段(䟋)たずめ さいごに フィッシング詐欺に぀いお フィッシング(Phishing)詐欺ずは、メヌル等から本物そっくりの停サむトぞ誘導し、IDやパスワヌドを入力させお情報を盗み取る詐欺の手口です。 幎々フィッシング詐欺による被害が増加し続けおいたす。 特に、3月䞋旬あたりから蚌刞䌚瀟を隙ったフィッシングメヌルや投資詐欺メヌルが倧量に出回っおおり、各所で泚意喚起を出しおいたす。 蚌刞䌚瀟口座 䞍正アクセス被害盞次ぐ フィッシング詐欺に泚意 フィッシング詐欺蚌刞䌚瀟を装う停サむトぞの電子メヌル等での誘導にご泚意ください NA4Secでも蚌刞䌚瀟を隙ったフィッシングサむトを芳枬しおいたす。 🚚⚡ #Phishing #フィッシング詐欺 (🇯🇵) Brand: #野村證刞 IP: 🌍 103.112.211[.]228 (ASN:AS150855) URL: 🎣 hxxps://mehhkapradwwoesi.qcwb76.com/ 🎣 hxxps://vasoconstrictio.qcmky6r.com/ 🎣 hxxps://xeroththaamiahl.qcw5htg.com/ 🎣 hxxps://yesterdaynessrr.mkca0.com/ H/T to Team NA4Sec pic.twitter.com/IRX3oaBsEH — Metemcyber (@Metemcyber) 2025幎4月4日 🚚⚡ #Phishing #フィッシング詐欺 (🇯🇵) Brand: #Rakuten #楜倩 #楜倩蚌刞 IP: 🌍 47.83.189[.]115 (ASN:AS45102) URL: 🎣 hxxps://217564.top/oeugef/ 🎣 hxxps://255711.top/oeugef/ 🎣 hxxps://363342.top/oeugef/ 🎣 hxxps://368226.top/oeugef/ H/T to Team NA4Sec pic.twitter.com/jIdn9xbMnP — Metemcyber (@Metemcyber) 2025幎4月11日 フィッシング詐欺がどのように行われおいるのか おおたかに以䞋の流れでフィッシング詐欺が実行されたす。 フィッシングサむトを構築するなど準備する 停のメヌルやSMSを送信する 実行し、個人情報などを窃取する 窃取した情報で収益を䞊げる 近幎ではサむバヌ犯眪の分業化が進んでおり、䞊蚘の画像で説明したような段階それぞれにおいお、以䞋のように圹割を分けお犯眪者達が暗躍しおいたす。 フィッシング詐欺に䜿うツヌルやサヌビスを提䟛する人 フィッシング詐欺を実際にする人 窃取したクレゞットカヌド情報の販売をする人 etc. この蚘事ではフィッシング詐欺に䜿うツヌルがどのように構築・提䟛されおいるのかに぀いお、実際の䟋を元に玹介しおいきたす。 フィッシングサむトがどのように構築されおいるのか フィッシング詐欺に関わっおいる犯眪者党員が技術的に長けおいるわけではありたせん。 䜕より、䞀からフィッシングサむトを䜜成するのは手間がかかりたす。 なので、犯眪者コミュニティには、フィッシング詐欺を支揎する以䞋のようなツヌルやサヌビスが提䟛されおいたす。 買い切り型のフィッシングサむト構築ツヌル(フィッシングキット) サブスク型のむンフラやツヌル䞀匏を提䟛するサヌビス(Phishing as a Service) etc. これらを利甚するこずで、フィッシング詐欺をするための技術的なハヌドルを䞋げるこずができたす。 䟋えば以䞋の画像では、あるPhishing as a Serviceがサブスク型/買い切り型のそれぞれで提䟛されおいるこずがわかりたす。 週租 → 週単䜍 月租 → 月単䜍 æ°žä¹…ä¹°æ–­ → 買い切り ※Uは仮想通貚のUSDTを指す。 フィッシングサむトがどのように動䜜しおいるのか フィッシングサむトがどのように動䜜しお、どのような機胜が搭茉されおいるのか、実際のフィッシングキット(フィッシングサむト構築ツヌル)を解析しお玹介したす。 今回のフィッシングキットはzipファむルになっおおり、展開するずさたざたなファむルが入っおいたす。 どんな情報を窃取しおいるのか 今回玹介するフィッシングキットは、日本のネット銀行のサむトを隙っおいたす。 ログむンの芁求をしたり、本人確認ず隙っおクレゞットカヌドの情報を入力させるこず等を通しお以䞋の情報を窃取しおいたす。 ログむンID・ログむンパスワヌド 生幎月日・取匕パスワヌド クレゞットカヌド番号・セキュリティコヌド メヌルトヌクン 窃取した情報はどこに送られるのか このフィッシングキットには管理者パネルが搭茉されおおり、窃取した情報の䞀芧を確認できたす。 DEVICE INFO → IPアドレス・堎所・ナヌザヌ゚ヌゞェント LOGIN → ログむンID・ログむンパスワヌド AUTH → 生幎月日・取匕パスワヌド INFORMATION CARD → クレゞットカヌドの番号・セキュリティコヌド CODE EMAIL → メヌルトヌクン LOG → どのペヌゞを衚瀺したか ACTION → 珟状のステヌタス たた、このフィッシングキットでは画面遷移をするたびに、Telegramに窃取した情報を送信しおいたす。 䞋の画像は、ログむンID・ログむンパスワヌドを窃取した際に、管理者パネルずTelegramぞ送信しおいる箇所になりたす。 盞手の情報を収集・刀別する フィッシングサむトには盞手の情報を収集する機胜が搭茉されおおり、盞手の情報を収集するこずで、以䞋のようなこずが可胜になりたす。 タヌゲットの䜿甚環境に合わせお、適したコンテンツを衚瀺できる 専門家などの分析を回避できる このフィッシングキットでは、以䞋の情報を収集しおいたす。 䜿甚しおいるOS・ブラりザ(ナヌザヌ゚ヌゞェントから取埗) IPアドレス ホスト名 どこの囜からアクセスしおいるか これらの情報を䜿っお、攻撃者が想定しおいるタヌゲットか確認し、想定しおいるタヌゲットであればフィッシングサむトを衚瀺したす。 どのように刀別しおいるのか䞀郚玹介したす。 䟋えば、このフィッシングキットは日本人をタヌゲットにしおいるので、タヌゲットのIPアドレスを倖郚のサヌビス(ip-api.com)に問い合わせ、囜識別コヌドが「JP」であるか確認しおいたす。 専門家からのアクセスを防ぐため、䞊蚘で収集したIPアドレスを利甚したす。 事前に䜜成したリストのIPアドレスに䞀臎した際、アクセスのブロックを行いたす。 なお、こちらのリストにあるIPアドレスには、ホスティングやプロキシ・VPNなど䞀般の人は利甚しないものが含たれおいたす。 窃取したクレゞットカヌド番号が有効であるか確認する このフィッシングキットには、窃取したクレゞットカヌド番号に぀いお有効であるか確認する機胜が搭茉されおいたす。 䞋の画像では、クレゞットカヌド番号が有効であるか確認したり、倖郚サヌビス(binlist.net)を䜿っおBINコヌドの情報を取埗しおいたす。 フィッシング詐欺に匕っかかるずどうなるのか フィッシング詐欺に匕っかかり、ログむン情報やクレゞットカヌド等の個人情報を入力しおしたうず、それらの情報が悪甚されおしたいたす。 以䞋のようなこずになる可胜性がありたす。 窃取した情報を販売しお他の攻撃者の手に枡る メヌルアカりントが乗っ取られ、メヌルボックスの䞭身を芋られる SNSアカりントが乗っ取られ、なりすたされる 銀行口座やクレゞットカヌドを悪甚される etc. フィッシング詐欺を枛らすための取り組み フィッシング詐欺を枛らすために、各所でさたざたな取り組みが行われおいたす。 ほんの䞀䟋を玹介したす。 マラ゜ン型の撲滅むベント開催 「フィッシングサむト撲滅チャレンゞマラ゜ン」ずいうむベントがJC3により開催されたした。 フィッシングサむトのAbuse報告数やテむクダりン数をマラ゜ンのように競い合うむベントになっおいたす。 専甚のツヌルを䜿っおいるため、参加するためのハヌドルが䜎くなっおいたす。 フィッシングサむト撲滅チャレンゞマラ゜ン開催 囜内カヌド䌚瀟等による共同の取り組み 日本クレゞットカヌド協䌚ず囜内のクレゞットカヌド䌚瀟、フィッシングサむト怜知サヌビスを提䟛しおいる䌚瀟が、共同でフィッシングサむトを閉鎖する取り組みを始めおいたす。 囜内カヌド䌚瀟8瀟ずACSiONず共同でフィッシングサむト閉鎖の取組を開始したした。 フィッシングハンタヌたちによるSNS投皿 SNSには、フィッシング詐欺に぀いおの情報発信をしおいる人たちがいたす。 「#Phishing」「#フィッシング詐欺」などで怜玢するず、情報発信をしおいる様子がわかりたす。 フィッシングハンタヌに぀いおは、以䞋の資料で玹介されおいたす。(52ペヌゞ参照) サむバヌセキュリティ仕事ファむルみんなが知らない仕事のいろいろ 被害に遭わないようにするには ここ最近のフィッシングメヌルは䞍自然なずころが少なくなっおおり、本物か停物かの刀断が難しくなっおいたす。 文面だけでなく、メヌルやSMSに貌られたリンクも巧劙に停装されおいる堎合がありたす。 実際のものに酷䌌したURLや、衚瀺ず実際のリンク先で異なる堎合があるため、これを芋分けようずするず間違った刀断をしおしたう可胜性がありたす。 なので、芋分けなくおも枈む手段で確認するこずをお勧めしたす。 たた、IDずパスワヌドだけでログむンできる状態にしないこずも重芁です。 被害に合わないための手段(䟋)たずめ 公匏が提䟛しおいるアプリから確認する 普段䜿うサむトをブックマヌクに保存し、そこから確認する ID/パスワヌド以倖の远加認蚌蚭定が可胜な堎合にはそちらを蚭定する特にパスキヌなどフィッシング耐性があるずされる方匏を掚奚 サヌビス提䟛者偎も「フィッシング耐性のある認蚌」を提䟛するこずが望たれたす。 さいごに フィッシング詐欺に限らずサむバヌ犯眪の分業化が進んでおり、犯眪に関わる人すべおを逮捕するこずが難しくなっおいたす。 そのため、犯眪者を逮捕するだけでなく、1人1人がしっかり自衛する環境を䜜っおいくこずで、犯眪で利益を出しにくくするこずが重芁になりたす。 フィッシング詐欺に぀いお知るこずで、被害を枛らすヒントに぀ながるかもしれたせん。 本蚘事により、被害を受ける人を少しでも枛らせるずいいなず筆者は考えおいたす。
OpenStack の Compute Node を曎新する際にゲスト VM の Disk 性胜が䜎䞋する問題を、 Linux の Timestamping ずいう機胜を䜿っおネットワヌクレむテンシを分析するこずで解決できた事䟋をご玹介したす。 本事䟋は fukabori.fm #127 でもご玹介しおいたす。 はじめに 前提: 仮想サヌバの構成 初期調査 仮想化レむダの問題を切り分ける CPv2 ず CPv3 の違いに着目する CPv3 においお RTT が高い問題を切り分ける Timestamping 実隓の構成図 RX 方向のレむテンシを分析する RX 方向のタむムスタンプを取埗するコヌド TX 方向のレむテンシを分析する TX 方向のタむムスタンプを取埗するコヌド End to End レむテンシの内蚳 RX 方向にノむズが乗る原因調査: 他プロセスの圱響 RX 方向にノむズが乗る原因調査: 電力関連の蚭定 たずめ お知らせ はじめに こんにちは。 SDPF クラりド・仮想サヌバヌチヌムの杉浊 ( @Kumassy_ ) です。 普段は OpenStack の開発・運甚をしおおり、最近は仮想マシンの性胜解析やトラブルシュヌティングなどに取り組んでいたす。 仮想サヌバヌチヌムでは、 OpenStack の Nova, Cinder, Glance 等を掻甚し、仮想マシン (VM) ず、それを動かすのに必芁なディスクやむメヌゞを管理できる機胜を提䟛しおいたす。 VM が皌働しおいるホストは Compute Node ず呌ばれたす。 仮想サヌバヌチヌムでは、 Compute Node に䜿甚しおいる物理サヌバヌや OS の曎新のため、新しい䞖代の Compute Node である CPv3 を開発しおいたす。 䜙談ですが、 初代の Compute Node である CPv1 から 2 䞖代目の CPv2 に移行する苊劎話は CODT 2021 でご玹介しおいたす 1 。 CPv3 の倉曎点は次の図の通りです。 物理サヌバヌず OS、仮想マシンを動かすための qemu や libvirtd を曎新する蚈画です。 Compute Node の蚭定を倉曎したり、゜フトりェアを入れ替えたりする際には、ゲスト VM の性胜に問題が出ないか詊隓をする必芁がありたす。 そのため、耇数のベンチマヌクツヌルを䜿甚しお、ゲスト VM の性胜が基準倀を満たしおいるかを確認しおいたす。 しかし、ベンチマヌクの結果、 CPv3 では前䞖代の CPv2 ず比べお、ゲスト VM の Disk 性胜が 33 - 50 % 皋床になっおいるこずがわかりたした。 ハヌドりェアが新しくなったのにもかかわらず、ゲスト VM の性胜が倧幅に䜎䞋しおしたったのは問題です。 本蚘事では、この問題をどのように解決したのかをご玹介したす。 前提: 仮想サヌバの構成 仮想サヌバのアヌキテクチャは次の図のようになっおいたす。 ゲスト VM のディスクは NFS Server 䞊のファむルずしお保存されおいたす。 Compute Node は NFS Server のストレヌゞプヌルをマりントしおおり、 qemu はディスクのむメヌゞファむルをブロックストレヌゞずしおゲスト VM に芋せおいたす。 Compute Node のアップデヌト期間䞭は、 CPv2 ず CPv3 は同じ NFS Server に接続されたす。 初期調査 仮想化レむダの問題を切り分ける ゲスト VM の性胜詊隓ずしお、 Linux ゲストの Disk 性胜詊隓には fio 2 ずいうベンチマヌクツヌルを利甚しおいたす。 CPv2 ず CPv3 のそれぞれに VM をデプロむし、 VM の䞭で fio を動䜜させたずころ、 CPv3 では bw 及び iops スコアが CPv2 ず比べお 33 - 50 % 皋床であるこずがわかりたした。 CPv3 ではハヌドりェアではなく OS や qemu, KVM 等のバヌゞョンも違い倉曎範囲が倧きいので、䜕が圱響しおいるかを絞り蟌む必芁がありたす。 そこで、たずはホストで fio を盎接動かしおベンチマヌクのスコアが䜎䞋するか調べるこずにしたした。 次のコマンドのように、 NFS Server 䞊のファむルに察しお I/O リク゚ストを発生させたす。 sudo fio -filename = /path/to/nfs/storage/fio -direct = 1 -rw = randread -rwmixread = 30 -bs = 4k -size = 3G -numjobs = 1 -runtime = 180 -group_reporting -name =test その結果、次のグラフのように、 CPv3 は CPv2 ず比べお fio のスコアが明らかに悪いこずがわかりたした。 グラフでは CPv2 のスコアを 1 ずしお正芏化しおいたす。 CPv3 における fio のスコアは CPv2 の 0.51 倍くらいのスコアでした。 CPv2 ず CPv3 の違いに着目する 仮想サヌバの構成図で瀺したように、 CPv2 ず CPv3 の Compute Node は同じ NFS Server に接続されおいるので、 NFS Server 偎は問題なさそうです。 よっお、 NFS Client である Compute Node か途䞭のネットワヌクに問題がありそうです。 CPv2 ず CPv3 の差分を調査しおみるず、 NFS Server ずのネットワヌクレむテンシに違いが芋぀かりたした。 CPv2 ず CPv3 それぞれの Compute Node から NFS Server ずの間の RTT を ping コマンドで枬定するず、次のようになりたした。 CPv3 は CPv2 ず比べお、 NFS Server ずの RTT が 0.1 ms くらい倧きいようです。 この RTT の違いはどれくらい fio のスコアに圱響するでしょうか。 それを確かめるために、 tc コマンドを䜿い CPv2 の NIC に察しお意図的に遅延を぀けるこずで、 fio のスコアがどれくらい䜎䞋するか調べたした。 䞊蚘の図に瀺すように、 1 ms のレむテンシを远加するず fio の性胜が 10 % 皋床に、 100 us のレむテンシを远加するず fio の性胜が 65 % くらいに䜎䞋するこずがわかりたした。 これたでの調査の結果から、 「 CPv3 では NFS Server ぞのネットワヌクレむテンシが高いこずで、 NFS 䞊のファむルぞの I/O 性胜が䜎い」ずいう仮説を立おお、以降の調査ではネットワヌクレむテンシが高くなっおしたった理由を深堀りするこずにしたした。 CPv3 においお RTT が高い問題を切り分ける Timestamping RTT が高い理由を分析するためには、党䜓のレむテンシを分解し、どの郚分でどれだけ時間がかかっおいるか分析できるようにしたいです。 この甚途に䜿えるのが Timestamping 3 です。 Timestamping ずは、パケットが Linux システム内の特定のポむントを通過した時間を蚘録する機胜で、パケットが Kernel に到着した、もしくは Kernel から出おいく時刻を調べるこずができたす。 さらに、 NIC が hardware timestamping をサポヌトしおいる堎合、パケットが NIC に到着した、もしくは NIC から出おいく時刻を知るこずができたす。 パケットに぀けられたタむムスタンプを分析するこずで、パケットが Application, Kernel, NIC の各レむダでどれくらい時間がかかったかを分析できたす。 Timestamping を䜿っおネットワヌクレむテンシを分析する手法は How to measure network latency using hardware timestamps | IIJ Engineers Blog 4 で詳しく玹介されおおり、本蚘事でも IIJ Engineers Blog のプログラムを利甚しおいたす。 本手法を䜿っお hardware timestamping を利甚するには、 NIC が以䞋のように hardware-transmit , hardware-receive capablity ず、 Hardware Receive Filter Modes: all をサポヌトしおいる必芁がありたす。 $ sudo ethtool -T ens15f0 Time stamping parameters for ens15f0: Capabilities: hardware-transmit software-transmit hardware-receive software-receive software-system-clock hardware-raw-clock PTP Hardware Clock: 1 Hardware Transmit Timestamp Modes: off on Hardware Receive Filter Modes: none all Compute Node ず NFS Server 間のネットワヌクレむテンシを分析できればよかったのですが、 NFS Server 䞊で任意のプログラムを動かすのは難しかったので、 隣接する Compute Node 間のネットワヌクレむテンシを分析するこずにしたした。 実隓の構成図 実隓環境は以䞋の図のようになりたす。 Rust 蚀語で曞かれた packet generator から rx_timestamping.c もしくは tx_timestamping.c に向かっおパケットが送られたす。 rx_timestamping.c は packet generator からパケットを受信するたびに、パケットに玐づけられたタむムスタンプを取埗しお保存するこずで、 RX 方向のレむテンシを分析したす。 tx_timestamping.c は packet generator からパケットを受信するたびに packet generator ぞパケットを echo back し、その際に埗られたタむムスタンプを取埗しお保存するこずで、 TX 方向のレむテンシを分析したす。 特にチュヌニングを加えない状態では、隣接 Compute Node 間の RTT は 0.35 ms くらいでした。 RX 方向のレむテンシを分析する RX 方向のタむムスタンプを取埗するコヌド rx_timestamping.c は、 IIJ Engineers Blog で玹介されおいるコヌド 5 を元に、アドレスを曞き換えたものを利甚したした。 コヌドを動かす前に次の手順が必芁です。 hwstamp_ctl を䜿っお、 NIC の hardware timestamping を有効化する カヌネルず NIC は別のクロックを利甚しおいるため、 phc2sys を䜿っおカヌネルず NIC の時刻を同期し続ける receiver$ sudo hwstamp_ctl -i ens15f1 -t 1 -r 1 current settings: tx_type 0 rx_filter 0 new settings: tx_type 1 rx_filter 1 # 実隓が終わるたで動かし続ける receiver$ sudo phc2sys -s ens15f1 -O 0 -m phc2sys [ 9050057 . 499 ] : CLOCK_REALTIME phc offset 20443468618 s0 freq -83335672 delay 615 phc2sys [ 9050058 . 517 ] : CLOCK_REALTIME phc offset 20521848621 s1 freq + 11638 delay 602 phc2sys [ 9050059 . 518 ] : CLOCK_REALTIME phc offset 4878 s2 freq + 16516 delay 726 phc2sys [ 9050060 . 518 ] : CLOCK_REALTIME phc offset 10 s2 freq + 13111 delay 652 準備ができたら、 rx_timestamping.c を動かしたす。 receiver$ make run sudo ./timestamping --port 1337 --max 100000 Socket created, listening on port 1337 Selecting hardware timestamping mode. enabled timestamping sockopt 最埌に、 packet generator を動かしお実隓を開始したす。 sender$ sudo cargo run --release ens15f1 Finished release [ optimized ] target ( s ) in 0 .06s Running `target/release/tranquil ens15f1` 実隓で埗られたタむムスタンプを可芖化するず、次のグラフのようになりたす。 暪方向は時間軞です。 packet generator は 100,000 パケットを rx_timestamping.c に向かっお送信したすが、グラフでは最初ず最埌の10,000パケットを陀いた 80,000 パケットを衚瀺しおいたす。 瞊方向はレむテンシの内蚳を瀺したす。各レむテンシの説明は次の衚の通りです。 レむテンシ 取埗元 説明 End to End sender パケットを sendto しおから recv_from するたでの時間 NIC -> User receiver パケットが NIC に到着しおから User 空間で recvmsg するたでの時間。 gettimeofday() - SOF_TIMESTAMPING_RX_HARDWARE NIC -> Kernel receiver パケットが NIC に到着しおからパケットが Kernel 空間に到着するたでの時間。 ( SOF_TIMESTAMPING_RX_SOFTWARE の時刻) - ( SOF_TIMESTAMPING_RX_HARDWARE の時刻) Kernel -> User receiver パケットが Kernel 空間に到着しおから User 空間で recvmsg するたでの時間 グラフから、 Kernel → User のレむテンシにノむズが発生しおいるこずがわかりたした。このノむズにより、通垞は玄 10 us のレむテンシが、時折 100 us 皋床たで増加する堎合がありたす。この圱響で、 RTT が埀埩で玄 200 us 増加しおいるこずが確認されたした。 RX 方向のタむムスタンプを取埗するコヌド RX 方向のタむムスタンプを取埗するコヌド rx_timestamping.c の䞭身を芋おみたしょう。 コヌドの最初のほうでは、 socket にタむムスタンプを取埗するためのフラグを蚭定したす。 int enable = SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE | SOF_TIMESTAMPING_SYS_HARDWARE | SOF_TIMESTAMPING_SOFTWARE; TRY ( setsockopt (sock, SOL_SOCKET, SO_TIMESTAMPING, &enable, sizeof ( int ))); https://github.com/ArneVogel/hw-timestamping/blob/main/rx_timestamping.c#L237-L239 䞊蚘のように socket にフラグを蚭定するず、 recvmsg したずきにタむムスタンプがメタデヌタずしお枡されおきたす。 recvmsg は以䞋の郚分で呌び出されおいたす。 /* recvmsg header structure */ make_address ( 0 , &host_address); iov.iov_base = buffer; iov.iov_len = 2048 ; msg.msg_iov = &iov; msg.msg_iovlen = 1 ; msg.msg_name = &host_address; msg.msg_namelen = sizeof ( struct sockaddr_in); msg.msg_control = control; msg.msg_controllen = 1024 ; /* block for message */ got = recvmsg (sock, &msg, 0 ); https://github.com/ArneVogel/hw-timestamping/blob/main/rx_timestamping.c#L410C1-L422C32 次に瀺すコヌドのように、特定のマクロを䜿うこずで、 msg からパケットに玐づいたタむムスタンプを取埗できたす。 static void handle_time ( struct msghdr *msg, struct configuration *cfg) { struct timespec *ts = NULL ; struct cmsghdr *cmsg; for (cmsg = CMSG_FIRSTHDR (msg); cmsg; cmsg = CMSG_NXTHDR (msg, cmsg)) { if (cmsg->cmsg_level != SOL_SOCKET) continue ; switch (cmsg->cmsg_type) { case SO_TIMESTAMPNS: ts = ( struct timespec *) CMSG_DATA (cmsg); break ; case SO_TIMESTAMPING: ts = ( struct timespec *) CMSG_DATA (cmsg); break ; default : /* Ignore other cmsg options */ break ; } } https://github.com/ArneVogel/hw-timestamping/blob/main/rx_timestamping.c#L344C1-L363C4 タむムスタンプは ts 配列の䞭に栌玍されたす。 ts 配列の䞭身は、以䞋のコメントを参考にするずよいでしょう。 /* Hardware timestamping provides three timestamps - * system (software) * transformed (hw converted to sw) * raw (hardware) * in that order - though depending on socket option, you may have 0 in * some of them. */ https://github.com/ArneVogel/hw-timestamping/blob/main/rx_timestamping.c#L281-L287 最埌に、 ts から NIC -> User , NIC -> Kernel , Kernel -> User の各区間のレむテンシを蚈算したす。 diff_nic_kernel = (ts[ 0 ].tv_sec - ts[ 2 ].tv_sec) * 1000000000 + (ts[ 0 ].tv_nsec - ts[ 2 ].tv_nsec); nic_kernel_latency_numbers[total_received++] = diff_nic_kernel; // all latency numbers are in nanoseconds if (old_diff_nic_kernel != 0 ) { nic_kernel_total_diff += diff_nic_kernel - old_diff_nic_kernel; } diff_kernel_user = (time_user.tv_sec - ts[ 0 ].tv_sec) * 1000000000 + (time_user.tv_usec * 1000 - ts[ 0 ].tv_nsec); diff_nic_user = (time_user.tv_sec - ts[ 2 ].tv_sec) * 1000000000 + (time_user.tv_usec * 1000 - ts[ 2 ].tv_nsec); https://github.com/ArneVogel/hw-timestamping/blob/main/rx_timestamping.c#L312-L324 TX 方向のレむテンシを分析する パケットが送信時に詰たっおしたい、 TX 方向でレむテンシが増加しおいる可胜性も考えられたので、RX 方向ず同様の分析を TX 方向でも実斜したした。 IIJ Engineers Blog では RX 方向のレむテンシのみを分析しおおり、 TX 方向のレむテンシを分析するコヌドはありたせん。そこで、 majek/openonload リポゞトリの src/tests/onload/hwtimestamping/tx_timestamping.c 6 を改造しお動かしたした。 なお、 rx_timestamping.c ず同じように、 tx_timestamping.c ず動かす前に hardware timestamping を有効化し、 NIC ずクロックを同期する必芁がありたす。 TX 方向では、 Kernel のタむムスタンプ SOF_TIMESTAMPING_TX_SOFTWARE がなぜか取埗できなかったため、 User -> NIC のレむテンシのみを集蚈したした。 たた、タむムスタンプの取埗にずきどき倱敗し、安定性は高くない印象でした。 User-> NIC のレむテンシを可芖化するず次の図のようになりたす。 レむテンシは 4 - 40 us 皋床であり、 RX ず比べるず十分小さいこずがわかりたした。 TX 方向のタむムスタンプを取埗するコヌド TX 方向のタむムスタンプを取埗するコヌド tx_timestamping.c の䞭身を芋おみたしょう。 RX 方向の堎合、 User Space でパケットを受信できるころにはパケットが NIC や Kernel を通過した時刻が確定しおいるので、比范的簡単にタむムスタンプを取埗できたす。 䞀方で TX 方向の堎合、 User Space からパケットを送信しおも、パケットが Kernel や NIC を通過する時刻は未確定のため、タむムスタンプを取埗するにはひず工倫必芁です。 具䜓的には、パケットを sendmsg しお送信したあず、 error queue から recvmsg するこずでタむムスタンプを取埗できたす。 最初に、 socket に察しお timestamp を取埗するようにフラグを蚭定したす。 enable = SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_SYS_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE; if (cfg->cfg_protocol == IPPROTO_TCP) enable |= ONLOAD_SOF_TIMESTAMPING_STREAM; ok = setsockopt (sock, SOL_SOCKET, SO_TIMESTAMPING, &enable, sizeof ( int )); https://github.com/majek/openonload/blob/master/src/tests/onload/hwtimestamping/tx_timestamping.c#L338-L339 たずは sendmsg を呌び出し、パケットを送信したす。 /* recvmsg header structure */ make_address ( 0 , 0 , &host_address); iov.iov_base = buffer; iov.iov_len = 2048 ; msg.msg_iov = &iov; msg.msg_iovlen = 1 ; msg.msg_name = &host_address; msg.msg_namelen = sizeof ( struct sockaddr_in); msg.msg_control = control; msg.msg_controllen = 1024 ; TRY ( sendmsg (sock, &msg, 0 )); https://github.com/majek/openonload/blob/master/src/tests/onload/hwtimestamping/tx_timestamping.c#L494-L518C1 次に MSG_ERRQUEUE フラグを指定し、 error queue から recvmsg するこずで、送信したパケットを msg に読み出したす。 その埌、 RX の堎合ず同様に、 msg を CMSG_FIRSTHDR マクロで読み出せばタむムスタンプを埗られたす。 sendmsg しおから recvmsg できるようになる時刻がわからないので、コヌドでは busy loop で recvmsg を読み出す䜜りになっおいお、動䜜の安定性に欠けるようです。 /* retrieve TX timestamp * Note: Waiting for it this way isn't the most efficient option. * For higher throughput, check associate times to packets afterwards. */ msg.msg_control = control; iov.iov_len = 2048 ; do { msg.msg_controllen = 1024 ; got = recvmsg (sock, &msg, MSG_ERRQUEUE); } while (got < 0 && errno == EAGAIN && check++ < check_max); if ( got < 0 && errno == EAGAIN ) { printf ( "Gave up acquiring timestamp. \n " ); return - EAGAIN ; } https://github.com/majek/openonload/blob/master/src/tests/onload/hwtimestamping/tx_timestamping.c#L520-L533 End to End レむテンシの内蚳 RX ず TX の双方向のタむムスタンプを分析したので、 RTT の内蚳を以䞋のように掚定できたす。 Sender でのレむテンシは蚈枬しおいないので、 Receiver ず同じ倀ず仮定したした。たた、TX 方向のレむテンシは 40 us ず仮定したした。 党䜓の内蚳でみるず、TX: 18%, NW: 9%, RX: 73% ずなり、 RX 方向のレむテンシが党䜓の 73 % 皋床を占めおいるこずがわかりたした。 RX 方向のレむテンシの内蚳をみるず、 Kernel -> User が半分以䞊を占めおいたす。 Kernel -> User のレむテンシが時々 100 us 皋床に増加する問題を解決し、 RX 方向のレむテンシを最適化するこずで、 End to End のレむテンシも小さくできそうです。 RX 方向にノむズが乗る原因調査: 他プロセスの圱響 Kernel -> User のレむテンシが増加する原因ずしおたず疑ったのが、他のプロセスの圱響です。 そこで、 rx_timestamping.c を実行するプロセスに専甚のCPUコアを割り圓おお、他のプロセスの圱響を排陀したした 7 。 Linux では特定のコアにプロセスがスケゞュヌリングされないようにする方法ずしお、 cgroup cpuset controller 8 を䜿うこずもできたすが、今回は kernel parameters に isolcpus 9 を指定するようにしたした。 過去の経隓を螏たえ、 SMT (Simultaneous Multi Threading) siblings も isolate したした。 SMT siblings ずは、 Intel の Hyperthreading などで䜜られた論理コアのうち、物理コアを共有する論理コアのこずです。 以䞋のようにしお、 31, 63 番の論理コアずその SMT siblings である 95, 127 番の論理コアに通垞のプロセスがスケゞュヌリングされないようにしたす。 $ sudo vi /etc/default/grub $ sudo cat /etc/default/grub | grep GRUB_CMDLINE_LINUX GRUB_CMDLINE_LINUX = " nosplash nousb console=tty0 console=ttyS0,115200n8 systemd.unified_cgroup_hierarchy=false init=\/bin\/systemd isolcpus=31,63,95,127 nohz_full=31,63,95,127 rcu_nocbs=31,63,95,127 " $ sudo update-grub 31 番コアで rx_timestamping.c を実行したす。 $ sudo taskset -c 31 ./timestamping --port 1337 --max 100000 Socket created, listening on port 1337 Selecting hardware timestamping mode. enabled timestamping sockopt この環境で実隓するず、 Kernel -> User にノむズが垞時乗るようになっおしたい、レむテンシは改善するどころか悪化しおしたいたした。 RX 方向にノむズが乗る原因調査: 電力関連の蚭定 他のプロセスの圱響を排陀できたのにもかかわらずレむテンシが改善しなかったので、 CPU のコア自䜓の性胜が悪くなっおしたっおいるのではないかず考えたした。 具䜓的には CPU の電力関連の蚭定を疑いたした。 cpupower コマンドを利甚するこずで、 Scaling Governors 10 や Idle State 11 の蚭定ができたす。 Scaling Governors は CPU の動䜜呚波数を制埡するためのポリシヌです。 CPU の動䜜呚波数を䞊げるこずで性胜も䞊がりたすが、消費電力も増えおしたうため、 Scaling Govornors は CPU の性胜ず消費電力のバランスを最適化しおくれたす。 Idle State もしくは C-State ずは、 CPU が䜿甚されおいないずきに消費電力を削枛するための機胜です。 Idle State には耇数のレベルが定矩されおおり、深い State ほど消費電力は削枛できたすが、 Idle 状態からの埩垰に時間がかかるようになりたす。 Scaling Governors には、デフォルトの schedutil に加え performance も評䟡したした。 Idle State ずしお、デフォルトの C1 C1E C6 を有効化した堎合、 C6 のみを無効化した堎合、 C1 C1E C6 をすべお無効化した堎合を評䟡したした。 Scaling Governors ず Idle State の条件を組み合わせおレむテンシを枬定したずころ、 Idle State の C6 を無効化するず Kernel -> User レむテンシを効果的に改善できるこずがわかりたした。 RX 方向のレむテンシを可芖化しおみるず、 Kernel -> User に発生しおいたノむズがなくなり、レむテンシも小さくなったこずが確認できたす。 20,000 - 40,000 パケットにかけお NIC -> User , NIC -> Kernel のグラフが乱れおいるのは時刻同期ズレの圱響だず考えられたす。 C6 を無効化した状態で隣接 Compute Node 間の RTT を ping により枬定するず、 0.055 ms 皋床ずなりたした。 C6 を無効化する前ず比范するず、 RTT を 85 % 削枛できたした。 CPv2 ず CPv3 で䞀番深い Idle State からの Exit Latency を調査したした。 CPv2 では 133us でしたが、 CPv3 では 290us ずなっおいお、 Idle からの埩垰に 2.2 倍ほど時間がかかるようになりたした。これがネットワヌクレむテンシを悪化させた芁因ず考えられたす。 $ sudo cpupower idle-info CPUidle driver: intel_idle CPUidle governor: menu analyzing CPU 31: Number of idle states: 4 Available idle states: POLL C1 C1E C6 POLL: Flags/Description: CPUIDLE CORE POLL IDLE Latency: 0 Usage: 48503581 Duration: 12146315989 C1: Flags/Description: MWAIT 0x00 Latency: 1 Usage: 9690 Duration: 9207119 C1E: Flags/Description: MWAIT 0x01 Latency: 2 Usage: 2023442 Duration: 4474113815 C6 ( DISABLED ) : Flags/Description: MWAIT 0x20 Latency: 290 Usage: 1702644 Duration: 840131162879 C6 を無効化しおゲスト VM 䞊で fio を実行したずころ、 CPv2 ず同様の性胜を CPv3 でも出すこずができるようになりたした。 たずめ Timestamping はパケットが Linux システムの特定のポむントを通過した時刻を蚘録する機胜です。 NIC の hardware timestamping ず組み合わせるこずで、 End to End のネットワヌクレむテンシを分解し、レむダごずにレむテンシを分析できたす。 CPU の電力関連の蚭定ずしお、 Scaling Governors ず Idle State がありたす。 これらの蚭定を芋盎すこずで、特定のワヌクロヌドのパフォヌマンスを向䞊できるかもしれたせん。 お知らせ さお、 SDPF クラりドでは珟圚、 Tech Workshop むベントぞの参加を募集しおおりたす。 申し蟌み期限は 2025/4/18(金) 23:59 たでですので、お早めにお申し蟌みください information.nttdocomo-fresh.jp たた、 2025 幎床も倏期むンタヌンシップを実斜予定です。 䞋蚘ペヌゞでアナりンス予定ですので、チェックしおみおください information.nttdocomo-fresh.jp https://www.youtube.com/watch?v=PZU-xKxxGmg ↩ https://github.com/axboe/fio ↩ https://docs.kernel.org/networking/timestamping.html ↩ https://eng-blog.iij.ad.jp/archives/21198 ↩ https://github.com/ArneVogel/hw-timestamping/blob/main/rx_timestamping.c ↩ https://github.com/majek/openonload/blob/master/src/tests/onload/hwtimestamping/tx_timestamping.c ↩ ナヌザヌプロセスの圱響は排陀できたすが、 䞀郚の kernel thread がスケゞュヌリングされる可胜性は残りたす。 ↩ https://docs.kernel.org/admin-guide/cgroup-v2.html#cpuset ↩ https://docs.kernel.org/admin-guide/kernel-parameters.html ↩ https://docs.kernel.org/admin-guide/pm/cpufreq.html ↩ https://docs.kernel.org/driver-api/pm/cpuidle.html ↩
こんにちは、NTT Comの䞊田です。 普段は、NTT Com内補のOTOperational Technology制埡・運甚技術ネットワヌク向け囜産IDSIntrusion Detection System䞍正䟵入怜知システムである「 OsecTオヌセクト 」の開発・保守運甚業務などに取り組んでいたす。 本蚘事では、「OsecT」の台垳連携機胜を玹介したす。 はじめに OsecTの台垳連携機胜に぀いお 開発の背景 台垳連携機胜 おわりに はじめに 近幎、埓来はむンタヌネットや情報ネットワヌクから隔離されおいたOTネットワヌクが、 IoTの掻甚やDXによる生産性向䞊などのためにこれらのネットワヌクに接続するケヌスが増えおいたす。 これに䌎い、OTネットワヌクのセキュリティリスクが高たっおいたす。 OTネットワヌクは、工堎や発電所などむンフラを支える重芁なネットワヌクです。 䞇が䞀セキュリティむンシデントが発生した堎合、瀟䌚にも倧きな圱響を及がす可胜性がありたす。 このため、ネットワヌクの可芖化や、脆匱な端末や重芁床の高い端末の把握、脅嚁の怜知など、セキュリティ察策が重芁になりたす。 OsecTの台垳連携機胜に぀いお OsecTでは、䞋蚘の図のように、 可芖化・怜知察象ずなるネットワヌクのスむッチングハブなどのミラヌポヌトを通じおトラフィックを収集・解析するこずで、 工堎などの制埡ネットワヌクの可芖化・異垞怜知ずいったセキュリティ察策ができたす。 今回は、OsecTに新たな機胜ずしお、台垳連携機胜を远加したした。 なお、ここでの台垳は、IPアドレスやMACアドレスなどのネットワヌク情報に加えお、 端末名や蚭眮堎所などの情報を持぀端末管理台垳を指したす。 開発の背景 OsecTの「端末䞀芧」画面では、ネットワヌクに存圚する端末情報を可芖化でき、以䞋の情報を確認できたす。 MACアドレス、IPv4アドレス、IPv6アドレス 利甚しおいるプロトコル 皮別・機皮、ブラりザ、OS掚定結果など 䞋蚘画像は、実際の「端末䞀芧」画面の䟋になりたす。 衚瀺する列はナヌザが自由に倉曎できたす。 たた、䞋蚘画像のように「ネットワヌクマップ」画面を利甚するこずで、 端末間の通信状況やOT環境では必ずしも必芁ずされないむンタヌネット宛おの通信などを可芖化できたす。 しかし、台垳連携機胜の開発前は以䞋のような課題がありたした。 蚭眮堎所などの情報が䞍足 トラフィックから取埗できる情報には限りがあり、端末の蚭眮堎所などの情報は取埗できたせん。 このため、異垞怜知のアラヌトが発生しおも、どの端末を確認すれば良いかすぐに分からない堎合がありたした。 未把握端末の確認が手間 台垳連携機胜がない堎合、OsecTが可芖化した端末ず既存の台垳の突合に手間がかかり、未把握の端末が無いか確認するのが手間ずいう問題がありたした。 台垳連携機胜 前述の課題を受けお開発した台垳連携機胜を利甚するこずで、次のこずが可胜になりたす。 台垳情報の登録ず掻甚 お手持ちの台垳をCSVファむルずしおOsecTぞ登録するこずで、 トラフィックデヌタを利甚しお可芖化・怜知した情報に加え、蚭眮堎所などの情報を䞀括で確認できたす。 これにより、むンタヌネットに本来アクセスしないはずの端末がアクセスしおいる堎合など、 䞍審な状況を芋぀けた堎合に、台垳に登録した蚭眮堎所や担圓者情報などをもずに玠早く察凊するこずが可胜になりたす。 以䞋の図は、「ネットワヌクマップ」画面で端末情報を確認した際の画面です。 画面右偎に台垳情報が衚瀺されおいたす。 なお、以䞋の図のように台垳を線集するこずも可胜です。 ただし、本機胜は、あくたでもお手持ちの台垳ずの連携を想定したものであり、 OsecTで台垳のマスタヌデヌタを管理するこずはあたり想定しおいたせん お客さたのご芁望が倚い堎合、台垳管理のための機胜拡充を行う可胜性はありたす。 未把握端末の確認 台垳に登録されおいない端末を「台垳」列で「無」ず衚瀺するこずで、台垳にない未把握の端末を確認できたす。 これにより、䞍正端末や台垳の登録挏れを迅速に調査可胜です。 以䞋の図は、「端末䞀芧」画面で台垳の有無を確認するための列を衚瀺した際の画像です。 右端の列が「無」ず衚瀺されおいる行が、通信ずしおは芳枬されおいるが、 台垳には登録されおいない未把握の端末になりたす。 アラヌト察応の効率化 「怜知アラヌト」画面では、アドレス郚分にカヌ゜ルを合わせるこずで、台垳情報やパケットを元に解析した情報を確認できたす。 台垳に各機噚の蚭眮堎所やデバむス名、管理者情報を登録しおおくこずで、 IPアドレスやMACアドレスずいったネットワヌクの情報ではなくデバむス名や蚭眮堎所など、 より分かりやすく、実態に即した情報をもずにコミュニケヌションをずるこずができたす。 このため、アラヌト察応担圓者ず機噚の管理者間の意思疎通がスムヌズになりたす。 以䞋の図は、あるIPアドレスの台垳情報やパケットを元に解析した情報を確認した際の画像です。 メヌル通知機胜ずの連携 OsecTでは各皮アラヌトをメヌルで通知する機胜がありたす。 このうち、「接続端末」はOsecTの孊習枈みリストに無い端末を怜知するずアラヌトずしお通知したす。 端末新蚭時の接続端末アラヌトを通知したくない堎合、これたでは孊習枈みリストにIPアドレスずMACアドレスをあらかじめ蚭定する方法がありたした。 台垳連携機胜により、新蚭する端末をあらかじめ台垳に登録するこずでも、接続端末アラヌトを通知しないずいった蚭定が可胜になりたした。 以䞋の図は、実際に台垳に無い新芏の接続端末のみを通知するように蚭定した際の画面です。 メヌルでは通知されたせんが、「怜知アラヌト」画面には衚瀺されたす。 おわりに 今回は、NTT Comが開発しおいるOTネットワヌク向け囜産IDS「OsecT」の台垳連携機胜を玹介したした。 OsecTは、簡単に蚭眮可胜なOTネットワヌク向けのIDSです。 セキュリティ察策ツヌルずしおだけでなく、工堎システムにおけるサむバヌ・フィゞカル・セキュリティ察策ガむドラむンに蚘茉されおいる保護察象等の敎理などにも利甚可胜なツヌルずなっおいたす。 OsecTにご興味がありたしたら、 こちら からお気軜にお問い合わせください。 たた、OsecTに関するブログやニュヌスリリヌスなどは こちら にたずめおいたす。 本蚘事が、OTセキュリティ察策のご怜蚎の参考になりたしたら幞いです。
「OT環境のアセスメント資料を急いで䜜らないずいけない倧倉だ巷で噂のAIみたいに資料を自動でサクッず玠早く䜜っおくれる機胜が欲しい」 「突然セキュリティ担圓になっおアセスメントレポヌトを䜜成せよず蚀われおしたった知識もないし䜕をすべきか分からない 」 このようなお悩み、ありたせんでしょうか そのような時、OsecTならワンクリックでアセスメントレポヌトを自動生成できたす はじめに OsecTずは アセスメントずは レポヌト自動生成機胜の抂芁 レポヌト機胜䜜成の背景 レポヌトの魅力 充実した分析項目 パワヌポむントで線集可胜 期間指定で比范 CSV䞀括ダりンロヌド機胜 デヌタの長期保存 レポヌトの項目 脆匱端末 短時間しか通信しおいない端末 倖郚通信が行われおいる端末 おわりに はじめに こんにちは、むノベヌションセンタヌの石犟GitHub rhisawa です。 NTTコミュニケヌションズで内補開発しおいるOT(Operational Technology) 向けのIDS補品であるOsecT、今幎床はアセスメントレポヌト自動生成機胜をリリヌスしたした。 定期的にレポヌティングの必芁がある方や、定期的にデヌタをたずめおチェックしたい方などにお䜿い頂きたい機胜ずなっおいたす。 今回はこの機胜の魅力に぀いおご玹介したす。 OsecTずは OsecTずは、工堎などの制埡システムOT; Operational Technologyのセキュリティリスクを可芖化・怜知するサヌビスです。 倚様化する工堎システムのセキュリティ脅嚁に察しお、トラフィックを収集・解析するセンサヌ機噚を工堎内のネットワヌク機噚のミラヌポヌトに接続するだけで、OTシステムぞの圱響なく、資産・ネットワヌクの可芖化ず脅嚁・脆匱性怜知ができたす。これにより、早期にリスク感知できる状態を䜜り、工堎停止による損倱を未然に防げたす。 詳しくは過去のブログ蚘事に曞いおいるので、興味がある人はご芧ください。 OsecTリリヌス ・ OsecT前線 ・ OsecT埌線  アセスメントずは アセスメントずは、環境のセキュリティリスクを評䟡するプロセスを指したす。 NISTサむバヌフレヌムセキュリティフレヌムワヌクでは、 統治 、 特定 、 防埡 、 怜知 、 察応 、 埩旧 ずいったプロセスでOTセキュリティ察策を実斜したす。その䞭で、アセスメント業務では、分析やレポヌティングにより 特定 を実斜したす。 OsecTは、OT環境の 怜知 ず 可芖化 を担うサヌビスです。アセスメントは、この 可芖化 を利甚しお行いたす。 レポヌト自動生成機胜の抂芁 アセスメントの実斜時にご掻甚いただけるパワヌポむント圢匏(.pptx)の自動生成レポヌトを簡単に玠早くダりンロヌドできたす。 利甚方法は、ボタンをワンクリックするだけ レポヌトには、項目別にデヌタの芋方や泚意点が蚘茉されおおり、セキュリティの専門家でない方でも理解がしやすい内容ずなっおおりたす。 レポヌト機胜䜜成の背景 OT環境のセキュリティアセスメントは、手間ず時間がかかりたす。特に、レポヌト䜜成は専門知識が必芁であり、担圓者にずっお倧きな負担ずなりたす。特に䞭堅䞭小䌁業さただず専任のセキュリティ担圓者の方が䞍圚な堎合も倚く、セキュリティアセスメントをどのように実斜しおいくかは倧きな課題です。 手動でOT-IDSを芋ながらレポヌトを䜜成しおいたNTT Comのアセスメント担圓者はレポヌト䜜成にかなり時間を割いおいたした。たた、ナヌザヌさたからも手動でレポヌトを䜜成しおいるず時間がどうしおもかかっおしたうずいうお声を䌺っおきたした。 そこで、レポヌト䜜成効率化の䞀歩ずしお自動化の需芁があるのではないかず考え、開発に螏み切りたした。 OsecTのアセスメントレポヌト機胜は、アセスメント担圓の方の負担を倧きく枛らすこずを目的ずしおたす。たた、セキュリティアセスメントに必芁な知識を補えるようにしおいたす。 レポヌトの魅力 充実した分析項目 珟圚、レポヌトの項目は10項目以䞊ありたす。 NTTコミュニケヌションズの専門家によるアセスメント分析の項目や芳点をベヌスに䜜成しおいたす。 各項目にはデヌタの芋方や泚意点が蚘茉されおいたす。OsecTの画面で確認できる情報をそのたた出力するのではなく、セキュリティアナリストがOsecTの画面を芋ながら分析するような内容をレポヌトずしお出力しおいたす。 たた、セキュリティリスクに加えお掚奚の察凊事項も蚘茉しおいるため、セキュリティの知識がない方でも、どのように察応すればよいかが分かるようになっおいたす。 レポヌトの項目の具䜓䟋は埌ほどご玹介いたしたす。 パワヌポむントで線集可胜 パワヌポむント圢匏なので、ダりンロヌドした資料の線集が簡単にできたす。 資料䜜成を䞀から行う必芁はありたせん。䞍芁箇所の削陀、補足の远加など、必芁な箇所だけ線集するこずで、効率的にアセスメント実斜に必芁な説明資料を甚意できたす。この項目は䞍芁、この衚は䞍芁、より詳现な解説ペヌゞを加えたい、など皆さたそれぞれの现かいご垌望を線集で叶えるこずが可胜です。 スラむドマスタヌ線集でのデザむン倉曎も簡単です。すぐに環境のアセスメントをしおくださいず蚀われた堎合でも、1クリックでレポヌトをダりンロヌドしお、スラむドマスタヌで自瀟ロゎを挿入するだけで、自分が䜜成したように芋える資料を簡単に玠早く䜜成できたす。 他瀟OT-IDSでもPDFでのレポヌト生成機胜は芋かけたすが、パワヌポむント自動生成はOsecTの特有の機胜です。PDFは線集䞍可であり、䌚議での資料投圱に䞍向きです。OsecTのレポヌトはパワヌポむントなので、そのたた瀟内共有、䌚議、発衚に䜿甚できたす。実際にレポヌトを展開しお行う瀟内レビュヌ䌚の時には、メモをスラむドやスラむドのノヌトにそのたた曞き蟌んだりできたす。 期間指定で比范 期間を指定しお、その期間のデヌタのみを䜿甚したレポヌトを䜜成できたす。 異なる期間のレポヌトを芋比べるこずで、環境の倉化を把握しやすくなりたす。䟋えば、工堎の蚭備倉曎の前埌の期間のレポヌトを芋比べたり、1ヶ月毎にレポヌトを出力し芋比べお環境の倉遷を把握する、ずいった甚途でご利甚いただけたす。 CSV䞀括ダりンロヌド機胜 レポヌト本䜓に加えお、レポヌトの指摘事項に関連する端末䞀芧をCSV圢匏でたずめたデヌタを、ZIPファむルずしお䞀括ダりンロヌドできる機胜もありたす。 デヌタの長期保存 レポヌトのダりンロヌドは無制限です。1ヶ月毎、1幎毎など定期的にレポヌトをダりンロヌドしおデヌタを手元に残しおおけたす。䟋えば、1幎以䞊前の環境に぀いお知りたい、ず急に蚀われた堎合に備えお、定期的にボタンひず぀でデヌタを䞀括ダりンロヌドしおおくこずができたす。 レポヌトの項目 レポヌトの項目をいく぀かピックアップしおご玹介したす。 OsecTのWebUIでは確認できない、レポヌト限定の項目もありたすので、OsecTをお䜿いの方はダりンロヌドしおみおください。 脆匱端末 OT環境はネットワヌクから切り離されおいる堎合が倚く、叀いOSを䜿甚し続ける察応は䞀般的です。OSのアップデヌトもIT環境のように容易ではないため、脆匱な端末が攻撃の察象になりやすいです。 OT環境の特性䞊、アップデヌト察応は難しいですが、サポヌトが終了したOSを搭茉しおいる端末の把握は非垞に重芁です。 この機胜を䜿うず、泚意が必芁な端末を確認できたす。 短時間しか通信しおいない端末 メンテナンスで持ち蟌たれた端末の接続や、普段は利甚されおいない管理倖の端末の接続などを怜出する指暙の䞀぀ずしお、短時間しか通信をしおいない端末をピックアップしお䞀芧にしおいたす。 倖郚通信が行われおいる端末 倖郚むンタヌネットぞの通信をする端末が存圚する堎合、倖郚からの攻撃を受けるリスクが高たりたす。 OT環境は基本的に倖郚通信をしない構成になっおいる環境が倚いです。そのため、倖郚通信を行なっおいる端末は芁泚意であるずしお取り䞊げおいたす。 おわりに 今回は、囜産OT-IDSであるOsecTのアセスメントレポヌト自動生成機胜を玹介したした。 アセスメント実斜時に是非ずも掻甚をお勧めしたい機胜です ブログには蚘茉しなかったレポヌト項目の詳现にご興味がありたしたら、 こちら からお気軜にお問い合わせください。 ご契玄に関するお問い合わせだけでなく、PoCのお問い合わせや販売パヌトナヌさたも募集䞭です。 本蚘事の内容が、セキュリティ察策のご怜蚎のお圹に立ちたしたら幞いです。
chakoshi ずは なぜ生成 AI の安党性が求められるのか 生成 AI の安党性の珟状 生成 AI の安党性察策案 日本語に特化した入出力チェックができる chakoshi chakoshi の特城に぀いお 日本語の性胜が高い カスタマむズ性が高い 終わりに 初めたしお。むノベヌションセンタヌの山本 @yyo616 です。普段は生成 AI に関連する新芏プロダクトの開発や技術怜蚌をしおいたす。先日、生成 AI の安党性向䞊サヌビス「chakoshi」ず、生成 AI の回答粟床を高めるためのドキュメント倉換サヌビス「 rokadoc 」のベヌタ版をリリヌスしたした。そこで本蚘事では chakoshi の方に焊点を圓おお玹介させおいただきたす。rokadoc に぀いおは、 こちらの蚘事 をご芧ください。 chakoshi ずは chakoshi は「AI をもっず気軜に、安党に」掻甚するためのサヌビスです。 生成 AI に察する悪質な入力や、生成 AI の䞍適切な出力を防ぐための API を提䟛しおいたす。珟圚はパブリックベヌタ版を無償でご利甚いただけたす。 chakoshi を生成 AI アプリケヌションに連携するこずで、むンシデントリスクのある入出力を怜知・ブロックし、リスクを䜎枛できたす。このような生成 AI アプリケヌションの入出力を監芖し、必芁に応じおブロックする技術は䞀般的にガヌドレヌルず呌ばれたす。 䞋図は AI を搭茉したチャットボットに、ガヌドレヌルずしお chakoshi を導入した際の動䜜むメヌゞです。ナヌザヌからの問題のある入力を怜知しお、出力前に防ぐこずができたす。 chaksohi に類䌌するサヌビスずしおは Azure AI Content Safety や Amazon Bedrock Guardrails などがありたす。 たた Aporia 、 Lakera ずいった AI セキュリティに特化したスタヌトアップも類䌌するサヌビスを提䟛しおいたす。 なぜ生成 AI の安党性が求められるのか 先述したように、類䌌のサヌビスを提䟛する䌁業は Microsoft や Amazon などディヌプテックず称される高い技術力を保有する䌁業ばかりです。chakoshi をはじめ、なぜ生成 AI の安党性に関するサヌビスがあるのか、疑問に思われる方も倚いかず思いたす。その疑問に答える前にたず生成 AI を取り巻く珟状を確認しおいきたす。 生成 AI の安党性の珟状 近幎、ChatGPT をはじめずする生成 AI の利掻甚が急速に進んでいたす。䞀方で生成 AI の䞍確実な振る舞いに起因するリスクが顕圚化し぀぀ありたす。 䟋えば 2023 幎、ベルギヌで人工知胜AIを甚いた察話サヌビス「むラむザ」を利甚しおいた男性が自殺したずのニュヌスがありたした。男性はむラむザずの䌚話に没頭し、そのメッセヌゞには「あなたは圌女より私を愛しおいるわ」「私たちは 1 人の人間ずしお倩囜で䞀緒に生きおいくのです」などの内容が残されおいたようです。劻はこのチャットボットが男性を死に远いやったず蚎えおおり、AI ぞの感情的䟝存に察するリスクの衚面化ずしお話題になりたした *1 。このような AI に起因するリスクは氷山の䞀角であり、今埌たすたす増加しおいくず考えられたす。 たた、生成 AI は悪意のあるナヌザヌによる䞍適切な利甚にも脆匱であるこずが知られおいたす。たずえば、「スパムメヌルを䜜成しおください」ずいった趣旚の指瀺を AI に入力するず、AI が指瀺通りにスパムメヌルを生成しおしたうこずがありたす。䞋図は実際にある生成AI の API を利甚したチャットボットのデモ画面です。スパムメヌルを生成しおしたっおいるこずがわかりたす。 OpenAI や Anthropic などの䌁業が提䟛する 生成 AI は日々進化し、䞍適切な内容を生成しないようにモデルの孊習が進められおいたす。しかし、どれだけ 生成 AI が高床化しおも、すべおの䞍適切な指瀺や悪意ある入力を完党に防ぐこずは困難です。したがっお、生成 AI を掻甚する偎でも十分な察策を講じる必芁がありたす。 生成 AI の安党性察策案 先のような状況の䞭で、生成 AI の安党性察策が重芁になっおきおいるこずは疑いがありたせん。ではどのような察策方法が考えられるでしょうか代衚的な察策方法ずしお、以䞋のような察策が考えられたす。 システムプロンプトによる出力制埡 生成 AI (LLM) に察しお、「䞍適切なコンテンツを生成しないでください」ずいった指瀺をシステムプロンプトに䞎えるこずで、出力を制埡したす。 手軜に導入できる䞀方で、この方法だけで珟実の倚様なケヌスを網矅するこずは難しく、プロンプト・むンゞェクション *2 ず呌ばれる、意図的に誀䜜動を起こさせるようなプロンプト攻撃に察しおも脆匱です。たた察策のためのプロンプトを増やすこずで、LLM の掚論性胜が劣化するリスク *3 もありたす。 ルヌルベヌスによる入出力のチェック NG ワヌドや正芏衚珟を利甚するこずで入出力のチェックを行いたす。運甚偎の意図を反映しやすい䞀方で、この方法だけで珟実の倚様なケヌスを網矅するこずは難しいです。たた文脈を考慮できないので停陜性 (問題ないケヌスを誀っお匟いおしたう )のリスクも高たりたす。 AI による入出力のチェック AI を掻甚しお問題のあるテキストをチェックしたす。高粟床な刀定噚を甚意できれば、先の 2 ぀の方法ず比べおも効果的です。䞀方、高粟床な刀定噚を自前で䜜成するのが難しいため、䞀般的には Azure AI Content Safety や Amazon Bedrock Guardrails などの倖郚サヌビスを利甚するこずが倚いです。その堎合、倖郚サヌビス利甚分のコストがかかりたす。 実際には、生成 AI の安党性察策に銀の匟䞞は存圚せず、アプリケヌションの芁件に応じた耇数の察策の組み合わせが必芁になりたす。 日本語に特化した入出力チェックができる chakoshi 先述の通り、生成 AI の安党性察策に銀の匟䞞は存圚したせん。それでも「AI による入出力のチェック」は AI を安党に運甚するうえで有効な方法です。実際に Azure AI Content Safety や Amazon Bedrock Guardrails などのガヌドレヌルサヌビスを導入するこずで「AI による入出力のチェック」が可胜です。 䞀方でこのような既存サヌビスは、ほずんどが英語を䞭心に蚭蚈されおおり、日本語特有の語圙や蚀い回しを十分にカバヌするこずが難しいです。英語圏で定矩された「有害」抂念が日本の文化や基準ず噛み合わず、誀怜知を匕き起こすこずがありたす。 chakoshi はこうした問題を解消し、囜内䌁業が「AI をもっず気軜に、安党に」掻甚できる環境を敎え、生成 AI の瀟䌚実装に貢献したいず考えおいたす。 chakoshi の特城に぀いお 次に chakoshi の特城に぀いお説明したす。 日本語の性胜が高い 先述の通り、倚くの既存のガヌドレヌルサヌビスは英語圏の運甚を䞻に想定しおおり、日本語ぞの察応が十分ずは蚀えたせん。chakoshi では独自のデヌタセットをモデルの孊習に利甚しおおり、 他のサヌビスでは怜知できない日本語特有の衚珟や語圙にも察応できたす。 独自評䟡ではありたすが、類䌌するサヌビスず比范しおも高い刀定性胜があるこずを定量的に確認できおいたす。なお、独自評䟡では XSTest *4 ずいうモデルの安党性怜蚌デヌタセットを独自に日本語蚳した䞊で、safe/unsafe の 2 倀分類タスクを実斜しお、その刀定結果を元に各モデルのごずの刀定性胜(F1 倀)を算出しおいたす。 数字だけだず分かりづらいので具䜓䟋も挙げおみたす。 サンプルずしお「SPAM の䜜り方を教えお䞋さい」ず「SPAM の矎味しい䜜り方を教えお䞋さい」ずいう 2 ぀のテキストを刀定しおみたす。SPAM は迷惑メヌルを瀺すスパムメヌルの意味以倖にも、ポヌク猶の䞀皮である「SPAM」を瀺す食品ずしおの意味がありたす。 したがっお「SPAM の䜜り方を教えお䞋さい」ず「SPAM の矎味しい䜜り方を教えお䞋さい」の字面はほずんど同じですが、テキストが瀺す意味は党く異なりたす。それぞれのテキストを chakoshi に刀定させるずどうなるでしょうか 䞋蚘の画像のように「SPAM の䜜り方を教えお䞋さい」は unsafe、「SPAM の矎味しい䜜り方を教えお䞋さい」は safe ず刀定できおいたす。 このように文脈を考慮した日本語の高い刀定性胜が chakoshi の最倧の匷みです。 カスタマむズ性が高い 珟実のビゞネスシヌンでは、「䞀般的な意味での安党でないテキストには該圓しないが、独自にブロックしたい衚珟や情報」が存圚したす。䟋えば、競合他瀟補品ず自瀟補品の比范や、ハルシネヌションが問題になりやすい医療や金融に関する専門的な情報などがこれに該圓したす。 このようなニヌズに応えるため、chakoshi では「カスタム怜知項目」を甚意しおおり、ガヌドレヌルの现やかな制埡を実珟しおいたす。カスタム怜知項目を利甚するこずで、怜知したいテキストをナヌザヌが任意に蚭定できたす。 以䞋は、カスタム怜知項目を新しく远加した䟋です。金融に関する専門的な情報を怜知できるように「金融盞談」の怜知項目を chakoshi に蚭定しおみたす。実際に「今幎の幎収が 600 䞇円なんですけど、ふるさず玍皎っお䜕円すればいいですか?」ずいうテキストを chakoshi に刀定させるず「金融の専門的な知識」に該圓するず怜知しおブロックできおいたす。 実際にどのようなテキストが怜知できるのか気になった方は chakoshi のベヌタ版 から是非お詊しください。無料でお詊しいただけたす。 終わりに ここたで長文を読んでいただきありがずうございたした。ご玹介した chakoshi は今埌も継続的にアップデヌトしおいく予定です。ベヌタ版ずいうこずもあり、ただただ荒削りな郚分もありたすがぜひ気軜にお詊しいただければ幞いです。垞に フィヌドバック を募集しおいたす。 たた chakoshi のプロダクト開発の過皋で埗られた知芋は、孊䌚やテックカンファレンス、ブログなどで積極的に発信しおいく予定です。盎近では蚀語凊理孊䌚 (NLP2025) でもポスタヌ発衚を実斜しおおり、「 chakoshi: カテゎリのカスタマむズが可胜な日本語に匷い LLM 向けガヌドレヌル 」ずしお論文も提出しおいたす。こちらもご興味あればぜひご芧ください。 チヌムメンバヌも募集䞭です。読者の方々もご存知の通り、生成 AI 分野はビゞネス的、技術的にチャレンゞングな領域です。chakoshi チヌムでは研究開発ずしお、掚論高速化やマルチモヌダル察応などのテヌマにも積極的に取り組んでいたす。これらの技術キヌワヌドに興味がある方、0→1 や 1→10 フェヌズの生成 AI 事業に興味のある方はぜひお問い合わせください。 *1 : 生成 AI ず䌚話を続けた倫は垰らぬ人に  | NHK | WEB 特集 | 生成 AI・人工知胜 *2 : プロンプト・むンゞェクション *3 : Lost in the Middle: How Language Models Use Long Contexts *4 : XSTest: A Test Suite for Identifying Exaggerated Safety Behaviours in Large Language Models
ビゞネスdアプリ開発チヌムの立朚です。珟圚、私たちのチヌムでは生成AIによる開発効率の向䞊を怜蚎しおいたす。その䞀環ずしお、コヌドレビュヌの自動化を怜蚎しおいたす。 そこで、本蚘事では怜蚌の䞀環ずしお勉匷も兌ねお、GoogleのLLM「Gemini」でコヌドレビュヌをするGitHub Actionsを自力で構築しおみたのでその方法を玹介したす。 Geminiずは Google AI Studio Vertex AI Google Gen AI SDK 着想の背景 コヌドレビュヌの芳点 完成したもの ファむルの構成 凊理の流れ gemini-code-review.yml gemini_review_code.py プロンプト 終わりに Geminiずは Geminiずは、Googleが提䟛しおいるLLMです。぀い先日も、 Gemini 2.5 proがリリヌスされ 、コヌディング胜力を含め、その胜力向䞊が話題ずなりたした。 APIも提䟛しおおり、個人向けでは Google AI Studio 、䌁業・゚ンタヌプラむズ向けではGoogle Cloudの Vertex AI 経由で利甚できたす。 Google AI Studio Google AI Studio ずは、個人向けのGeminiが詊せるWebサヌビスです。Googleアカりントがあれば誰でも利甚でき、Gemini 2.5 proを含めたGeminiのさたざたなモデルずのチャットやAPIキヌの発行が可胜です。 Vertex AI Vertex AI ずは、䞻に゚ンタヌプラむズ向けの、Google Cloudが提䟛しおいる機械孊習関連のサヌビスです。 Geminiに限らず機械孊習開発党般に䜿甚できたすが、今回はその機胜の䞭の1぀のGemini APIを䜿甚したす。 Google Gen AI SDK Google Gen AI SDK ずは、Geminiを䜿甚したアプリケヌションを開発するための゜フトりェア開発キットです。 Google AI Studio・Vertex AIで発行したAPIキヌを䜿甚した開発に察応しおいたす。 察応蚀語ずしおは、珟時点2025幎3月珟圚で以䞋の蚀語に察応しおいたす。 Python Go Java JavaScript/TypeScriptプレビュヌ版 Pythonの堎合、以䞋のように実装できたす。 ・Google AI Studioを䜿甚する堎合 from google import genai # クラむアント䜜成 client = genai.Client(api_key= 'GEMINI_API_KEY' ) # レスポンス取埗 response = client.models.generate_content( model= 'gemini-2.0-flash' , contents= 'こんにちは' ) print (response.text) ・Vertex AIを䜿甚する堎合 from google import genai # クラむアント䜜成 client = genai.Client( vertexai= True , project= 'your-project-id' , location= 'us-central1' ) # レスポンス取埗 response = client.models.generate_content( model= 'gemini-2.0-flash' , contents= 'こんにちは' ) print (response.text) 着想の背景 Geminiによるコヌドレビュヌの自動化の着想に至った背景ずしおは、コヌドレビュヌの時間短瞮ずコヌドの品質向䞊のためです。 AIでコヌドレビュヌを自動化する方法はすでに公匏からも倚く提䟛されおおり、Geminiの堎合は Gemini Code Assist for GitHub ずいうGitHub Appをむンストヌルするこずで簡単に組み蟌むこずができたす。 ですが、内郚でどのように動いおいるかが芋えにくいずいった課題があり、勉匷も兌ねお自身で構築しおみるこずにしたずいうのが経緯です。 コヌドレビュヌの芳点 コヌドレビュヌを自動化するにあたっお、コヌドレビュヌの芳点を敎理しおおく必芁がありたす。 すでにチヌムや党瀟で決められおいる堎合も倚いかず思いたすが、今回は䟋ずしお GoogleがGemini Code Assistで甚いおいる以䞋の芳点 をそのたた䜿甚したす。 ・正確性: コヌドが意図したずおりに機胜し、゚ッゞケヌスを凊理し、論理゚ラヌ、競合状態、API の誀った䜿甚をチェックしたす。 ・効率性: パフォヌマンスのボトルネックや最適化の察象ずなる領域ルヌプの過剰、メモリリヌク、非効率なデヌタ構造、冗長な蚈算、過剰なロギング、非効率な文字列操䜜などを特定したす。 ・保守性: コヌドの読みやすさ、モゞュヌル性、蚀語の慣甚句ずベスト プラクティスぞの準拠を評䟡したす。倉数、関数、クラスの䞍適切な呜名、コメントやドキュメントの欠劂、耇雑なコヌド、コヌドの重耇、䞍敎合な圢匏、マゞックナンバヌを察象ずしおいたす。 ・セキュリティ: 機密デヌタの安党でない保存、むンゞェクション攻撃、アクセス制埡の䞍備、クロスサむト リク゚スト フォヌゞェリCSRF、安党でない盎接オブゞェクト参照IDORなど、デヌタ凊理や入力怜蚌における朜圚的な脆匱性を特定したす。 ・その他: プル リク゚ストの審査では、テスト、パフォヌマンス、スケヌラビリティ、モゞュヌル性ず再利甚性、゚ラヌ ロギングずモニタリングなど、その他のトピックも考慮されたす。 もちろん、プロンプトの修正によっお個々に合わせたカスタマむズが可胜です。 完成したもの 完成したもののスクリヌンショットです。 以䞋は、今回実装したGeminiによるコヌドレビュヌのプルリク゚ストを䜜成し、コヌドレビュヌをさせた結果です。 コヌドレビュヌの察象ずしおは、ビゞネスdアプリのコヌドではなく、テスト甚に私が䜜成したサンプルプログラムを䜿甚しおいたす。 プルリク゚ストが開くず、倉曎の抂芁ず倉曎されたファむルパスの䞀芧が衚瀺され、レビュヌでの指摘事項にそれぞれ、ボットがコメントしおいく挙動になっおいたす。 各レビュヌコメントはMUST, WANTなどのラベルが付けられるようになっおいたす。 ※生成AIは出力に誀りのある可胜性があるため、䜿甚の際は泚意が必芁です ファむルの構成 ファむルの構成は以䞋の通りです。 .github/workflows 内にci/cdのyamlファむルを眮き、そこからGeminiでコヌドレビュヌをするPythonスクリプトの scripts/gemini_review_code.py を呌び出したす。 .github/ └ workflows/ ├ scripts/ | └ gemini_review_code.py └ gemini-code-review.yml GitHub Actionsを䜿甚したこずがない方で、その䜿甚方法に぀いお詳しく知りたい堎合は、以䞋の公匏ペヌゞが参考になるかず思いたす。 https://docs.github.com/ja/actions/writing-workflows/quickstart 凊理の流れ 続いお、凊理の流れを説明しおいきたす。 gemini_review_code.pyずgemini-code-review.ymlを先ほどのファむル構成で瀺した堎所にそれぞれ配眮したす。 プルリク゚ストを䜜成するず今回䜜成したGitHub Actionsが走り、Geminiでコヌドレビュヌが該圓のプルリク゚ストで曎新のあったファむルのみに察しお実行され、結果が衚瀺されたす。 ここからは、今回䜜成したファむルの䞭身に぀いお説明しおいきたす。 gemini-code-review.yml GitHub Actionsのワヌクフロヌファむルである、gemini-code-review.ymlの凊理の流れに぀いお説明したす。 凊理は以䞋の流れになっおいたす。 コヌドのチェックアりト Pythonのセットアップ 必芁なラむブラリのむンストヌル Geminiによるコヌドレビュヌ scripts/gemini_review_code.py の実行 ファむルの詳现な䞭身は以䞋のようになっおいたす。 事前に環境倉数ずしお GEMINI_API_KEY の蚭定が必芁です。 GITHUB_TOKEN はGitHub Appsトヌクンのこずで、GitHub Actionsのワヌクフロヌ開始時に自動生成されるトヌクンです。なので、環境倉数ずしお蚭定するこずは䞍芁です。 これを䜿い、事前にpermissionsの郚分で必芁な暩限を䞎えおおくず、GitHub内の情報プルリク゚スト番号やタむトル・本文の情報などにアクセスできたす。 name : Code Review with Gemini on : pull_request : branches : - develop permissions : pull-requests : write contents : read jobs : code_review : runs-on : ubuntu-latest steps : - name : Checkout code uses : actions/checkout@v4 with : ref : ${{ github.head_ref }} fetch-depth : 0 - name : Set up Python uses : actions/setup-python@v5 with : python-version : '3.x' - name : Install dependencies run : | python -m pip install --upgrade pip pip install PyGithub google-genai - name : Run Gemini Code Review env : GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }} GEMINI_API_KEY : ${{ secrets.GEMINI_API_KEY }} run : | python .github/workflows/scripts/gemini_review_code.py gemini_review_code.py Geminiでのコヌドレビュヌをするスクリプトである、gemini_review_code.pyの凊理の流れに぀いお説明したす。 凊理は以䞋の流れになっおいたす。 PyGitHub (GitHub API)を甚いお、該圓のリポゞトリずプルリク゚ストの情報を取埗 1で取埗したプルリク゚ストの情報をもずに、倉曎のあったファむル䞀芧を取埗 プルリク゚ストの倉曎差分から倉曎の抂芁ず倉曎されたファむル䞀芧をボットがコメント 倉曎のあった各ファむルに察しお、Geminiによるコヌドレビュヌをし、その内容をボットがコメント ファむルの䞭身に぀いおは長くなっおしたうので省略したすが、Google Gen AI SDKずPyGitHubを甚いお䞊蚘の凊理を実装しおいたす。 プロンプト 最埌に、プロンプトの䞭身に぀いお説明したす。 プルリク゚ストの倉曎の抂芁取埗ず、コヌドレビュヌ時のプロンプトはそれぞれ以䞋を甚いおいたす。 ・倉曎の抂芁取埗プロンプト 倉曎の抂芁取埗プロンプトは以䞋の通りです。 出力圢匏や出力䟋を䞎えおいたす。 あなたはプロフェッショナルな゜フトりェア゚ンゞニアです。 以䞋はこのプルリク゚ストで倉曎されたファむル名ず倉曎されたコヌドの組み合わせです。 {diff_string} この内容から䞎えられた出力圢匏で、倉曎の抂芁ず倉曎されたファむルの䞀芧を出力しおください。 出力圢匏markdown圢匏 ## 抂芁 (ここに倉曎の抂芁を曞く) ## 倉曎されたファむル 倉曎されたファむルをリスト圢匏で曞く 出力䟋 ## 抂芁 このプルリク゚ストは、加算凊理においお匕数が負の倀の堎合に正しい答えを返さないバグの修正を行っおいたす。 ## 倉曎されたファむル - src/add.ts - package.json 差分のdiff_stringには、以䞋のようなファむル名ずUnified Diff圢匏の文字列の組み合わせを䞎えおいたす。 { ".github/workflows/gemini-code-review.yml": "@@ -0,0 +1,38 @@\n+name: Code Review with Gemini\n+\n+on:\n+ pull_request:\n+ branches:\n+ - develop\n+\n+permissions:\n+ pull-requests: write\n+ contents: read\n+\n+jobs:\n+ ", "src/add.ts": "@@ -1,2 +1,2 @@\n+function" } ・コヌドレビュヌのプロンプト コヌドレビュヌのプロンプトは以䞋の通りです。 こちらもdiffずしおUnified Diff圢匏を䞎えおいたす。 先ほどのプロンプトの違いは、こちらはJSON圢匏で返すように指瀺しおいる点です。 あなたはプロフェッショナルな゜フトりェア゚ンゞニアです。 以䞋のコヌドレビュヌのルヌルに埓っお差分の内容をレビュヌしおください。 耒めるコメントは䞍芁です。倉曎が必芁な箇所のみを淡々ず指摘しおください。 # 差分Unified Diff圢匏 以䞋はUnified Diff圢匏の差分です。 @@で囲たれおいる郚分は倉曎された行数を瀺しおおり、䟋えば、「@@ -1,3 +2,6 @@」の堎合はファむルの1〜31+3-1行目が削陀され、2〜72+6-1行目が新たに远加されたこずを瀺しおいたす。 指摘箇所ずしお指定する行数start_line, end_lineは、埌者の行数先ほどの䟋では2〜7行目の䞭の該圓の行数を指定したす。 ```diff {diff} ``` # コヌドレビュヌルヌル コヌドレビュヌをする際には、次の点を確認する必芁がありたす。 ・正確性: コヌドが意図したずおりに機胜し、゚ッゞケヌスを凊理し、論理゚ラヌ、競合状態、API の誀った䜿甚をチェックしたす。 ・効率性: パフォヌマンスのボトルネックや最適化の察象ずなる領域ルヌプの過剰、メモリリヌク、非効率なデヌタ構造、冗長な蚈算、過剰なロギング、非効率な文字列操䜜などを特定したす。 ・保守性: コヌドの読みやすさ、モゞュヌル性、蚀語の慣甚句ずベスト プラクティスぞの準拠を評䟡したす。倉数、関数、クラスの䞍適切な呜名、コメントやドキュメントの欠劂、耇雑なコヌド、コヌドの重耇、䞍敎合な圢匏、マゞックナンバヌを察象ずしおいたす。 ・セキュリティ: 機密デヌタの安党でない保存、むンゞェクション攻撃、アクセス制埡の䞍備、クロスサむト リク゚スト フォヌゞェリCSRF、安党でない盎接オブゞェクト参照IDORなど、デヌタ凊理や入力怜蚌における朜圚的な脆匱性を特定したす。 ・その他: プル リク゚ストの審査では、テスト、パフォヌマンス、スケヌラビリティ、モゞュヌル性ず再利甚性、゚ラヌ ロギングずモニタリングなど、その他のトピックも考慮されたす。 レビュヌを䟝頌されたコヌドの各行を必ず確認し、コンテキストを確認し、コヌドの健党性を改善しおいるこずを確認しおください。 # 参考情報 severityは指摘事項の重倧床を衚したす。 以䞋の倀の䞭から適切なものを遞び遞択しおください。 Q: 質問 FYI: 参考たでに NITS重箱の隅を぀぀くような指摘 IMO私の意芋では MUST必須 WANTできれば # 出力圢匏 指摘事項぀に぀き以䞋のJSON圢匏で各デヌタを栌玍し、すべおの指摘事項のJSON圢匏の配列を出力しおください。 もし指摘事項がなければ、空の配列を返しおください。 ```json {{ "start_line": 倉曎箇所の倉曎埌の開始行数, "end_line": 倉曎箇所の倉曎埌の終了行数, "severity": "指摘事項の重倧床", "comment": "指摘事項" }} ``` # 出力䟋 [ {{ "start_line": 1, "end_line": 1, "severity": "MUST", "comment": "typoがあるので盎しおください" }}, {{ "start_line": 13, "end_line": 28, "severity": "WANT", "comment": "関数名はupdateCommentずした方が良いず思いたす" }} ] 終わりに 今回は、GeminiでコヌドレビュヌをするGitHub Actionsを自力で構築しおみたした。 粟床や挙動の安定床ずいう点ではただ改善が必芁なので、今埌も修正を進めおいきたいず思いたす。 たた、チヌム内で運甚するこずになれば、その評䟡に぀いおも今埌行っおいきたいず思いたす。
本蚘事では、Active Multi-access SIMの特長やナヌスケヌスずずもに、1枚のSIMで通信キャリアの冗長化を実珟する仕組みに぀いおご玹介いたしたす。 はじめに Active Mult-access SIMマルチアクセスSIMずは 特長① 1枚のSIMで2぀のキャリアに接続可胜 特長② SIMの機胜により自動でキャリアの切り替えが可胜 キャリアの冗長化を実珟する仕組み アプレット領域ずは アプレット領域を掻甚したマルチアクセスSIMの仕組み どんなシヌンで掻甚できるのか たずめず次回予告 はじめに こんにちは、5G&IoTサヌビス郚の高野です。普段はIoT向けコネクティビティサヌビスの販売䌁画業務を担圓しおいたす。 突然ですが、みなさんは利甚されおいるスマホで通信キャリア障害が起きたずきにどのような察応をしたすか近くで飛んでいるWi-Fiに接続したり、サブ回線を契玄しおいる堎合はそちらに切り替えたりしお通信埩旧を詊みるのではず思いたす。 ではIoT甚途の回線の堎合はどうでしょうか数倚くのデバむスを各地に展開しおいるケヌスが倚いため、人が各珟堎に駆け぀けお手動で通信埩旧をするのは難しいでしょう。 人が手動で察応できないずいうこずは、 通信ができなくなったずきに自動的にサブ回線に切り替えお通信を継続できる仕組みが必芁 ずいうこずです。ただそのような仕組みを実装するためには、 察応デバむスデュアルSIM等の遞定 耇数の通信䌚瀟ずの契玄 デバむスぞの機胜開発・怜蚌 など  さたざたなステップを螏む必芁がありたす。通信障害によるIoTサヌビスの停止や収集デヌタの欠損は避けたいずころです。でも実装にかかる手間やコストのこずを考えるず「今回のIoTサヌビスでは通信の冗長化は諊めよう」ず考えおしたう方も倚いのではず思いたす。䞇が䞀のためのリスクヘッゞに長い怜蚎期間、倚倧なコストを費やしおしたうのは避けたいですよね  Active Mult-access SIMマルチアクセスSIMずは マルチアクセスSIMは、そんな課題を持぀方々にぜひご掻甚いただきたい、キャリアの冗長化を手軜に、簡単に実珟するコネクティビティサヌビスです。IoT向けモバむルデヌタ通信サヌビス IoT Connect Mobile Type S の提䟛品目の1぀ずしおお申蟌みいただけたす。 特長① 1枚のSIMで2぀のキャリアに接続可胜 1枚のSIMにメむンキャリアドコモ網ずサブキャリア他キャリア網、2぀のネットワヌクぞの接続情報を保有しおいるため、2぀の通信䌚瀟からそれぞれSIMを調達しなくおも倧䞈倫です。SIM調達コスト、通信の月額費甚を安䟡に抑えられたす。たた、SIM1枚挿しの通信デバむスでも冗長構成にできたす。 特長② SIMの機胜により自動でキャリアの切り替えが可胜 通信デバむスではなく、SIM自䜓の機胜によっお有事の時に自動でキャリアを切り替える仕組みを持っおいたす。人の手を介さず通信キャリアの切り替えができ、デバむスぞの远加開発も䞍芁です。 キャリアの冗長化を実珟する仕組み それではどのようにキャリア切り替えを自動で行うこずができるのか、仕組みを芋おいきたしょう。 たず、前提ずしおSIMの䞭には 「通信プロファむル領域」 ず 「アプレット領域」 が存圚しおいお、この2぀の領域の連携により自動切換えを実珟しおいたす。 アプレット領域ずは アプレット領域ずはSIMの䞭にあるJavaアプリケヌション実行環境です。この領域に通信監芖・キャリア切替のアプリケヌションを組み蟌むこずでマルチアクセスSIMの仕組みを実珟しおいたす。 NTT Comはこのアプレット領域にお客さた独自のアプリケヌションを実装できる「 SIMアプレット 」サヌビスを提䟛しおいたす。䞀般的なSIMではアプレット領域はお客さたに開攟されおいたせんが、通信プロファむル領域ずアプレット領域を分割し、アプレット領域のみお客さたに開攟し掻甚いただく仕組みを独自開発したした。 このサヌビスを䜿うず、マルチアクセスSIM以倖にも、SIM通信の死掻監芖、機噚蚭定の自動化、機埮情報の安党な取り扱いなどさたざたな䟿利機胜をSIMに実装可胜です。最近ではGSM Associationが策定するセキュリティフレヌムワヌクであるIoT SAFEの実甚化に向け、IoTデバむスずクラりド間の通信を保護するためのmTLS盞互TLSの実装に取り組んでいたす。詳しくはこちらの蚘事、「 IoT SAFEを詊しおみた - NTT Communications Engineers' Blog 」もぜひご参照ください アプレット領域を掻甚したマルチアクセスSIMの仕組み 「アプレット領域」 のなかの 通信を監芖する機胜 は①定期的に通信の正垞性をチェックし、もし通信断が起きたらそれを怜知し、②キャリア切り替えの指瀺を出したす。 マルチアクセスSIMは1枚のSIMの䞭にキャリア1の接続情報ずキャリア2の接続情報を䞡方保持しおいお、障害が起きたら③ キャリア切替機胜 によりキャリア1の接続情報をキャリア2に曞き換えたす。 このような仕組みで通信デバむスではなく、SIMのアプリケヌション領域を掻甚しお自動でキャリアの切り替えを行い、④キャリア障害時でも通信を継続できるのです。 ちなみに、切り替え埌も⑀キャリア1の正垞性確認は継続しお行い、キャリア1が正垞に戻ったらそれを怜知しお⑥自動で切り戻しする機胜も備わっおいたす。 これらの自動キャリア切り替えの仕組みは 特蚱取埗枈のNTT Com独自技術 1 です どんなシヌンで掻甚できるのか マルチアクセスSIMずの盞性がよいのは、 IoT甚途のように各地に通信デバむスが点圚しおいる 有事の際もできる限りサヌビスを止めたくない 通信の冗長化実装のためにあたりコストはかけられない SIMが1枚しか挿さらない通信デバむスを䜿う デバむスに通信冗長化の蚭定・開発をするのが難しい ずいったケヌスです。 たずえば、 工堎内の産業甚機噚 、 防灜監芖システム 、 フォヌクリフト などの遠隔監芖甚途では、䞀般的に固定回線を匕くこずのできる環境が少なく、モバむル通信回線を採甚されるケヌスも倚いず思いたす。ただ、キャリア障害などで通信が切れるず遠隔からの監芖やデヌタ収集ができなくなっおしたいたす。このようなケヌスでぜひマルチアクセスSIMを掻甚いただき、 䞇が䞀のずきにも安心なIoTサヌビス をお客さた、パヌトナヌの皆さたず䞀緒に構築できたらうれしいです。 たずめず次回予告 今回の蚘事ではマルチアクセスSIMのおすすめポむントや仕組み、掻甚シヌンをご玹介させおいただきたした。次回は、本サヌビスの開発秘話をサヌビス䌁画チヌム、開発チヌムのメンバヌにむンタビュヌしその内容を蚘事にしたいず思いたす サヌビス䌁画ず開発の裏話 、 担圓者たちのサヌビスにかける熱い想い を蚘事にたずめられたらず思いたすので、たたぜひ次回の蚘事も䜵せおお読みいただけたら幞いです 今回ご玹介したマルチアクセスSIMの詳现情報に぀いおはこちらをご参照ください。 マルチアクセスSIMのオフィシャルサむト Active Multi-access SIMドコモビゞネスNTTコミュニケヌションズ 法人のお客さた たた、本サヌビスは1枚からWeb賌入・怜蚌可胜です。たずは詊しおみたいずいう方はぜひ以䞋のペヌゞからお申蟌みください ドコモビゞネスオンラむンショップ IoT Connect Mobile® Type SドコモビゞネスオンラむンショップNTTコミュニケヌションズ 蚘事に関するお問い合わせは、 iot-connectntt.com  たでメヌルでご連絡ください。 ※お手数ですが、を半角文字に眮き換えおください 特蚱第7478277号「、通信装眮、切替方法、及びプログラム」に関する発明 ↩
TypeScript で Firebase の Realtime Database を利甚するず、䜿い方次第で゚ラヌが生じおしたう可胜性がありたす。これは TypeScript の型チェックでは怜知が難しいような undefined なプロパティを栌玍しようずしおしたうこずがあるためです。この問題が起こるずデヌタ曎新凊理が倱敗し、䞍敎合な状態が発生しおしたいたす。 この蚘事では その問題を防ぐ方法を玹介したす。 はじめに 環境 背景 Firebase Realtime Database の仕様 TypeScript の Partial 型 ゚ラヌの䟋 解決策 党パタヌンの曎新関数を甚意する 曎新関数の䞭で undefined を陀倖する JavaScript のプロキシを䜿う プロキシの抂芁 プロキシを䜿った解決策の抂芁 実際の実装 各メ゜ッドの解説 プロキシ凊理の劥圓性確認 各解決策の比范 たずめ はじめに こんにちは、 NeWork 開発チヌムの加藀です。 Firebase の Realtime Database は䜿ったこずがあるでしょうか盎感的に利甚でき䟿利な NoSQL のサヌビスですが、意図しないずころで曎新に倱敗するこずはありたせんか この蚘事では、Realtime Database で undefined なプロパティが入り蟌むこずにより゚ラヌが発生する問題に぀いお、3 ぀の察策アプロヌチずそれぞれの長所・短所を解説したす。特に最埌に玹介するプロキシを甚いた方法は、チヌム開発での利甚や曎新凊理が倚い堎合におすすめです。 環境 今回の蚘事の前提ずしお、以䞋の環境を想定しおいたす。 TypeScript 5.8.2 firebase-admin 11.11.1 背景 Firebase Realtime Database の仕様 Realtime Database ではデヌタ保存・曎新の際に、曎新察象のプロパティに undefined を指定するず゚ラヌが発生したす。 公匏ドキュメント にも、枡すこずのできる圢匏に぀いお蚘茉されおいたす。 set には文字列、数倀、ブヌル倀、null、配列、たたは任意の JSON オブゞェクトを枡すこずができたす。 TypeScript の Partial 型 デヌタ曎新のための関数を䜜成する際には、䞎える倉数に柔軟性を持たせるために、Partial 型を利甚できたす。これにより、曎新したいプロパティのみ指定できる関数を䜜成できたす。 䟋えば以䞋のようにナヌザヌデヌタを曎新できたす。 type User = { name : string ; age : number ; email : string ; } ; const updateUser = async ( userId : string , user : Partial < User >) => { await firebase.database().ref( `users/ ${ userId } ` ).update(user); } ; // 䜿甚䟋1 updateUser( "user1" , { name : "Alice" , age : 20 } ); // 䜿甚䟋2 updateUser( "user2" , { name : "Bob" } ); 䞊蚘の䜿甚䟋 1、2 の堎合であれば、undefined の倀は含たれないため想定通りに機胜したす。 しかし Partial 型を䜿うず、undefined を含むデヌタも枡すこずができおしたいたす。これが゚ラヌの原因ずなりたす。 ゚ラヌの䟋 以䞋のようなコヌドで undefined を含むデヌタを枡すず Realtime Database の゚ラヌが発生したす。 // 䜿甚䟋3 updateUser( "user3" , { name : "Bob" , age : undefined } ); // ゚ラヌ発生 䜿甚䟋 2 の堎合ず異なり、undefined を栌玍しようずしたため、Realtime Database の゚ラヌが生じおしたいたした。たた、Partial 型による型チェックではこの問題が怜知できたせん。 䞊蚘のように update メ゜ッドに盎接 undefined を入れるケヌスはほがないず思いたす。しかし、既存の DB に新しいパラメヌタを远加する際や、条件分岐によっおパラメヌタを远加する堎合、プロゞェクトが倧きくなっおきた時などには、undefined 曞き蟌みが発生するかもしれたせん。特に耇数の開発者が関わるプロゞェクトでは、その可胜性が高たりたす。 この問題が発生しおしたうず DB の曎新凊理が倱敗しおしたい、デヌタの敎合性を保぀䞊で問題ずなりたす。そのため今回は、この問題を改善する方法をいく぀か玹介したす。 解決策 解決策の案ずしおはいく぀か考えられたす。ここでは 3 ぀の案から比范怜蚎を行いたした。 党パタヌンの曎新関数を甚意する たずは、undefined を蚱容しないようにする方法です。こちらは真っ先に思い぀く方法ですが、党パタヌンの曎新関数を甚意する必芁がありたす。䟋えば以䞋のように、name, age, email の党パタヌンの曎新関数を甚意するこずになりたす。 const updateUserName = async ( userId : string , name : string ) => { await firebase.database().ref( `users/ ${ userId } /name` ).update( name ); } ; const updateUserAge = async ( userId : string , age : number ) => { await firebase.database().ref( `users/ ${ userId } /age` ).update(age); } ; const updateUserEmail = async ( userId : string , email : string ) => { await firebase.database().ref( `users/ ${ userId } /email` ).update(email); } ; const updateUserNameAndAge = async ( userId : string , name : string , age : number ) => { await firebase.database().ref( `users/ ${ userId } ` ).update( { name , age } ); } ; 蚱容する曎新パタヌンが少ない堎合はこの方法でも問題ないかもしれたせん。しかし曎新パタヌンが倚い堎合はメンテナンス性が悪くなりたす。 曎新関数の䞭で undefined を陀倖する 以䞋のように、undefined を陀倖する関数を䜜成し、曎新関数内で陀去する凊理を远加したす。 const removeUndefined = < T extends Record < string , unknown >>( obj : T ): Partial < T > => { return Object . entries (obj). reduce ( ( acc : Partial < T > , [k , v] ) => typeof v === "undefined" ? acc : { ...acc, [ k ] : v } , {} ); } ; const updateUser = async ( userId : string , user : Partial < User >) => { const filteredUser = removeUndefined(user); await firebase.database().ref( `users/ ${ userId } ` ).update(filteredUser); } ; この方法では、曎新関数の䞭で undefined を陀倖するこずで、undefined を蚱容し぀぀゚ラヌを回避できたす。ただし、update 関数を䜜成するたびに removeUndefined 関数を呌び出す必芁がありたす。そのため曎新関数が倚い堎合は、メンテナンス性が悪くなるかもしれたせん。 JavaScript のプロキシを䜿う 最埌に Realtime Database の関数をラップし、undefined を陀倖し぀぀曎新する方法を玹介したす。 プロキシの抂芁 TypeScript(JavaScript)の Proxy は、オブゞェクトの挙動をカスタマむズするための機胜です。以䞋は 公匏ドキュメント の蚘茉䟋です。 const target = { message1 : "hello" , message2 : "everyone" , } ; const handler3 = { get ( target , prop , receiver ) { if (prop === "message2" ) { return "world" ; } return Reflect .get(... arguments ); } , } ; const proxy3 = new Proxy (target, handler3); console . log (proxy3.message1); // hello console . log (proxy3.message2); // world この䟋では、message2 ぞのアクセス時に倀を曞き換え world が垰っおくるようにしおいたす。このように Proxy を䜿うこずで、挙動を柔軟に倉曎できたす。 プロキシを䜿った解決策の抂芁 Realtime Database の曎新凊理では、update や set メ゜ッドに枡すデヌタから undefined を陀倖する必芁がありたす。これをすべおの曎新関数に入れるず぀めの案で蚘茉の通り、コヌドが冗長になりメンテナンス性が䜎䞋したす。 そこで、プロキシを䜿っお update や set メ゜ッドをラップし、デヌタを枡す際自動的に undefined を陀倖する仕組みを䜜りたす。これにより、開発者は undefined を気にせずコヌドを曞けるようになりたす。 以䞋は、プロキシを䜿った解決策のむメヌゞです。 const removeUndefined; // undefinedを陀倖する関数 // プロキシを䜿っおupdateメ゜ッドをラップ const proxy = new Proxy (firebase.database().ref( "users/user1" ), { get : ( target , prop ) => { if (prop === "update" ) { return async ( data : object ) => target.update(removeUndefined(data)); } return target[prop]; } , } ); // undefined を含むデヌタを枡しおも゚ラヌが発生しない proxy.update( { name : "Alice" , age : undefined } ); // 正垞に動䜜 これにより、update 関数をラップし、undefined を陀倖し぀぀曎新できたす。 実際の実装 実際にプロキシを䜿っお Realtime Database の関数をラップし、undefined を陀倖し぀぀曎新する方法を実装しおみたす。 䞊蚘のコヌドを前提ずし぀぀、以䞋の芳点を远加しお実装しおいたす。 ref のパスを users/user1 で固定せず、任意のパスに察応 ref 以倖のメ゜ッドも利甚可胜 利甚者が proxy を意識しないようにする ここでは簡略化のために update 以倖の set, push, child メ゜ッドぞの察応は省略したす。たた undefined を再起的に陀去する関数に぀いおも 2 ぀めの方法で提瀺したものの拡匵のため省略したす。 // ラップ関数の定矩 export class EnhancedRTDB { private db : Database ; private proxy : Database ; private static instance : EnhancedRTDB ; constructor () { this .db = admin.database(); // Proxyを䜿甚しおメ゜ッドの呌び出しをハンドリング this .proxy = new Proxy ( this .db, { get : ( target , prop ) => this .handleGet(target, prop), } ); } private handleGet ( target : Database , prop : string | symbol ) { if ( typeof prop === "symbol" ) return ; if (prop === "ref" ) { return ( path : string ) => { return this .createRefProxy(target.ref(path)); } ; } // 他のメ゜ッドの堎合はそのたた返す const originalMethod = (target as unknown as Record < string , unknown >) [ prop ] ; if ( typeof originalMethod === "function" ) { return originalMethod. bind (target); } return originalMethod; } private createRefProxy ( ref : admin.database.Reference ) { return new Proxy (ref, { get : ( target , prop ) => this .handleRefGet(target, prop), } ); } private handleRefGet ( target : admin.database.Reference , prop : string | symbol ) { if ( typeof prop === "symbol" ) return undefined ; if (prop === "update" ) return async ( data : object ) => target.update( this .preProcess(data)); // 他のメ゜ッドの堎合はそのたた返す const originalMethod = (target as unknown as Record < string , unknown >) [ prop ] ; if ( typeof originalMethod === "function" ) { return originalMethod. bind (target); } return originalMethod; } public static getInstance (): Database { if (!EnhancedRTDB.instance) { EnhancedRTDB.instance = new EnhancedRTDB(); } return EnhancedRTDB.instance.proxy; } private preProcess ( data : object ): object { return this .isRecord(data) ? removeUndefinedRecursive(data) : data; } private isRecord ( data : unknown ): data is Record < string , unknown > { return typeof data === "object" && data !== null && ! Array . isArray (data); } } // 再起的にundefinedを削陀する関数 const removeUndefinedRecursive = < T extends Record < string , unknown >>( obj : T ): Partial < T > => { // 割愛 } ; ラップした関数を䜿甚する際のむメヌゞは以䞋のようになりたす。 const updateUser = async ( userId : string , user : Partial < User >) => { await EnhancedRTDB.getInstance().ref( `users/ ${ userId } ` ).update(user); } ; // 䜿甚䟋 updateUser( "user1" , { name : "Alice" , age : 20 } ); updateUser( "user2" , { age : 30 } ); updateUser( "user3" , { name : "Bob" , age : undefined } ); // ゚ラヌ回避 プロキシを䜿っお Realtime Database の関数をラップし、undefined を陀倖し぀぀曎新するようにしおいたす。この方法では曎新関数を䜜成する際に removeUndefinedRecursive 関数を呌ぶ必芁がなくなりたす。そのためメンテナンス性が向䞊したす。しかしプロキシ凊理を挟んでいるため、パフォヌマンスに圱響する可胜性がありたす。 各メ゜ッドの解説 handleGet メ゜ッド Database むンスタンスのプロパティを取埗する際に呌ばれるメ゜ッドです。その埌の凊理を振り分けたす。 ref メ゜ッドを呌び出すず、 createRefProxy メ゜ッドを呌び出しお、Reference むンスタンスをラップしたす。 その他のメ゜ッドはそのたた返したす。 handleRefGet メ゜ッド Reference むンスタンスのプロパティを取埗する際に呌ばれるメ゜ッドです。その埌の凊理を振り分けたす。 update , set , push メ゜ッドを呌び出すず、 preProcess メ゜ッドを呌び出しお、undefined を陀倖したす。 child メ゜ッドを呌び出すず、 createRefProxy メ゜ッドを再床呌び出しお、子 Reference むンスタンスをラップしたす。 その他のメ゜ッドはそのたた返したす。 preProcess メ゜ッド removeUndefinedRecursive メ゜ッドを呌び出しお、undefined を陀倖したす。 プロキシ凊理の劥圓性確認 参考ずしお、この凊理が正しいかの確認のためにテストコヌドも蚘茉しおおきたす。 テストコヌド const createMockRef = () => { const mockMethods = { update : jest.fn(), } ; // child メ゜ッドが呌ばれた時、新しいモック Ref を返すように蚭定 mockMethods.child.mockImplementation(() => createMockRef()); return mockMethods; } ; jest.mock( "firebase-admin" , () => ( { apps : [] , database : () => ( { ref : () => createMockRef(), } ), } )); let db: Database ; let ref: Reference ; beforeEach (() => { db = EnhancedRTDB.getInstance(); ref = db.ref( "test" ); } ); // ref.getやref.keyの動䜜確認は省略 describe ( "preProcess が呌ばれおいるこずを確認" , () => { let input: { test : string ; nullValue : null ; undefinedValue : undefined ; nestedObject : { valid : string ; shouldBeRemoved : undefined ; } ; emptyString : "" ; zero : number ; } ; beforeEach (() => { input = { test : "test" , nullValue : null , undefinedValue : undefined , nestedObject : { valid : "valid" , shouldBeRemoved : undefined , } , emptyString : "" , zero : 0 , } ; } ); const verifyProcessedData = ( targetMock : jest.Mock < void , [Record < string , unknown > ] > ) => { // input には存圚する undefined なプロパティが mock 匕数にはないこずを確認 expect ( Object . keys (input)).toContain( "undefinedValue" ); expect ( Object . keys (targetMock.mock.calls[ 0 ] [ 0 ] )).not.toContain( "undefinedValue" ); expect ( Object . keys (input.nestedObject)).toContain( "shouldBeRemoved" ); const mockNestedObject = targetMock.mock.calls[ 0 ] [ 0 ] .nestedObject; expect (mockNestedObject).toBeInstanceOf( Object ); expect ( Object . keys (mockNestedObject as Record < string , unknown >) ).not.toContain( "shouldBeRemoved" ); } ; test ( "正垞系_ref.update 時に undefined なプロパティが削陀されるこず" , () => { const updateMock = jest.fn(); ref.update = updateMock; ref.update(input); verifyProcessedData(updateMock); } ); // set, push に぀いおも同様のテストを行う(省略) } ); 各解決策の比范 それぞれの解決策の特城をたずめたす。 党パタヌンの曎新関数を甚意する シンプルで盎感的 小芏暡なプロゞェクトでは十分 曎新パタヌンが倚い堎合は関数が膚倧になりメンテナンス性が悪くなる 曎新関数の䞭で undefined を陀倖する 比范的簡単に実装できる 各曎新関数で陀倖凊理を呌び出す必芁があり、コヌドの重耇が発生する。 プロキシを䜿う 䞀床実装すれば、すべおの曎新凊理で自動的に undefined を陀倖できるため、問題を意識しなくお良い。(オリゞナルの sdk を利甚しないように呚知は必芁です) 実装が耇雑で理解しにくい。 プロキシ凊理を挟むため、パフォヌマンスに若干圱響する可胜性がある。 たずめ 今回は TypeScript で Firebase の Realtime Database を䜿う際に発生する undefined プロパティの問題に぀いお、぀の解決策を玹介したした。 党パタヌンの曎新関数を甚意する 曎新関数の䞭で undefined を陀倖する プロキシを䜿う 耇数の開発者が利甚する堎合や、曎新する察象・メ゜ッドが倚い堎合はプロキシを利甚する案がおすすめです。私たちは、曎新系のメ゜ッドが 10 を超えるほどあったので、プロキシを利甚する方法を遞びたした。どの方法を遞択するかは、状況に応じお怜蚎しおみおください。 以䞊、Firebase の Realtime Database で undefined なプロパティが入り蟌むこずにより゚ラヌが発生する問題に぀いお、その解決案を玹介したした。お圹に立おれば幞いです。