<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
    <title>Fractal Prologue&#x2F;Monologue</title>
    <subtitle>機械学習エンジニア &#x2F; MLOps エンジニアとして，過去には推薦・検索・生成 AI システムの開発に携わり，現在では自動運転車開発における MLOps の仕組み作りなどに携わっています．より大規模なデータやシステムを活用して社会的にインパクトを与えられるような機械学習の社会実装と継続的な仕組み作りに興味があります．</subtitle>
    <link rel="self" type="application/atom+xml" href="https://masatakashiwagi.com/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://masatakashiwagi.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-12-31T00:00:00+00:00</updated>
    <id>https://masatakashiwagi.com/atom.xml</id>
    <entry xml:lang="ja">
        <title>2025年の振り返り🚀</title>
        <published>2025-12-31T00:00:00+00:00</published>
        <updated>2025-12-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/look-back-on-this-year-2025/"/>
        <id>https://masatakashiwagi.com/blog/look-back-on-this-year-2025/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/look-back-on-this-year-2025/">&lt;p&gt;今年は子供が幼稚園に通い始めて日々の生活リズムが変化して規則正しくなったものの，幼稚園で風邪を貰ってきたりで月一ぐらいは家族の誰かが風邪を引いたりしてました．仕事面では，夏頃に2年半ぶりに転職して（そろそろジョブホッパーと言われる頃合いかも），2025年後半は色々と慌ただしかったです．&lt;&#x2F;p&gt;
&lt;p&gt;そんなこんなで色々と変化がある一年だったかなと思います．&lt;strong&gt;変化があると新しい気づきや発見，体験が出来て飽き性の自分にとっては楽しい日々です&lt;&#x2F;strong&gt;．&lt;&#x2F;p&gt;
&lt;p&gt;※ 年末年始に時間が取れずに年明けにこのブログを書いています😅&lt;&#x2F;p&gt;
&lt;h2 id=&quot;shi-shi-bian&quot;&gt;仕事編&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;tetukuridomaneziyatositedong-itemite&quot;&gt;テックリードマネージャーとして動いてみて&lt;&#x2F;h3&gt;
&lt;p&gt;今年前半は前職でテックリードマネージャーとして，マネージャーとプレイヤーの二足の草鞋を履いて仕事をしていました．マネージャーと言ってもメンバーはミドル以上だったので，手取り足取り何かをするというわけではなく，チームの目標を設定してそれに向けて成果を出すために一緒に考えたり，動きやすいように交通整理をしていました（他にも細かい仕事は色々とありました）．&lt;&#x2F;p&gt;
&lt;p&gt;一方でチームが4人程度だったので，自分自身がプレイヤーとして動くことを会社からは求められていて，マネジメントと自身のプロジェクトとのリソース配分に悩んで余裕がない時もありました．マネジメント業務では手を動かすというよりは頭を使うことが多く，隙間時間でちょこちょこできるものではなく，まとまった時間を確保しないとアウトプットを出すことがこの時の僕にとっては難しかったです．結果として，プレイヤーとしてのタスクもあり，そちらでも成果を出す必要があったので，色々なものが中途半端になってしまうことがありました．また，自分の中でもマネージャーとして働く覚悟が足りていなかったのと，実際経験すると上手くバランスを取れなかったなと反省しています．&lt;&#x2F;p&gt;
&lt;p&gt;今思うとマネージャーは責任とプレッシャーもありますが，&lt;strong&gt;大きな成果を出すためにレバレッジを効かせる権限を持っている&lt;&#x2F;strong&gt;ので，それはメンバーでは出せないバリューでもあり，考え方を切り替えて物事を進める決心があっても良かったのかもしれません．今後機会があれば，また挑戦したいと思います．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sheng-cheng-ai-gatai-tou-sitekitejin-gai-metesi-ukoto&quot;&gt;生成 AI が台頭してきて今改めて思うこと&lt;&#x2F;h3&gt;
&lt;p&gt;生成 AI が台頭して技術の流れが早まって来たと当時は感じていて，プレイヤーとして順応していけなくなるのでは？という漠然とした不安がありました．ただ今となっては生成 AI でできることは増えて民主化されつつありますが，根本の技術は今まで通り理解する必要があり，何でもかんでも生成 AI を使う必要もなく，自社のビジネスを理解して，どこにどうやってどのタイミングと規模感で適切な技術を充てるかは今までと変わりがないのかもしれないです．プロダクションまでのスピードが早まり，選択肢が増えたと考えるといいのかもしれません（とは言っても運用を考えると生成 AI を上手く制御するのはまだ課題がありそうです）．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;qian-zhi-denozui-hou-nopuroziekuto&quot;&gt;前職での最後のプロジェクト&lt;&#x2F;h3&gt;
&lt;p&gt;プレイヤーとしては，最後に検索システムのデータ基盤を整備するプロジェクトを担当していました．検索精度面で課題があり，スコアリングの活用やより高度な検索を実現するために，データベースから Elasticsearch へのデータインジェストを担うパイプラインを整備しました．システム的には，Google Cloud の Dataflow と Workflows を使ってニアリアルタイムでデータ同期を実現したのと，精度面はアナライザーやスコアリング関数（Function Score Query）を調整して良さげなものを用意しました．というプロジェクトを結構タイトなスケジュールの中，一人で複数のステークホルダーと調整してゼロから仕上げたので，&lt;strong&gt;達成感と燃え尽き気味だった&lt;&#x2F;strong&gt;のかもしれないです．&lt;&#x2F;p&gt;
&lt;center&gt;&lt;blockquote class=&quot;bluesky-embed&quot; data-bluesky-uri=&quot;at:&#x2F;&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;app.bsky.feed.post&#x2F;3ltohyfymz22v&quot; data-bluesky-cid=&quot;bafyreiav5abnjt62n7iorrxqjigdlhckkgpayncgewpxj6pq7q5oug7a74&quot; data-bluesky-embed-color-mode=&quot;system&quot;&gt;&lt;p lang=&quot;ja&quot;&gt;本日でコミューン最終出社日でした！
2年半ぐらいでしたが、機械学習チームの立ち上げからチームのマネジメント、推薦基盤に検索基盤、生成AIシステムなど、失敗もありましたが、AI&#x2F;MLに関連する基礎には貢献できたかなと思います。次は8月からなので、7月残りは夏休みとして過ごします👋&lt;br&gt;&lt;br&gt;&lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;post&#x2F;3ltohyfymz22v?ref_src=embed&quot;&gt;[image or embed]&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (&lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz?ref_src=embed&quot;&gt;@asteriam.bsky.social&lt;&#x2F;a&gt;) &lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;post&#x2F;3ltohyfymz22v?ref_src=embed&quot;&gt;2025年7月11日 17:56&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt;&lt;script async src=&quot;https:&#x2F;&#x2F;embed.bsky.app&#x2F;static&#x2F;embed.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;&lt;&#x2F;center&gt;
&lt;h3 id=&quot;zhuan-zhi-hou-individual-contributor-tositenozai-sutato&quot;&gt;転職後：Individual Contributor としての再スタート&lt;&#x2F;h3&gt;
&lt;p&gt;そこから8月に転職して，今は自動運転で物流課題を解決する会社で MLOps 周りの取り組みをリードしています．Individual Contributor として，自分のタスクに集中して直接成果を出すためにより専門性を高める必要性を感じています．やっぱり AI&#x2F;ML という技術を軸にして，調査・開発・運用と自分で手を動かして貢献するのが好きだなと感じています．&lt;&#x2F;p&gt;
&lt;p&gt;特に去年2024年の振り返りでも書いていましたが，最近取り上げられることも多くなってきた &lt;strong&gt;Physical AI 領域での機械学習適用には当分関わりたい&lt;&#x2F;strong&gt;と思っています．&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;個人的に物理の世界（リアルワールド）での機械学習適用に再び興味が戻って来ていて&lt;br&gt;
引用：&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masatakashiwagi.com&#x2F;blog&#x2F;look-back-on-this-year-2024&#x2F;&quot;&gt;2024年の振り返り🚀&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;仕事関連で技術的に興味があるのは，データ周り（VLM を活用したオートラベリング・キャプション生成，データキュレーションなど）の効率化だったり，モデル改善ループ（アクティブラーニングなど）周りの高度化を AI&#x2F;ML × SWE でどう仕組み化していくか，その改善をどう回していくかに興味を持っています．また最近では，動画を直接扱えるような VLM やドメイン特化の Small LLM&#x2F;VLM の開発やモデル推論周りが気になっています．&lt;&#x2F;p&gt;
&lt;center&gt;&lt;blockquote class=&quot;bluesky-embed&quot; data-bluesky-uri=&quot;at:&#x2F;&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;app.bsky.feed.post&#x2F;3lvd6yvgtes2h&quot; data-bluesky-cid=&quot;bafyreia3py4zkprutprb4cxbrf7k52y4s4jtypooswakujaf4tp5unr2x4&quot; data-bluesky-embed-color-mode=&quot;system&quot;&gt;&lt;p lang=&quot;ja&quot;&gt;今日からT2でトラックの幹線道路におけるレベル4自動運転実現のためにMLOpsやって行きます！&lt;br&gt;&lt;br&gt;&lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;post&#x2F;3lvd6yvgtes2h?ref_src=embed&quot;&gt;[image or embed]&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (&lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz?ref_src=embed&quot;&gt;@asteriam.bsky.social&lt;&#x2F;a&gt;) &lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;post&#x2F;3lvd6yvgtes2h?ref_src=embed&quot;&gt;2025年8月1日 17:07&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt;&lt;script async src=&quot;https:&#x2F;&#x2F;embed.bsky.app&#x2F;static&#x2F;embed.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;&lt;&#x2F;center&gt;
&lt;p&gt;という感じで巷で賑わっている生成 AI を組み込んだ Web サービス &#x2F; SaaS 開発とは少し距離があきそうなので，浦島太郎状態になりそうな気もしますが，動向は追いつつも限界まで conventional な AI&#x2F;ML を堪能しようと思います（あくまで個人的な感想ですが，現状は生成 AI プロバイダーが提供する API を使うだけ（と言ったら怒られそうですが...）の仕事はあまり乗り気がしないです）．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;puraibetobian&quot;&gt;プライベート編&lt;&#x2F;h2&gt;
&lt;p&gt;2025年の前半のプライベートの思い出は&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masatakashiwagi.com&#x2F;blog&#x2F;look-back-at-from-january-to-june-2025&#x2F;&quot;&gt;こちら&lt;&#x2F;a&gt;にあるので，そちらをご覧下さい．&lt;&#x2F;p&gt;
&lt;p&gt;8月以降は転職直後というのもあって，10月に大阪に帰省した以外旅行などには行かなかったです．今年から子供が幼稚園に通いだしたので，体調を考慮して近場で過ごしたりすることが多かったかなと思います．小学生になると益々旅行の機会が減りそうな気がするのとここ数年行けていないので，来年は沖縄に切実に行きたいです😅&lt;&#x2F;p&gt;
&lt;p&gt;良かったことといえば，幼稚園で仲の良い家族グループでスポッチャや人工スキー場に行ったり，その後の飲み会で交流することができたのは，とても幸せを感じるイベントでした．こういった身近なコミュニティでの体験や経験がより実感を持って幸せを感じるのかもしれないと最近は思います．個人的にはパパ友が出来たのが何気に嬉しかったです☺️&lt;&#x2F;p&gt;
&lt;p&gt;ネットでの知り合いにも近しい子を持つ人達も居ますが，リアルでの交流は無かったりするので，是非一緒に遊んだりできると同じ年齢の子を持つ親として共感できることが多そうだなと思ったりしています．&lt;&#x2F;p&gt;
&lt;p&gt;あとプライベートで悩みがあるとすれば，個人プロジェクトや学習の時間をどう捻出するかという問題があります．土日は家族に時間を割くので，なかなか自分の時間を取るのが難しく，平日も子供の寝かしつけ等々で22時以降でないと時間を取るのが難しく，あんまり夜更かしすると翌日の体調に影響が出てきます．同じような生活リズムでも時間を捻出している人を見ると尊敬でしか無いです．あと1日中パソコンに触れているので，夜も触れると睡眠の質が悪くなるのを露骨に感じる年齢になってきたというのもあり，なかなか難しい問題です... 良い折り合いの付け方をご存知の方は教えて下さい🙏&lt;&#x2F;p&gt;
&lt;p&gt;他に何かなかったか思い出してみると，Perfume がコールドスリープするので，来年以降当分は新曲が聞けなくなってしまい悲しかったり，一方で Switch2 を色々と探し回ってゲットできて嬉しかったり，トラックボールのマウスを友人に勧められて初めて買ったら，使い心地に感動したりなどがありました😆&lt;&#x2F;p&gt;
&lt;center&gt;&lt;blockquote class=&quot;bluesky-embed&quot; data-bluesky-uri=&quot;at:&#x2F;&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;app.bsky.feed.post&#x2F;3lyp57zjgx225&quot; data-bluesky-cid=&quot;bafyreigy7eb7lrxl6btc5u2caqo3oo47vxfebckb5lsuavljqe7iizq67m&quot; data-bluesky-embed-color-mode=&quot;system&quot;&gt;&lt;p lang=&quot;ja&quot;&gt;遂にSwitch2ゲットできた🎉&lt;br&gt;&lt;br&gt;&lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;post&#x2F;3lyp57zjgx225?ref_src=embed&quot;&gt;[image or embed]&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (&lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz?ref_src=embed&quot;&gt;@asteriam.bsky.social&lt;&#x2F;a&gt;) &lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;post&#x2F;3lyp57zjgx225?ref_src=embed&quot;&gt;2025年9月13日 15:22&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt;&lt;script async src=&quot;https:&#x2F;&#x2F;embed.bsky.app&#x2F;static&#x2F;embed.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;&lt;&#x2F;center&gt;
&lt;h3 id=&quot;owarini&quot;&gt;おわりに&lt;&#x2F;h3&gt;
&lt;p&gt;最近は X を開く頻度が落ちてきたなと感じていて，というのも X は心がざわつくツイートがタイムラインに流れてくるのが多く心理的にもよろしく無いので，見ないようになっているのだと思う．とはいえ知り合いの多くはまだまだ X 上に居るし，海外からの情報は X で流れることもままあるので，全く見ないわけではない．でも心が落ち着くのは確実に Bluesky になっている今日この頃です．&lt;&#x2F;p&gt;
&lt;p&gt;全然話が変わりますが，もう一つ最近思うことは，OpenAI &#x2F; Anthropic &#x2F; Google 等が提供する生成 AI の API をプロダクトに組み込まれていくのを見ると，これは機械学習エンジニアの持っているスキルセットよりは，ソフトウェアエンジニアが持っているスキルセットであるエンジニアリング要素が強く，そちらの人達がより speedy に AI&#x2F;ML を組み込んだ機能を形作って活躍できる，また求められていると感じています（この辺の認識は人それぞれあると思います）．それらを鑑みると，機械学習エンジニアはどう振る舞っていくと良いのでしょうか．ソフトウェアエンジニアリングスキルを上げていく？よりビジネス側に踏み込んでいく？生成 AI プロバイダーの API では困難なフィールドを模索する？あまり打算的に考えるのは好きでは無いですが，世の中の情勢を把握して生存戦略を考えることは必要だと思うので，自分自身が満たされる &amp;amp; 家族を養えるぐらいのことは考えておきたいです．今のところは，答えを急がずに物理的なフィールドでの AI&#x2F;ML の実践を手を動かし続けながら考えていきたい所存です．&lt;&#x2F;p&gt;
&lt;p&gt;ではでは今年はこの辺で👋&lt;&#x2F;p&gt;
&lt;p&gt;良いお年をお迎えください！&lt;br&#x2F;&gt;
Have a happy new year!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>2025年1月から7月までの思い出プレイバック📕</title>
        <published>2025-07-17T00:00:00+00:00</published>
        <updated>2025-07-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/look-back-at-from-january-to-june-2025/"/>
        <id>https://masatakashiwagi.com/blog/look-back-at-from-january-to-june-2025/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/look-back-at-from-january-to-june-2025/">&lt;p&gt;久しぶりに今年の1月から7月までの家族との思い出プレイバックを残しておこうと思います．4月から保育園が始まったので，去年ほど毎月どこかに行くのは大変になってきました．あと後半は僕個人の転職活動やら退職準備などでバタバタしていました😅&lt;&#x2F;p&gt;
&lt;p&gt;ざっと時系列だと，こんな感じです．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;1月: 那須旅行 → 子供の体調不良により中止 → 7月にリベンジ&lt;&#x2F;li&gt;
&lt;li&gt;2月: ディズニーシー&lt;&#x2F;li&gt;
&lt;li&gt;3月: 大阪（実家帰省）&lt;&#x2F;li&gt;
&lt;li&gt;4月: 保育園入園・ワンパーク・こども広場Ｂのくに（群馬県）&lt;&#x2F;li&gt;
&lt;li&gt;7月: サンリオピューロランド・那須旅行&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;では，それぞれの月の出来事を振り返っていきます．&lt;&#x2F;p&gt;
&lt;p&gt;※ 最近つぶやきは X から Bluesky に移しているので，そちらのつぶやきを埋め込みしています．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zhen-rifan-ri-1yue-bian&quot;&gt;振り返り: 1月編&lt;&#x2F;h2&gt;
&lt;p&gt;1月は後半に那須旅行を計画していたのですが，相変わらずイベント前に体調が悪くなる娘の本領が発揮されて，熱のため旅行はキャンセルしました😭&lt;&#x2F;p&gt;
&lt;p&gt;7月編でも紹介しますが，今月無事に那須旅行のリベンジができました🙌&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zhen-rifan-ri-2yue-bian&quot;&gt;振り返り: 2月編&lt;&#x2F;h2&gt;
&lt;p&gt;2月は娘の誕生日にディズニーシーに行きました！今回初めてトイストーリーホテルに泊まりましたが，装飾が可愛かったり中に軽く遊べる場所があったりバイキングも美味しく，総じて楽しく過ごすことができました．&lt;&#x2F;p&gt;
&lt;p&gt;ホテル内には可愛らしいデフォルメされた壁画があり，思わず写真を撮っちゃいました．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025&#x2F;look_back_at_from_january_to_june_2025&#x2F;disney-img1.jpg&quot; alt=&quot;トイストーリーホテル&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;アトラクションは，&quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.tokyodisneyresort.jp&#x2F;tds&#x2F;attraction&#x2F;detail&#x2F;256&#x2F;&quot;&gt;ラプンツェルのランタンフェスティバル&lt;&#x2F;a&gt;&quot; には乗ることができました．小さな子供でも乗れるのは良かったですが，5分程度で一瞬で終わっちゃいました．あとは，アナ雪が大好きな娘が乗りたがっていた &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.tokyodisneyresort.jp&#x2F;tds&#x2F;attraction&#x2F;detail&#x2F;255&#x2F;&quot;&gt;アナとエルサのフローズンジャーニー&lt;&#x2F;a&gt;&quot; は残念ながら入場してすぐに当日分のチケットがなくなって乗れませんでした😭（次回はリベンジして見せてあげたいなと思います）&lt;&#x2F;p&gt;
&lt;p&gt;個人的に良かったのは，ご飯を食べながら見れる &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.tokyodisneyresort.jp&#x2F;tds&#x2F;show&#x2F;detail&#x2F;7601&#x2F;&quot;&gt;ダッフィー＆フレンズのワンダフル・フレンドシップ&lt;&#x2F;a&gt;&quot; のショーが，物語があるストーリーとミュージカルさでとても良くて，また行きたいと思わせて貰いました！&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;images&#x2F;2025&#x2F;look_back_at_from_january_to_june_2025&#x2F;disney-img2.jpg&quot; alt=&quot;属性&quot;&gt;
&lt;center&gt;&lt;figcaption&gt;魔法使いの弟子ミッキー&lt;&#x2F;figcaption&gt;&lt;&#x2F;center&gt;
&lt;p&gt;新設されたエリアの奥にあった魔法使いのミッキーのオブジェが良い感じだったので，その写真を載せておきます！&lt;&#x2F;p&gt;
&lt;p&gt;あとは，7月からの新イベントの開始に伴い終わってしまうジャンボリーミッキーのステージが最後にど真ん中の良い席で見れたのは幸運でした！家族みんな好きなので，残念です...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zhen-rifan-ri-3yue-bian&quot;&gt;振り返り: 3月編&lt;&#x2F;h2&gt;
&lt;p&gt;3月は半年に一度の大阪帰省で実家に帰ってました．今回はたまたま実家の近くでサーカスの公演がやっており，家族が誘ってくれたので，初めてサーカスを見に行ってきました！&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dreamcircus.jp&#x2F;&quot;&gt;ハッピードリームサーカス&lt;&#x2F;a&gt;という全国津々浦々と公演をしているみたいで，初めて見ましたが衝撃が半端なかったです．これは実際に見ないとわからないので，貴重な経験ができたかなと思います．他のサーカス，特に世界三大サーカスの木下大サーカスも見てみたいなと思っていたら，11月から来年2月まで立川でやるみたいなので，行ってみようかな...&lt;&#x2F;p&gt;
&lt;center&gt;&lt;blockquote class=&quot;bluesky-embed&quot; data-bluesky-uri=&quot;at:&#x2F;&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;app.bsky.feed.post&#x2F;3ll6qabejsc23&quot; data-bluesky-cid=&quot;bafyreidjhwhbkpe7poosq4jixapyypzrzc3cyrbfxebs4cgbndnmzfh5tq&quot; data-bluesky-embed-color-mode=&quot;system&quot;&gt;&lt;p lang=&quot;ja&quot;&gt;大阪帰省してた時に初めてサーカス🎪見に行ったけど、凄過ぎて久しぶりに感動体験した！&lt;br&gt;&lt;br&gt;&lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;post&#x2F;3ll6qabejsc23?ref_src=embed&quot;&gt;[image or embed]&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (&lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz?ref_src=embed&quot;&gt;@asteriam.bsky.social&lt;&#x2F;a&gt;) &lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;post&#x2F;3ll6qabejsc23?ref_src=embed&quot;&gt;Mar 25, 2025 at 16:20&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt;&lt;script async src=&quot;https:&#x2F;&#x2F;embed.bsky.app&#x2F;static&#x2F;embed.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;&lt;&#x2F;center&gt;
&lt;h2 id=&quot;zhen-rifan-ri-4yue-bian&quot;&gt;振り返り: 4月編&lt;&#x2F;h2&gt;
&lt;p&gt;去年に引き続き4月の GW 初めに群馬県にある &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;won-park.com&#x2F;&quot;&gt;ワンパーク・こども広場Ｂのくに&lt;&#x2F;a&gt;&quot; に行ってきました！相変わらずの広さで人もまばらで空いていてとても快適に子供と遊ぶことができました！そしてまたまた外観の写真を撮り忘れるという笑&lt;&#x2F;p&gt;
&lt;p&gt;まだまだ遊べそうな大きさと遊具があるので，来年もまた行こうかなと思います！ついでに佐野プレミアム・アウトレットにも寄りましたが，こちらは意外と全体的に大きくなく，フードコートは特に狭くて期待外れでした．&lt;&#x2F;p&gt;
&lt;p&gt;4月からは幼稚園が始まり，それまでと比べて毎月どこかに行くのが難しくなりそうな感じです！去年からプレ幼稚園に通っていて，そこで同じクラスだった友達とは違うクラスになってしまって残念がっていましたが，すぐに今では親友となっている友達を見つけて楽しく過ごしています！自分もその子のお父さんとパパ友になれて会った時には色々と会話させて貰ってます☺️&lt;&#x2F;p&gt;
&lt;p&gt;毎日幼稚園に通うようになってから風邪や体調を崩す日が明らかに増えました．GW も後半は風邪を引いたので，どこにも行けずでした😭&lt;&#x2F;p&gt;
&lt;p&gt;徐々に免疫力が付いて風邪に負けない身体になっていって欲しいものです（親も移されて風邪を引かないようにしないとです）．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zhen-rifan-ri-7yue-bian&quot;&gt;振り返り: 7月編&lt;&#x2F;h2&gt;
&lt;p&gt;5, 6月は家族の体調があまり良くなったりして特にどこかに遠出する機会はなかったです．この時期は僕個人も転職活動をしていたり，退職の準備をしたりでバタバタしていました．7月は退職の引き継ぎなどが落ち付いていたので，まず7月頭にサンリオピューロランドに初めて行ってきました！&lt;&#x2F;p&gt;
&lt;center&gt;&lt;blockquote class=&quot;bluesky-embed&quot; data-bluesky-uri=&quot;at:&#x2F;&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;app.bsky.feed.post&#x2F;3lsulpxvafs27&quot; data-bluesky-cid=&quot;bafyreict5zjfvoyiutwmzk4ka3bb2ltgn3xmngwizayn5bbfilt3rglu5m&quot; data-bluesky-embed-color-mode=&quot;system&quot;&gt;&lt;p lang=&quot;ja&quot;&gt;サンリオピューロランドに参戦してきます！&lt;br&gt;&lt;br&gt;&lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;post&#x2F;3lsulpxvafs27?ref_src=embed&quot;&gt;[image or embed]&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (&lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz?ref_src=embed&quot;&gt;@asteriam.bsky.social&lt;&#x2F;a&gt;) &lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;post&#x2F;3lsulpxvafs27?ref_src=embed&quot;&gt;Jul 1, 2025 at 10:54&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt;&lt;script async src=&quot;https:&#x2F;&#x2F;embed.bsky.app&#x2F;static&#x2F;embed.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;&lt;&#x2F;center&gt;
&lt;p&gt;娘が風邪気味だったので，パレード&#x2F;ショーを見たのとキティちゃんに会うだけでサクッと帰りました．パレード&#x2F;ショーは &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.puroland.jp&#x2F;parade-show&#x2F;miracle-gift-parade&#x2F;&quot;&gt;Miracle Gift Parade&lt;&#x2F;a&gt; というのを見ました．知恵の木というのが中央にあって，それをぐるぐるとキャラクター達がフロートに乗ったりして周りながら行われます．事前に席を購入していて，妻の推しのマイスウィートピアノが良く見える場所を確保していました．パレードはダンサーの数がかなり多くて，結構しっかりパフォーマンスがあってびっくりしました．演出や内容のストーリーも良くて心あたたまる感動のパレードでした！（個人的に推しのバッドばつ丸くんが登場しなかったのは残念でした笑）&lt;&#x2F;p&gt;
&lt;p&gt;そして最終出社日の翌週に1月に行けなかった那須旅行に行ってきました🚙&lt;&#x2F;p&gt;
&lt;p&gt;台風が来ていて生憎のお天気でしたが，久しぶりにゆっくり楽しく過ごせました！今回は&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;grand-mercure-nasuhighlands-resortandspa.jp&#x2F;&quot;&gt;グランドメルキュール那須高原&lt;&#x2F;a&gt;に泊まったのですが，google の口コミを見ていて微妙な感じのコメントが多くて戦々恐々としていました．が，全く問題なくてオールインクルーシブのバイキングなど大満足でした☺️&lt;&#x2F;p&gt;
&lt;p&gt;1日目は本当は近くの那須どうぶつ王国にも行きたいなと予定を立てていたのですが，雨だったのもあり昼ぐらいにホテル近くの&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.yuainomori.com&#x2F;&quot;&gt;道の駅那須高原友愛の森&lt;&#x2F;a&gt;に着く感じで車を運転して向かいました．お昼は奮発して那須和牛の御膳を頼んで脂身のあるステーキが絶品でした！その後は道の駅から5分ぐらいにある&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.okashinoshiro.co.jp&#x2F;&quot;&gt;お菓子の城 那須ハートランド&lt;&#x2F;a&gt;に行きました．ここでの目的はお菓子作り体験が出来るとのことで行ったのですが，お菓子作りは土日しかしておらずで残念ながら出来ませんでした．その代わりにサンキャッチャー作り体験は出来るとのことだったので，そちらを娘と一緒に作成しました．好きなパーツを幾つか選んでそれをワイヤーに通して作っていく感じです．可愛く出来て今はリビングのカーテンレールに吊るされてます笑&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025&#x2F;look_back_at_from_january_to_june_2025&#x2F;nasu-img1.jpg&quot; alt=&quot;那須ハートランド&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;良い感じに楽しめたので，ホテルに向かってチェックインしたり，少しエントランスでくつろいだりして，お風呂に入ってバイキングに向かいました🚶&lt;&#x2F;p&gt;
&lt;center&gt;&lt;blockquote class=&quot;bluesky-embed&quot; data-bluesky-uri=&quot;at:&#x2F;&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;app.bsky.feed.post&#x2F;3ltw2mdojuk2v&quot; data-bluesky-cid=&quot;bafyreiavcuk5t3j63kizecvymowasbif3zn3gyowq3ofhrw2chzuwemyvm&quot; data-bluesky-embed-color-mode=&quot;system&quot;&gt;&lt;p lang=&quot;ja&quot;&gt;バイキング始まった！&lt;br&gt;&lt;br&gt;&lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;post&#x2F;3ltw2mdojuk2v?ref_src=embed&quot;&gt;[image or embed]&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (&lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz?ref_src=embed&quot;&gt;@asteriam.bsky.social&lt;&#x2F;a&gt;) &lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;did:plc:dmpw32bjo7awxbiubfdesxrz&#x2F;post&#x2F;3ltw2mdojuk2v?ref_src=embed&quot;&gt;Jul 14, 2025 at 18:18&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt;&lt;script async src=&quot;https:&#x2F;&#x2F;embed.bsky.app&#x2F;static&#x2F;embed.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;&lt;&#x2F;center&gt;
&lt;p&gt;バイキングは種類豊富で海鮮やローストビーフなどなど色々とありました．ビールはクラフトビールで美味しかったです！お腹がパンパンになるぐらい食べて大満足して部屋に戻ったら爆睡してしまいました😄&lt;&#x2F;p&gt;
&lt;p&gt;翌日は朝食のバイキング（こちらも大満足の美味しさでした）を食べてチェックアウトして，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.teddynet.co.jp&#x2F;nasu&#x2F;&quot;&gt;那須テディベアミュージアム&lt;&#x2F;a&gt;に行って，ぬいぐるみ作り体験をして来ました！&lt;&#x2F;p&gt;
&lt;center&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025&#x2F;look_back_at_from_january_to_june_2025&#x2F;nasu-img2.jpg&quot; alt=&quot;属性&quot;&gt;&lt;&#x2F;center&gt;
&lt;p&gt;外にはトトロが出迎えてくれます！丁度雨も少し降っていたので，映画のバス停で待ってるシーンを思い出しました．ぬいぐるみ作りは前日に予約しました．体験の時間は15~20分ぐらいだったかなと思います．ぬいぐるみを選んで綿を中に機械で入れるところから出来ました！最後は飾りをつけたりして完成です（下の写真が完成したぬいぐるみです）．&lt;&#x2F;p&gt;
&lt;p&gt;作った後は隣のミュージアムを回って，併設されている喫茶店でお茶をしました（ここのシフォンケーキは絶品でした！）．丁度そのぐらいの時間で雨のピークが来て豪雨が凄まじかったので，少しマシになるまで待ってました．&lt;&#x2F;p&gt;
&lt;center&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025&#x2F;look_back_at_from_january_to_june_2025&#x2F;nasu-img3.jpg&quot; alt=&quot;属性&quot;&gt;&lt;&#x2F;center&gt;
&lt;p&gt;最後に佐野 SA でお昼ご飯を食べて，お土産を買ったりして夕方に家路に着きました．佐野 SA は上りと下りが階段で繋がっているので，行き来が可能になっています．さのまるのハイウェイスタンプがあったので，記念に押して帰りました！&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025&#x2F;look_back_at_from_january_to_june_2025&#x2F;nasu-img4.jpg&quot; alt=&quot;さのまる&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;1月から7月までの思い出をつらつらと書きましたが，実は途中で何回か子供の体調不良で旅行やイベントがキャンセルになったりしました😭（イベントが近づくと体調が悪くなるという運の悪さ）&lt;&#x2F;p&gt;
&lt;p&gt;7月の旅行は雨でしたが，久しぶりに遠出の旅行が出来て良かったです．2025年の後半戦も記念に残る1ヶ月を積み上げて行きたいと思います！8月は花火をしたりプール or 海に行けると良いかな？行きたい旅行先はいっぱいあるので，隙を見て計画を家族 &amp;amp; Claude と立てたいと思います！😎&lt;&#x2F;p&gt;
&lt;p&gt;ただ8月は新しい職場ということもあり，様子を見つつという感じかなと...&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Prompt Cache について理解を深める</title>
        <published>2025-07-06T00:00:00+00:00</published>
        <updated>2025-07-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/learning-prompt-cache/"/>
        <id>https://masatakashiwagi.com/blog/learning-prompt-cache/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/learning-prompt-cache/">&lt;p&gt;ふと MLSys の Proceedings を眺めていたら，&lt;strong&gt;Prompt Cache&lt;&#x2F;strong&gt; の論文（Prompt Cache: Modular Attention Reuse for Low-Latency Inference）を見つけたので，仕組みを知りたくて読んでみました．今回はそれの備忘録になります．この論文での Prompt Cache の機構は，LLM プロバイダーが提供する Prompt caching の仕組みとはドキュメントを見たところ違うものでした．こちらは実用性を重視した機能で，Cache Hits によるプロンプト内でのプレフィックスの一致でキャッシュする方法になります．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;lun-wen-deti-an-sareta-prompt-cache-noshi-zu-miwojian-teiku&quot;&gt;論文で提案された Prompt Cache の仕組みを見ていく&lt;&#x2F;h2&gt;
&lt;p&gt;特定のタスクを LLM に解かせる際にプロンプトをチューニングしますが，システムプロンプトや指示などの前提となるコンテキストはリクエスト毎に変わらずに使用されることが多いと思います．また，プロンプトはプロンプトエンジニアリングによって再利用可能な形でテンプレート化されることも多く，プロンプト間で重複する部分も多いです．このような背景から，Prompt Cache は異なる複数のプロンプト間でアテンション状態（Key-Value pairs）の再利用を可能にすることで，Time-To-First-Token (TTFT) のレイテンシを大幅に削減することを実現する技術です．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ji-cun-noji-suan-kosutoxue-jian-fang-fa-dearu-key-value-cache-tonobi-jiao&quot;&gt;既存の計算コスト削減方法である Key-Value Cache との比較&lt;&#x2F;h3&gt;
&lt;p&gt;Transformer では，各トークンを生成する際に全ての過去のトークンとのアテンション状態を再計算する必要がありますが，これは非常に計算コストがかかり非効率です．KV Cache では，入力に対して最初にアテンション状態を一度計算することで，以降はそれを再利用します（過去に生成されたトークンのキーとバリューを保存しておいて，新しいトークンを生成する際にこれらを再利用する）．これは prefill phase と呼ばれます．計算量は現在のシーケンス長を &lt;em&gt;n&lt;&#x2F;em&gt;，隠れ層の次元数を &lt;em&gt;d&lt;&#x2F;em&gt; とすると，過去のトークンとのアテンション計算が &lt;em&gt;O(nd)&lt;&#x2F;em&gt; なので，n 個のトークンを生成する場合，&lt;em&gt;O(n × nd) = O(n²d)&lt;&#x2F;em&gt; となります．1ステップで考えると，過去のキーとバリューをキャッシュしておき，次のステップでは新しいクエリに対してだけ計算すればいいので，&lt;em&gt;O(nd)&lt;&#x2F;em&gt; になります．つまり，1ステップあたりは線形にしか増えません．&lt;&#x2F;p&gt;
&lt;p&gt;ここまでは，KV Cache の話ですが，&lt;strong&gt;Prompt Cache はアテンション状態の再利用を単一プロンプトから複数プロンプトへと拡張したもの&lt;&#x2F;strong&gt;になります．計算結果をメモリ上に保存しておくことで，再計算せずにメモリから取り出して使用します．下図は，Prompt Cache がプロンプトアテンションの計算をバイパスすることで，異なるプロンプト間での再利用を実現する仕組みを表現しています．&lt;&#x2F;p&gt;
&lt;center&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025&#x2F;learning_prompt_cache&#x2F;prompt-cache-img1.png&quot; alt=&quot;属性&quot;&gt;&lt;&#x2F;center&gt;
&lt;center&gt;&lt;figcaption&gt;トークン生成方法の比較&lt;&#x2F;figcaption&gt;&lt;&#x2F;center&gt;
&lt;h3 id=&quot;donoyounisitefu-shu-puronputojian-deatensiyonzhuang-tai-wozai-li-yong-suruka&quot;&gt;どのようにして複数プロンプト間でアテンション状態を再利用するか？&lt;&#x2F;h3&gt;
&lt;p&gt;Transformer のアテンション状態は位置エンコーディングによって位置依存性を持ちます．KV Cache を用いて単一のプロンプトを扱う場合は，同じプロンプトコンテキストがすべてのステップにおいて同じ位置に配置されることから問題になりません．一方で，複数のプロンプト間で共有されるテキストセグメント（テキストの集合&#x2F;塊）はプロンプト間で異なる位置・状態に現れる可能性があるため，以下の2つの問題に対応する必要性を挙げています．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;テキストセグメントが異なるプロンプトにおいて異なる位置に現れる場合でも再利用可能にする&lt;&#x2F;li&gt;
&lt;li&gt;新しいプロンプトを受け取った際に，アテンション状態がキャッシュされている可能性のあるテキストセグメントを効率的に認識する&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;これらの問題を解決するために，この論文では2つのアイデアを組み合わせた提案をしています．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Prompt Markup Language (PML) の導入によるプロンプトの構造を明示的に記述する&lt;&#x2F;li&gt;
&lt;li&gt;LLM が不連続な位置 ID を持つアテンション状態を処理する（経験則的に可能である）&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;PML は再利用可能なテキストセグメントをスキーマに落とし込みます．ここでのスキーマは，プロンプトモジュールを定義することと，それらの相対位置と階層を記述します．これにより各プロンプトモジュールに固有の位置 ID が割り当てられます．&lt;&#x2F;p&gt;
&lt;p&gt;各スキーマは一意の識別子を持ち，プロンプトモジュールは &amp;lt;module&amp;gt; タグで指定し，プロンプトは &amp;lt;prompt&amp;gt; タグを使用してスキーマから構築されます．このタグは，schema 属性で利用するスキーマを指定して，インポートするプロンプトモジュールを用意します．&lt;&#x2F;p&gt;
&lt;center&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025&#x2F;learning_prompt_cache&#x2F;prompt-cache-img2.png&quot; alt=&quot;属性&quot;&gt;&lt;&#x2F;center&gt;
&lt;center&gt;&lt;figcaption&gt;Prompt Cache の再利用のメカニズム&lt;&#x2F;figcaption&gt;&lt;&#x2F;center&gt;
&lt;p&gt;例えば，論文図2のスキーマから miami モジュールをインポートするには，&amp;lt;miami&#x2F;&amp;gt; と記述します．Prompt Cache は，スキーマで指定されていないテキスト（例: 図2の &quot;Highlight the surf spots&quot;）のアテンション状態のみを計算して，インポートされたモジュール（例: trip-plan, miami）のアテンション状態を再利用することでレイテンシを削減しています．他に PML では，プロンプトモジュールのパラメータ化を可能にすることで，再利用性を高めています．&lt;&#x2F;p&gt;
&lt;p&gt;プロンプトモジュールのアテンション状態が必要になったタイミングで，それらは計算されてメモリに保存されます（スキーマのエンコーディング）．手続きとしては，Prompt Cache はスキーマからプロンプトモジュールのトークン系列を抽出して，各トークンに位置 ID を割り当てます．プロンプトモジュールのトークン系列と対応する位置 ID は，その後 LLM に渡されて，アテンション状態が計算されます．パラメータに関しては，所定数の &amp;lt;unk&amp;gt; トークン（未知のトークン）で置き換えられます．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tui-lun-purosesu&quot;&gt;推論プロセス&lt;&#x2F;h3&gt;
&lt;p&gt;論文図2に示されているように，Prompt Cache は以下のステップを実行します．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;キャッシュからのアテンション状態の取得: インポートされたプロンプトモジュールの事前計算済みアテンション状態をキャッシュから取得する（ステップ2）&lt;&#x2F;li&gt;
&lt;li&gt;新しいテキストの計算: キャッシュされていない新しいテキストセグメント（ステップ3と4）のアテンション状態を計算する&lt;&#x2F;li&gt;
&lt;li&gt;アテンション状態の連結: 1, 2 に加えて，計算済みのパラメータのアテンション状態を連結して，プロンプト全体のアテンション状態を生成する（ステップ5）&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;これにより，従来の prefill phase が置き換えられます．大部分のアテンション状態は事前計算済みで，新しく計算が必要なのはパラメータ値と新しいテキストのみになります．この仕組みによって，同じスキーマから派生した他のプロンプトでも同じキャッシュを再利用可能にしたり，長いプロンプトでも大部分の計算を省略できて，高速化が実現されるようになります．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;prompt-cache-noxing-neng-toping-jia-jie-guo&quot;&gt;Prompt Cache の性能と評価結果&lt;&#x2F;h3&gt;
&lt;p&gt;論文では，以下の評価観点が挙げられています．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Prompt Cache が最初のトークン生成までの時間（TTFT）のレイテンシと出力品質に与える影響&lt;&#x2F;li&gt;
&lt;li&gt;メモリストレージのオーバーヘッド&lt;&#x2F;li&gt;
&lt;li&gt;Prompt Cache が適しているアプリケーション（今回は触れず...）&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;ベースラインには，通常の KV Cache を使用しています．また，評価のために用意した環境とデータセットは，以下の通りになっています．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;CPU 構成: Intel i9-13900K (128 GB DDR5 RAM), AMD Ryzen 9 7950X (128 GB DDR4 RAM)&lt;&#x2F;li&gt;
&lt;li&gt;GPU 構成: NVIDIA RTX 4090 (Intel i9-13900K とペア), NVIDIA A40、NVIDIA A100 (NCSA Delta 上の仮想ノード)&lt;&#x2F;li&gt;
&lt;li&gt;LLM: Llama2, CodeLlama, MPT, Falcon などの OSS LLM を使用&lt;&#x2F;li&gt;
&lt;li&gt;データセット: LongBench (4K から 10K のコンテキスト長を持つ，6つのカテゴリ（多文書質疑応答・要約・コード補完など）にわたる21のデータセットからの厳選されたサンプル)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;center&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025&#x2F;learning_prompt_cache&#x2F;eval-results-img1.png&quot; alt=&quot;属性&quot;&gt;&lt;&#x2F;center&gt;
&lt;center&gt;&lt;figcaption&gt;GPU を利用した推論時のレイテンシー（図3）とCPU を利用した推論時のレイテンシー（図4）&lt;&#x2F;figcaption&gt;&lt;&#x2F;center&gt;
&lt;p&gt;図3では，プロンプトモジュールを CPU メモリに保存した場合，TTFT レイテンシは1.5~3倍に削減され，GPU メモリに保存した場合は，5倍~10倍に削減されています．図4では，Intel CPU で最大70倍，AMD CPU では最大20倍のレイテンシ削減を実現しています．CPU でのアテンション計算のレイテンシーが GPU よりはるかに大きいため，CPU 推論は GPU 推論よりも Prompt Cache からより大きな恩恵を受けています．&lt;&#x2F;p&gt;
&lt;center&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025&#x2F;learning_prompt_cache&#x2F;eval-results-img2.png&quot; alt=&quot;属性&quot;&gt;&lt;&#x2F;center&gt;
&lt;center&gt;&lt;figcaption&gt;ベンチマークデータでの精度結果（表1）&lt;&#x2F;figcaption&gt;&lt;&#x2F;center&gt;
&lt;p&gt;表1を見ると，精度面においても Prompt Cache による出力はベースラインと比較して同等の精度維持していることがわかります．&lt;&#x2F;p&gt;
&lt;p&gt;論文では，レイテンシー改善をどう理解するかが述べられています．KV Cache のレイテンシーがシーケンス長とともに二次的に増加する（セルフアテンションの計算）のに対して，Prompt Cache のメモリコピーのコストは線形に増加することが示されています．モデルサイズの影響に関しても，モデルのパラメータサイズが大きくなるにつれて，KV Cache の計算オーバーヘッドも増加します．例えば，7B モデルから13B モデルにし，3K トークン長を与えた場合，KV Cache では220ms のレイテンシーが追加されるのに対して，Prompt Cache では30ms しか追加されていません．&lt;&#x2F;p&gt;
&lt;center&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025&#x2F;learning_prompt_cache&#x2F;eval-results-img3.png&quot; alt=&quot;属性&quot;&gt;&lt;&#x2F;center&gt;
&lt;center&gt;&lt;figcaption&gt;キャッシュによるアドバンテージ（図5）とメモリオーバーヘッドの比較（表2）&lt;&#x2F;figcaption&gt;&lt;&#x2F;center&gt;
&lt;p&gt;Prompt Cache を行うためには，メモリ上に留めておく必要があるわけですが，表2の値を参考にすると，メモリとしては CPU しか現状は難しそうですね．&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left&quot;&gt;1K tokens の docs をキャッシュする場合&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;モデル&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;メモリ使用量&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Llama 7B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;500MB&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Llama 70B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;2.5GB&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left&quot;&gt;100docs (1K tokens) キャッシュする場合&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;モデル&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;メモリ使用量&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Llama 7B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;50GB&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Llama 70B&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;250GB&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;というわけで，Prompt Cache に関する論文を紹介しましたが，複数のプロンプト間でアテンション状態をキャッシュして再利用するという非常に興味深い技術だなと思いました．LLM を活用したレイテンシーに敏感なアプリケーション，リアルタイム応答だったりの推論を考えた場合に，こういった仕組みは必要になってくるだろうなと思います．PML を構築する部分は少々厄介かなと思いつつ，この辺のキャッシュ機構については面白いトピックだと思うので，他の論文とかも眺めたいなと思いました．&lt;&#x2F;p&gt;
&lt;p&gt;後半は LLM サービスプロバイダーでの実用的なキャッシュの仕組みを紹介します．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;llm-sabisupurobaidadeno-prompt-caching-noshi-zu-mi&quot;&gt;LLM サービスプロバイダーでの Prompt caching の仕組み&lt;&#x2F;h2&gt;
&lt;p&gt;OpenAI と Anthropic で提供されている仕組みについてメインで紹介します．他に，Google (Gemini) や Microsoft がありますが，基本的な仕組みは他のサービスプロバイダーと同じです．Implicit caching な仕組みと Explicit caching な仕組みがあり，Explicit の方は Time to Live (TTL) が設定できたりでトークンサイズに合わせてコストがかかる仕様になっています．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;openai-no-prompt-caching-noshi-zu-mi&quot;&gt;OpenAI の Prompt caching の仕組み&lt;&#x2F;h3&gt;
&lt;p&gt;OpenAI では，Cache Hit という仕組みによってシステムにデータをキャッシュしておくことで，レイテンシーやコストが削減される機能があり，それが Prompt caching になります．この機能はコード変更不要で自動的に有効になります．&lt;&#x2F;p&gt;
&lt;p&gt;下図は OpenAI のガイドから拝借していますが，この図の通りでプロンプト内でプレフィックスが完全に一致する場合にのみ Cache Hit が効く仕組みです．&lt;&#x2F;p&gt;
&lt;center&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025&#x2F;learning_prompt_cache&#x2F;context-caching.png&quot; alt=&quot;属性&quot;&gt;&lt;&#x2F;center&gt;
&lt;center&gt;&lt;figcaption&gt;Structuring prompts from OpenAI - Prompt caching&lt;&#x2F;figcaption&gt;&lt;&#x2F;center&gt;
&lt;p&gt;このガイドではもう少し詳しくどのように動作するか説明があります．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Cache Routing
&lt;ul&gt;
&lt;li&gt;リクエストされると，プロンプトのプレフィックスのハッシュ値（最初の 256 トークンが使用される）に基づいてルーティングされる．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Cache Lookup
&lt;ul&gt;
&lt;li&gt;ルーティングされた結果が，キャッシュに存在するかどうかを確認する．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Cache Hit
&lt;ul&gt;
&lt;li&gt;一致するプレフィックスが見つかった場合は，システムはキャッシュされた結果を利用する．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Cache Miss
&lt;ul&gt;
&lt;li&gt;一致するプレフィックスが見つからない場合は，システムはプロンプト全体を処理した後，そのプレフィックスをキャッシュして，将来のリクエストに備える．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;キャッシュは1024トークン以上のプロンプトで利用可能で，これ以下の場合は機能しない仕様となっているそうです．また，追加で128トークンずつキャッシュヒットが発生する仕組みです．キャッシュ対象は，&lt;strong&gt;Messages, Images, Tool use, Structured outputs&lt;&#x2F;strong&gt; になります．&lt;&#x2F;p&gt;
&lt;p&gt;あとはプラクティスとして，キャッシュのメリットを効果的に享受するためには，&lt;strong&gt;システムプロンプトや指示，例などの静的コンテンツをプロンプトの前半に配置して，リクエストによって可変になる情報はプロンプトの後半に配置する&lt;&#x2F;strong&gt;というのが書かれていました．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;anthropic-claude-no-prompt-caching-noshi-zu-mi&quot;&gt;Anthropic (Claude) の Prompt caching の仕組み&lt;&#x2F;h3&gt;
&lt;p&gt;Claude の Prompt caching の仕組みは，Explicit caching な仕組みで，&lt;code&gt;cache_control&lt;&#x2F;code&gt; パラメータを使用してキャッシュしたい部分を指定する必要があります．&lt;&#x2F;p&gt;
&lt;p&gt;この設定を有効にしてリクエストを送ると，&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;システムは指定されたキャッシュブレイクポイントまでのプレフィックス一致が，直近のクエリから既にキャッシュされているかを確認する&lt;&#x2F;li&gt;
&lt;li&gt;キャッシュされている場合は，キャッシュされたバージョンを使用する&lt;&#x2F;li&gt;
&lt;li&gt;キャッシュされていない場合は，プロンプト全体を処理して，レスポンスが開始されるとプレフィックスをキャッシュする&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;デフォルトでは，キャッシュの TTL は5分間になっています．対応するモデルやコストは公式ドキュメントを確認して下さい．&lt;&#x2F;p&gt;
&lt;p&gt;下記のサンプルコード（公式ドキュメントにある）では，ユーザーインストラクション部分はキャッシュせず，ロングコンテキストであるシステムプロンプトの50ページほどある法的契約の全文をプレフィックスとしてキャッシュしています．&lt;code&gt;&quot;cache_control&quot;: {&quot;type&quot;: &quot;ephemeral&quot;}&lt;&#x2F;code&gt; のパラメータがキャッシュの設定を明示的に行う部分になっています．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; anthropic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;client&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; anthropic.Anthropic()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; client.messages.create(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;    model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;claude-opus-4-20250514&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;    max_tokens&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;1024&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;    system&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;text&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;text&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;You are an AI assistant tasked with analyzing legal documents.&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;text&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;text&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Here is the full text of a complex legal agreement: [Insert full text of a 50-page legal agreement here]&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;cache_control&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;ephemeral&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;  # キャッシュの設定を明示的に行う&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;    messages&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;role&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;user&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;content&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;What are the key terms and conditions in this agreement?&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(response.model_dump_json())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;キャッシュ対象は，&lt;strong&gt;Tools, System messages, Text messages, Images &#x2F; Documents, Tool use と tool results&lt;&#x2F;strong&gt; になります．一方でキャッシュ対象外も定義されていて，&lt;strong&gt;Thinking blocks, 引用などのサブコンテンツブロック, 空のテキストブロック&lt;&#x2F;strong&gt; が対象外になっています．&lt;&#x2F;p&gt;
&lt;p&gt;プラクティスとして，OpenAI との違いを見ると，Claude では&lt;strong&gt;最大4つのキャッシュブレイクポイントを定義できるため，異なる再利用可能なセクションを独立してキャッシュする&lt;&#x2F;strong&gt;ことができます．これを有効に利用することを勧めています．&lt;&#x2F;p&gt;
&lt;p&gt;他には，TTL が1時間のキャッシュも用意されているので，5分のキャッシュと組み合わせた Mixing different TTLs によるより効果的に最適化する例も紹介されています．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は Prompt Cache の論文と LLM サービスプロバイダーでの Prompt caching の仕組みについて少し調べてみたので，整理してみました．他にも関連するトピックの論文がいくつかあるので，また読んだら整理していきたいと思います．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;proceedings.mlsys.org&#x2F;paper_files&#x2F;paper&#x2F;2024&#x2F;hash&#x2F;a66caa1703fe34705a4368c3014c1966-Abstract-Conference.html&quot;&gt;Prompt Cache: Modular Attention Reuse for Low-Latency Inference&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;platform.openai.com&#x2F;docs&#x2F;guides&#x2F;prompt-caching&quot;&gt;OpenAI - Prompt caching&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.anthropic.com&#x2F;en&#x2F;docs&#x2F;build-with-claude&#x2F;prompt-caching&quot;&gt;Anthropic - Prompt caching&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ai.google.dev&#x2F;gemini-api&#x2F;docs&#x2F;caching&quot;&gt;Gemini API - Context caching&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;ja-jp&#x2F;azure&#x2F;ai-foundry&#x2F;openai&#x2F;how-to&#x2F;prompt-caching&quot;&gt;Microsoft - Prompt caching&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>「Azure Machine Learning ではじめる機械学習 &#x2F; LLM 活用入門」を読んでの書評</title>
        <published>2025-06-20T00:00:00+00:00</published>
        <updated>2025-06-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/review-azure-ml-llm-book/"/>
        <id>https://masatakashiwagi.com/blog/review-azure-ml-llm-book/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/review-azure-ml-llm-book/">&lt;p&gt;遅ればせながら，2025年4月7日に発売された「&lt;strong&gt;Azure Machine Learning ではじめる機械学習 &#x2F; LLM 活用入門&lt;&#x2F;strong&gt;」を著者の一人である立脇さんから献本頂いたので，書評を書いていきます！&lt;&#x2F;p&gt;
&lt;div class=&quot;iframely-embed&quot;&gt;&lt;div class=&quot;iframely-responsive&quot; style=&quot;height: 140px; padding-bottom: 0;&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;gihyo.jp&#x2F;book&#x2F;2025&#x2F;978-4-297-14846-1&quot; data-iframely-url=&quot;&#x2F;&#x2F;iframely.net&#x2F;4Unf4kCx?card=small&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;div&gt;&lt;&#x2F;div&gt;&lt;script async src=&quot;&#x2F;&#x2F;iframely.net&#x2F;embed.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;改めて，出版おめでとうございます🎉&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet tw-align-center&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;Azure Machine Learningではじめる機械学習&#x2F;LLM活用入門を著者の立脇さんから献本頂きました🎉&lt;br&gt;Azureでの機械学習実践の書籍は今までなかったと思うので、楽しく読ませて頂きます！後ほど書評ブログも書こうと思います。 &lt;a href=&quot;https:&#x2F;&#x2F;t.co&#x2F;VQae8ekOGW&quot;&gt;pic.twitter.com&#x2F;VQae8ekOGW&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (@asteriam_fp) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asteriam_fp&#x2F;status&#x2F;1905940701885395390?ref_src=twsrc%5Etfw&quot;&gt;March 29, 2025&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;h2 id=&quot;shu-ji-nomu-ci&quot;&gt;書籍の目次&lt;&#x2F;h2&gt;
&lt;p&gt;目次は以下のように全体は4部構成（+付録）になっています．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;第1部: Azure Machine Learning の基本
&lt;ul&gt;
&lt;li&gt;第1章: 機械学習をビジネスに活かすには&lt;&#x2F;li&gt;
&lt;li&gt;第2章: Azure Machine Learning の概要&lt;&#x2F;li&gt;
&lt;li&gt;第3章: Azure Machine Learning のセットアップ&lt;&#x2F;li&gt;
&lt;li&gt;第4章: AutoML の概要と実践&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;第2部: 機械学習モデルの構築と活用
&lt;ul&gt;
&lt;li&gt;第5章: スクラッチでのモデル開発&lt;&#x2F;li&gt;
&lt;li&gt;第6章: MLflow による実験管理とモデル管理&lt;&#x2F;li&gt;
&lt;li&gt;第7章: 機械学習パイプライン&lt;&#x2F;li&gt;
&lt;li&gt;第8章: モデルのデプロイ&lt;&#x2F;li&gt;
&lt;li&gt;第9章: MLOps の概要と実践&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;第3部: 大規模言語モデルの活用
&lt;ul&gt;
&lt;li&gt;第10章: 大規模言語モデルの概要&lt;&#x2F;li&gt;
&lt;li&gt;第11章: 基盤モデルとモデルカタログ&lt;&#x2F;li&gt;
&lt;li&gt;第12章: プロンプトフローの活用&lt;&#x2F;li&gt;
&lt;li&gt;第13章: LLMOpsへの招待&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;付録
&lt;ul&gt;
&lt;li&gt;付録 A: クライアント環境のセットアップ&lt;&#x2F;li&gt;
&lt;li&gt;付録 B: Azure Machine Learning とデータ&lt;&#x2F;li&gt;
&lt;li&gt;付録 C: MLflow Modelsによるノーコードコンテナビルドとデプロイ&lt;&#x2F;li&gt;
&lt;li&gt;付録 D: 責任あるAIツールボックス&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;nei-rong-noshao-jie-togan-xiang&quot;&gt;内容の紹介と感想&lt;&#x2F;h2&gt;
&lt;p&gt;各章で個人的に興味深かった点や印象に残った点を紹介していきます．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;di-1bu-azure-machine-learning-noji-ben&quot;&gt;第1部: Azure Machine Learning の基本&lt;&#x2F;h3&gt;
&lt;p&gt;最初に機械学習をビジネスに適用する上でのプロセスの全体像が語られています．機械学習の適用を一度でも経験したことがある人なら目にしたことがある内容ですが，改めてコンパクトにまとめられて良きです．この辺りの理解は &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2003.05155&quot;&gt;CRISP-ML(Q)&lt;&#x2F;a&gt;&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; を眺めておくとより理解が深められると思います．参考になる資料として「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;speakerdeck.com&#x2F;isidaitc&#x2F;clisp-ml-q-wohazimetositamlsisutemufalsepin-zhi-que-bao-niguan-surudiao-cha?slide=48&quot;&gt;CLISP-ML(Q)をはじめとしたMLシステムの品質確保に関する調査&lt;&#x2F;a&gt;」を挙げておきます．&lt;&#x2F;p&gt;
&lt;p&gt;本書では，機械学習の取り組みは試行錯誤と改善を繰り返すループプロセスという説明がされていて，非常に好感が持てました．機械学習の適用は当初考えてもいなかったことが発生しうるため，Continuous X (X=Integration, Delivery, Training, Monitoring) が必要不可欠だと考えていますが，これらを効率的に行う上で，Azure Machine Learning のようなクラウドサービス・プラットフォームを活用して取り組んでいくことを推奨しています．&lt;&#x2F;p&gt;
&lt;p&gt;第1部 - 第2章以降では，Azure Machine Learning のセットアップやそれぞれのサービスや機能説明を詳細にされています．第4章では，AutoML について触れられていますが，以前一時期流行っていた AutoML 系は最近あまり聞かなくなったかなと思い，実際どれぐらい使われているのか気になりました（書籍の一部を割いているということは，今でも一定の利用ニーズはあるのかなとも思いつつ...）．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;di-2bu-ji-jie-xue-xi-moderunogou-zhu-tohuo-yong&quot;&gt;第2部: 機械学習モデルの構築と活用&lt;&#x2F;h3&gt;
&lt;p&gt;6章では，MLflow による実験管理の方法が丁寧に書かれていて，内部的なコンポーネントの役割などツールに対する理解が深まると思います．あまり実験管理のライブラリの使い方にページ数を割いている書籍は見ないので，細かく確認出来て MLflow に対する理解が進むと同時に，Azure Machine Learning との関係性についてもしっかり書かれているの連携のイメージがしやすく感じます．&lt;&#x2F;p&gt;
&lt;p&gt;続く7章は，機械学習パイプラインの話が書かれていて，個人的に機械学習パイプラインの構築は関心があるトピックなので，興味深く読ませて貰いました．パイプラインにおけるコンポーネントの設計の話に触れられていて，考え方は頭に入れておきたいです．コンポーネントの細かい分割は，ジョブ実行時のオーバーヘッドになり得る話が書かれていて，最近 Vertex AI Pipelines だと &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cloud.google.com&#x2F;vertex-ai&#x2F;docs&#x2F;pipelines&#x2F;persistent-resources&quot;&gt;Persistent Resource&lt;&#x2F;a&gt;&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; という機能が実装されていて，クラスタとしての役割を持って起動までにかかるオーバーヘッドを少なくできたりもします．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;少し余談ですが，例えば，1日1回のバッチ実行をするパイプラインでは，オーバーヘッドをそこまで気にしなくてもいいのでは？とも思います．適度にモジュラー構造を持って責務が分けられたコンポーネントになっていれば，バッチパイプラインではそれなりの時間がかかることが普通なので，コンテナの立ち上げ時にかかる時間オーバーヘッドは多少許容できるかなと（オーバーヘッドは少ないに越したことはないのは前提の上での話）．&lt;&#x2F;p&gt;
&lt;p&gt;時間を気にするユースケース例えば，高速な推論処理を推論パイプラインで行ったり，ストリーミング的なデータを処理するパイプラインでリアルタイムライクなケースでは，クラスタなどを用意するか，常時コンテナを立ち上げた状態で処理しないとそもそも間に合わないので，それはまた別のお話かなと感じました．とはいえ，このような非機能要件にも目を向けて書かれたいる書籍はあまり見かけないので，素晴らしいと思います．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;後半は，パイプラインのジョブ実行というハンズオンの内容が書かれていて，概要とイメージ図がセットになっていて，一連の処理を Azure Machine Learning 上で動かすガイドがしっかり書かれていて，動かせるイメージを持てました．&lt;&#x2F;p&gt;
&lt;p&gt;他には，8章のモデルデプロイの内容で，dev 用のローカルエンドポイントが用意されていたり，Azure Machine Learning ではローカルでのテストや動作確認などを簡単にできる仕組みが用意されていて，感心しました．マネージドサービスを使っていて難しいポイントは，ローカルでの動作確認や再現実行が比較的容易ではないので，苦労することが多いです．モデルのデプロイ方式（オンラインエンドポイント・バッチエンドポイント）の紹介もされていて，意外と他のクラウドサービスでもきちんと説明があるものは少ない印象なので，説明されていてありがたいと感じます．&lt;&#x2F;p&gt;
&lt;p&gt;また，9章では MLOps 成熟度の話やリファレンスアーキテクチャの参照を用意してくれていたり，より発展して学ぶことができそうでした．Azure Machine Learning の MLOps 機能で気になったものは，エンタープライズ利用を考慮したレジストリ機能は良さそうに思います．本番環境は，アクセス制御等の関係から開発環境と分離したいケース，課金請求やコスト管理を環境毎で行いたいケースなどでワークスペースを分けた利用というのはよくあることです．一方でワークスペース間でリソースシェアをしたいニーズもあり，それを実現するワークスペース間でのリソースシェアができる Hub としての役割でレジストリ機能が使えるということみたいです（詳しくは本書をご確認ください）．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;di-3bu-da-gui-mo-yan-yu-moderunohuo-yong&quot;&gt;第3部: 大規模言語モデルの活用&lt;&#x2F;h3&gt;
&lt;p&gt;基盤モデルの推論環境へのデプロイとして，サーバーレス API が用意されていて，対応したモデルを色々と使えるのは魅力的です．API への入出力のトークン数に応じた課金で使えるとのことです．ただ，対応するリージョンが日本に用意されているのかは気になりました．自前で用意したデータセットを用いたファインチューニングの方法もページ数を割いて紹介されています．&lt;&#x2F;p&gt;
&lt;p&gt;「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gihyo.jp&#x2F;book&#x2F;2024&#x2F;978-4-297-13929-2&quot;&gt;Azure OpenAI Service ではじめる ChatGPT&#x2F;LLM システム構築入門&lt;&#x2F;a&gt;」という書籍でも紹介されていて，以前僕も書評させて貰った&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masatakashiwagi.com&#x2F;blog&#x2F;review-azure-openai-service-book&#x2F;&quot;&gt;「Azure OpenAI Service ではじめる ChatGPT&#x2F;LLM システム構築入門」を読んでの書評&lt;&#x2F;a&gt;でも触れたプロンプトフローを使った効率的な LLM ワークフローの開発についても12章で触れられています．個人的にプロンプトフローの機能だけでもかなり価値があると思っていて，開発のイテレーションを標準化したり再現性を持って進められるツールで活用する価値が高いです！（Azure 使うなら絶対使いたい）&lt;&#x2F;p&gt;
&lt;p&gt;最後の13章では，LLMOps について紹介されています．MLOps との比較・違いもされていて，MLOps をやってきた人にとってマッピングしやすい内容になっています．LLMOps のプロセス&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;についてはまだまだプラクティスが確立されていない面も多いかなと思うので，本書の例は1つ参考にできそうです！&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;ここからは少し僕の見解ですが，LLM 活用としては「評価」と「監視（モニタリング・オブザーバビリティ）」が今まで以上に大事になってきています．評価で言うと，LLM の評価の難しさは，異なるタスクにおける能力のばらつき，プロンプトの変更に敏感でそれによる性能の変化が容易に起こりうる，自然言語のメトリクスでの評価（同じ文章でもドメイン固有で使われ方や意味も異なりうる），といった困難さがあります（他にも，モデルのアップデートによる回答の一貫性の欠如やハルシネーションなど色々とあります）．コントローラブルでない要素も多分にありますが，ゴールデンデータセットを用意する，LLM-as-a-judge&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; によるスコアリング評価など少しずつでも良いので，評価を行いながら評価自体の改善が必要になってきます．&lt;&#x2F;p&gt;
&lt;p&gt;もう1つの「監視（モニタリング・オブザーバビリティ）」ですが，LLM による生成はどうしても時間がかかるため，応答時間やレイテンシーは UX に直結してしまいます．複数の処理が入った時にどこがボトルネックになっているかを把握しておく必要があります．継続的な改善を行うためにも，ユーザーの実際の使用パターン，生成が上手くいかない失敗ケース，フィードバックなどのデータを収集して，プロンプトチューニングなどに活かすことが大事になってきます．他には，OpenAI や Anthropic が提供する API を使うケースが多いと思いますが，エラー率・トークン消費量・コスト&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#5&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;などを把握しておかないとシステム面の安定性が見込めないかもしれません．&lt;&#x2F;p&gt;
&lt;p&gt;こういったことをクラウドベンダーが提供するマネージドサービスを使ったり，LangSmith, Langfuse といったサードパーティのツールを使って LLM 活用の day one から取り掛かるのが良さそうです．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;全体を通して，一般的な機械学習の適用や活用に対する説明がありつつ，Azure Machine Learning 上で実用的に行うための設定方法や動かし方を図解でわかりやすく説明されています．図表が豊富で押さえておくポイントが整理されていて理解しやすかったです．特にコラムは説明の補足だけでなく，発展的な内容にも触れられているので読んでいて楽しかった！付録もデータ基盤周りの話が興味深い内容でした．&lt;&#x2F;p&gt;
&lt;p&gt;少し個人的な見解も折り込みましたが，Azure で機械学習を始める人は是非手に取って眺めて頂くことをオススメします！&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;CRISP-DM を機械学習プロジェクトの適用へと拡張したプラクティスです&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;2025年6月時点では，&quot;Pre-GA Offerings Terms&quot; というステータスになっています&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;3&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;3&lt;&#x2F;sup&gt;
&lt;p&gt;著者の一人が書かれた &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;speakerdeck.com&#x2F;shuntaito&#x2F;llmops-dmlops&quot;&gt;LLMOps : ΔMLOps&lt;&#x2F;a&gt; というスライドが参考になります&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;4&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;4&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2306.05685&quot;&gt;Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;5&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;5&lt;&#x2F;sup&gt;
&lt;p&gt;課金設定をオートチャージにしていないとクレジットが無くなって止まるケースもあるかもしれません&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>お名前.com から Cloudflare へのドメイン移行🚚</title>
        <published>2025-01-26T00:00:00+00:00</published>
        <updated>2025-01-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/domain-transfer-from-onamae-to-cloudflare/"/>
        <id>https://masatakashiwagi.com/blog/domain-transfer-from-onamae-to-cloudflare/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/domain-transfer-from-onamae-to-cloudflare/">&lt;p&gt;最近 X でお名前.com が Evil な件が取り沙汰されていましたが，僕も前から思うところがあったのと同僚も最近移行したよと聞いたので，これを機にドメインを Cloudflare に移行しました！&lt;&#x2F;p&gt;
&lt;p&gt;思うところがちらほらあったので，書いておくと...&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;メールの通知をオフにしないと大量に色々なメールが届く&lt;&#x2F;li&gt;
&lt;li&gt;サービス維持調整費という名で料金がよく上がる&lt;&#x2F;li&gt;
&lt;li&gt;レンタルサーバー代金が知らぬ間にかかっていた&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;自分もよく確認しておらず落ち度もあるが，&lt;strong&gt;なんせどこに料金がかかるのか分かりにくい&lt;&#x2F;strong&gt;です．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;domeinyi-xing&quot;&gt;ドメイン移行&lt;&#x2F;h2&gt;
&lt;p&gt;基本的に多くの先人が「お名前.com から Cloudflare へ」のドメイン移行をしていて，ネット上に記事が上がっているので，その通りにするだけです！&lt;&#x2F;p&gt;
&lt;p&gt;以下の記事を参考にして進めていきました．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zenn.dev&#x2F;muchoco&#x2F;articles&#x2F;9039762136e15c&quot;&gt;お名前.com から Cloudflare Registrar にドメイン移管した話&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zenn.dev&#x2F;ojisama&#x2F;articles&#x2F;ad50d9c0667d21&quot;&gt;お名前.comからCloudflareへのドメイン移管&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;注意としては，Cloudflare 側でドメインの登録をしてからでないと移行は進められないです．その際に移行したい自分のウェブサイト，僕の場合は &lt;strong&gt;masatakashiwagi.com&lt;&#x2F;strong&gt; が使われていないか確認する必要があります．&lt;&#x2F;p&gt;
&lt;p&gt;今回の移行に1点追記すると，このウェブサイトは，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vercel.com&#x2F;&quot;&gt;Vercel&lt;&#x2F;a&gt; でホスティングしています．今回は，Cloudflare のネームサーバーを利用するため，Cloudflare 側で DNS レコードを管理する必要があり，そのため Vercel 側のドメイン設定ページに行くと記載がある &lt;strong&gt;A Record と CNAME を Cloudflare の DNS レコードの管理画面で追加する&lt;&#x2F;strong&gt;を行い，これが完了することでウェブサイトを見れるようになります🎉&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;というわけで，お名前.com には少し前から不信感があったので，これを機に移行できて良かったです☺️&lt;&#x2F;p&gt;
&lt;p&gt;手順もとても簡単ですぐに進めることができました！めでたしめでたし．Cloudflare は今まで全然触ったことが無いサービスなので，機会があればまた触っていこうと思います．例えば Amazon S3 互換で S3 よりも料金が安い Cloudflare R2 Storage とかは以前話題になっていたのもあり，気になっているので何かの機会で使ってみたいです．&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>2024年の振り返り🚀</title>
        <published>2024-12-31T00:00:00+00:00</published>
        <updated>2024-12-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/look-back-on-this-year-2024/"/>
        <id>https://masatakashiwagi.com/blog/look-back-on-this-year-2024/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/look-back-on-this-year-2024/">&lt;p&gt;年を取ると1年が過ぎるのが早く感じます😅 今年は人生で初めて共著で MLOps に関する書籍を出版したり，業務面では生成 AI を活用したサービス開発に携わったり，色々なことを経験できた年でした．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;shi-shi-bian&quot;&gt;仕事編&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;manezimentoye-wu-henoben-ge-de-natiao-zhan-toyi-si-jue-ding&quot;&gt;マネジメント業務への本格的な挑戦と意思決定&lt;&#x2F;h3&gt;
&lt;p&gt;夏頃からマネジメント業務にも本格的に関わり出しました．今までの社会人生活では，マネジメント業務はあまり経験してこなかったので，未熟な面も多くチームメンバーに迷惑をかけてしまったかなと思います．プレイヤーとしても動かなければならず，自分の作業時間を確保して検証や実装を進めて成果を出すというマネジメント業務とのバランスを取るのはとても難しく感じました（世の中に多くいるプレイングマネージャーの人達や今までの上司やリーダーを改めて尊敬します）．&lt;&#x2F;p&gt;
&lt;p&gt;チームメンバーとのコミュニケーションや期待値の調整などミドル以上のメンバーが多い中でどこまで踏み込んで行くかは自分の中でも迷い悩んでいました．ただリーダーとして，意思決定をしないことはチームの状態を中途半端なものにしたり，方向性を失いやるべきことに集中できないことにも繋がるので，&lt;strong&gt;決めて前に進む&lt;&#x2F;strong&gt; ことはとても大事だと感じています．&lt;&#x2F;p&gt;
&lt;p&gt;こちらの坂井風太さんの NewsPicks の YouTube 動画（&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;AKIlibYDcvA?si=we_vN8--9bvurWte&quot;&gt;「会社の硬直化」はなぜ避けられない？／組織を変革するリーダー達は何をしているか／「合理的判断と決断」の違いを見極めろ（坂井風太：たった一人から始める「組織改革実践」）&lt;&#x2F;a&gt;）で話されている &lt;strong&gt;「合理的判断」と「決断」は異なる&lt;&#x2F;strong&gt; という話は学びがあったので紹介しておきます．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sheng-cheng-ai-nohuo-yong-to-ai-agent-henoqi-dai&quot;&gt;生成 AI の活用と AI Agent への期待&lt;&#x2F;h3&gt;
&lt;p&gt;他に機能開発面での取り組みは，数日前にプレスリリースが出されましたが，Community Copilot というコミュニティ運営をサポートする AI チャットボットサービスの開発を担当していました．自分の仕事がプレスリリースで外部に広く公開されるとやはり嬉しいです☺️&lt;&#x2F;p&gt;
&lt;p&gt;開発の話はまたテックブログか何かで紹介できればと思います．&lt;&#x2F;p&gt;
&lt;p&gt;PR TIMES の記事&lt;&#x2F;p&gt;
&lt;div class=&quot;iframely-embed&quot;&gt;&lt;div class=&quot;iframely-responsive&quot; style=&quot;height: 140px; padding-bottom: 0;&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;prtimes.jp&#x2F;main&#x2F;html&#x2F;rd&#x2F;p&#x2F;000000297.000036356.html&quot; data-iframely-url=&quot;&#x2F;&#x2F;iframely.net&#x2F;eCL8a6h?card=small&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;div&gt;&lt;&#x2F;div&gt;&lt;script async src=&quot;&#x2F;&#x2F;iframely.net&#x2F;embed.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;日経電子版の記事&lt;&#x2F;p&gt;
&lt;div class=&quot;iframely-embed&quot;&gt;&lt;div class=&quot;iframely-responsive&quot; style=&quot;height: 140px; padding-bottom: 0;&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.nikkei.com&#x2F;article&#x2F;DGXZQOUC268MH0W4A221C2000000&#x2F;&quot; data-iframely-url=&quot;&#x2F;&#x2F;iframely.net&#x2F;iauBw5K?card=small&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;div&gt;&lt;&#x2F;div&gt;&lt;script async src=&quot;&#x2F;&#x2F;iframely.net&#x2F;embed.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;生成 AI のサービス活用が世の中的にも盛んになり出した1年だったかなと思います．来年はチャットインターフェースから一段ステップアップした AI Agent が盛り上がりそうな感じではありますね（※ AI Agent の定義は諸説あるが...）．&lt;&#x2F;p&gt;
&lt;p&gt;個人的には，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ai.pydantic.dev&#x2F;&quot;&gt;PydanticAI&lt;&#x2F;a&gt; による AI Agent フレームワークが，プロダクションレベルでのアプリケーション開発を加速してくれることを期待して，追って行きたいです！&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Agents: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ai.pydantic.dev&#x2F;agents&#x2F;&quot;&gt;https:&#x2F;&#x2F;ai.pydantic.dev&#x2F;agents&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;最後にアウトプット系も書き出しておくと，テックブログは2件しか書けてなくて，ちょっと少ないと感じるので，来年は3ヶ月毎に1件の計4件程度書きたいです．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tech.commune.co.jp&#x2F;entry&#x2F;2024&#x2F;06&#x2F;24&#x2F;180000&quot;&gt;Vertex AI Pipelines で利用している Kubeflow Pipelines を v2 へ移行しました&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tech.commune.co.jp&#x2F;entry&#x2F;2024&#x2F;12&#x2F;12&#x2F;170000&quot;&gt;サービス×環境毎に用意していた GitHub Actions をサービス毎で1つに整理しました&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;jin-nian-noautopututotoshe-wai-fa-xin&quot;&gt;今年のアウトプットと社外発信&lt;&#x2F;h3&gt;
&lt;p&gt;社内でインタビューをいくつかして貰ったり，Findy に記事を寄稿したり，キャリア系のイベントに呼んで貰ったり去年とは違う経験がプラスでできました！&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;techhire.trackrecords.co.jp&#x2F;media&#x2F;ML-Career-Night1&quot;&gt;「ML Career Night #1｜生成AI時代の機械学習エンジニアのキャリア戦略」イベントレポート&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;note.com&#x2F;communeinc&#x2F;n&#x2F;n4d0104c5d483&quot;&gt;コミューンが考える 技術発信の意義と今後の展望&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;findy-tools.io&#x2F;articles&#x2F;ml&#x2F;17&quot;&gt;機械学習基盤のアーキテクチャ特集 〜8社の設計意図と今後の展望〜&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;note.com&#x2F;communeinc&#x2F;n&#x2F;n75db9daa87e0&quot;&gt;データの力でプロダクトに革新を！データチームの今と未来&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;puraibetobian&quot;&gt;プライベート編&lt;&#x2F;h2&gt;
&lt;p&gt;特に2024年は個人目標を立てていなかったですが，ジムに継続して通い続けられたのは良かったんじゃないかと思います．概ね週1~2回，仕事が忙しいと2週間に1回とかもありましたが，通えたことで体力や筋力を付けられただけでなく，精神的な部分も定期的にリフレッシュされてメンタルに良い影響があったと感じます．科学的にも，ドーパミンやセロトニンなどのホルモン分泌によって良い影響が出るみたいなので，来年も継続してジム通いは続けて行きます！！&lt;&#x2F;p&gt;
&lt;p&gt;2024年の一番大きい出来事はやっぱり &lt;strong&gt;書籍「事例でわかるMLOps」の出版&lt;&#x2F;strong&gt; ですかね！2023年にお話を頂いてから共著で参加させて貰いとても貴重な経験ができました．まさか自分が本を書くなんてゆめゆめ思ってなかったので，ブログを書いたり登壇したりコミュニティ運営に参加したりしていて良かったなと🎉&lt;&#x2F;p&gt;
&lt;div class=&quot;iframely-embed&quot;&gt;&lt;div class=&quot;iframely-responsive&quot; style=&quot;height: 140px; padding-bottom: 0;&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.amazon.co.jp&#x2F;%E4%BA%8B%E4%BE%8B%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8BMLOps-%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AE%E6%88%90%E6%9E%9C%E3%82%92%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AB%E3%81%95%E3%81%9B%E3%82%8B%E5%87%A6%E6%96%B9%E7%AE%8B-KS%E6%83%85%E5%A0%B1%E7%A7%91%E5%AD%A6%E5%B0%82%E9%96%80%E6%9B%B8-%E6%9D%89%E5%B1%B1-%E9%98%BF%E8%81%96&#x2F;dp&#x2F;4065369568&quot; data-iframely-url=&quot;&#x2F;&#x2F;iframely.net&#x2F;8re0DsL?card=small&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;div&gt;&lt;&#x2F;div&gt;&lt;script async src=&quot;&#x2F;&#x2F;iframely.net&#x2F;embed.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;Podcast でもこの辺りの話をしているので，もし良ければお聞きください！&lt;&#x2F;p&gt;
&lt;div style=&quot;max-width: 765px;&quot;&gt;&lt;div style=&quot;left: 0; width: 100%; height: 102px; position: relative;&quot;&gt;&lt;iframe src=&quot;https:&#x2F;&#x2F;anchor.fm&#x2F;double-m2&#x2F;embed&#x2F;episodes&#x2F;95-MLOps-e2q1hj9&quot; style=&quot;top: 0; left: 0; width: 100%; height: 100%; position: absolute; border: 0;&quot; allowfullscreen scrolling=&quot;no&quot;&gt;&lt;&#x2F;iframe&gt;&lt;&#x2F;div&gt;&lt;&#x2F;div&gt;
&lt;p&gt;出版イベントも開催して，MLOps 勉強会の他の運営メンバーとオフラインで会うことができて感慨深かったです！やっぱりリアルで人と会って会話するのは楽しい☺️&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mlops.connpass.com&#x2F;event&#x2F;328296&#x2F;&quot;&gt;第45回 『事例でわかるMLOps 機械学習の成果をスケールさせる処方箋』出版記念MLOps勉強会&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;iframe class=&quot;speakerdeck-iframe&quot; frameborder=&quot;0&quot; src=&quot;https:&#x2F;&#x2F;speakerdeck.com&#x2F;player&#x2F;fa33efb39ed6420486bf345fb51da531&quot; title=&quot;第45回 MLOps 勉強会 - ML Test Scoreを用いた機械学習システムの定量的なアセスメント&quot; allowfullscreen=&quot;true&quot; style=&quot;border: 0px; background: padding-box padding-box rgba(0, 0, 0, 0.1); margin: 0px; padding: 0px; border-radius: 6px; box-shadow: rgba(0, 0, 0, 0.2) 0px 5px 40px; width: 100%; height: auto; aspect-ratio: 560 &#x2F; 315;&quot; data-ratio=&quot;1.7777777777777777&quot;&gt;&lt;&#x2F;iframe&gt;
&lt;h3 id=&quot;jia-zu-ibento&quot;&gt;家族イベント&lt;&#x2F;h3&gt;
&lt;p&gt;子育て面では，子供がプレ幼稚園という形で週2回午前中だけ幼稚園に通い出して，友達を作ってきたり催し物をしたりと逞しく成長してくれていることは微笑ましいです☺️（よくお喋るする子で幼稚園ではムードメーカーみたい笑）スイミングにも通っていますが，つい数日前にテストに合格して1つ級がアップして運動も頑張ってくれてます！&lt;&#x2F;p&gt;
&lt;p&gt;あとは9月以降の家族イベントを振り返ると，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;10月
&lt;ul&gt;
&lt;li&gt;神戸須磨シーワールド&lt;&#x2F;li&gt;
&lt;li&gt;枚方パーク&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;実家に帰省して今回は須磨にあるシーワールドに行きました！自分が子供の頃にリニューアル前の水族館に行ったことがありますが，2024年6月1日にリニューアルされてめっちゃ綺麗になってました！見所はオルカ（シャチ）とイルカのショーで，オルカショーは飛び込み？ダイブ？の迫力が満点でした！ショーがメインで水族館要素はそこまで大きくない印象でした．&lt;&#x2F;p&gt;
&lt;p&gt;枚方パークは小学生ぐらいの小さい子供が楽しめそうなアトラクションが多くて子供連れには良さそうに思います！流石にまだ2歳だと身長制限で乗り物に乗れなかったりもしますが，それでも十分に楽しめました👍&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet tw-align-center&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;今日は神戸の須磨まで来てました！ &lt;a href=&quot;https:&#x2F;&#x2F;t.co&#x2F;MOEYZheO2p&quot;&gt;pic.twitter.com&#x2F;MOEYZheO2p&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (@asteriam_fp) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asteriam_fp&#x2F;status&#x2F;1844691683331788850?ref_src=twsrc%5Etfw&quot;&gt;October 11, 2024&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;ul&gt;
&lt;li&gt;11月
&lt;ul&gt;
&lt;li&gt;東武動物公園&lt;&#x2F;li&gt;
&lt;li&gt;よみうりランド&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;東武動物公園はちょうどアンパンマンショーがやっていたので，屋外で初めて子供と観戦して&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.anpanman.jp&#x2F;about&#x2F;friends&#x2F;m1nr4yc4nlj5uk0i.html&quot;&gt;かつぶしまん&lt;&#x2F;a&gt;を応援してました笑&lt;&#x2F;p&gt;
&lt;p&gt;初めて東武動物公園に行きましたが，動物園以外にも遊園地も併設されていて，巨大な遊具や滑り台があったりと遊べるものが多かったです．今回は時間が無くて遊具系では遊べなかったですが，また行きたいと感じられました．&lt;&#x2F;p&gt;
&lt;p&gt;よみうりランドの方はプリキュアショーを見るために行ってきました．最近日曜日の朝に一緒に見ているので，キャラクターの予習はバッチリでした笑&lt;&#x2F;p&gt;
&lt;p&gt;よみうりランドも初めてでしたが，企業協賛のアトラクションが色々とあったり，中でも大正製薬のアトラクションでは，ラムネ作りを子供と一緒に出来るのでおすすめです！&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet tw-align-center&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;今日は娘っちとプリキュアショーを見るために家族でよみうりランドに行った！&lt;br&gt;ゴンドラから見るイルミネーションがめっちゃ綺麗だった！ &lt;a href=&quot;https:&#x2F;&#x2F;t.co&#x2F;BxQHQRnQOt&quot;&gt;pic.twitter.com&#x2F;BxQHQRnQOt&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (@asteriam_fp) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asteriam_fp&#x2F;status&#x2F;1860634776480469492?ref_src=twsrc%5Etfw&quot;&gt;November 24, 2024&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;12月は家族の体調不良もあり予定していたイベントに行けなかったりしたので，来年は毎月イベントの皆勤賞目指していきます🔥&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lai-nian-nobao-fu&quot;&gt;来年の抱負&lt;&#x2F;h3&gt;
&lt;p&gt;来年もプライベートは家族との思い出作りがメインではあるものの，Software Engineering for ML&#x2F;MLOps 的な何かをしたいと思っているので，一緒にやろうと言ってくれる人がいらっしゃったらお声がけください🙏&lt;&#x2F;p&gt;
&lt;p&gt;興味関心がある新しい技術に触れていく幅を広げる動きと，今までの経験してきた領域のレベルを洗練させていく深さを掘る動きの両輪をバランス良く回して行きたいです！&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet tw-align-center&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;結局エンジニアは手を動かして動くモノ作らないと価値貢献出来ないなと感じるのと、自分の得意領域のレベルを洗練させていかないとなーと思う。&lt;&#x2F;p&gt;&amp;mdash; asteriam (@asteriam_fp) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asteriam_fp&#x2F;status&#x2F;1834186753722515878?ref_src=twsrc%5Etfw&quot;&gt;September 12, 2024&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;あとは個人的に物理の世界（リアルワールド）での機械学習適用に再び興味が戻って来ていて，ここ数年でのハードウェアの進歩やエネルギー効率の改善でエッジ側での機械学習を使った取り組みは面白そうだなと思うので，勉強して実験していきたいです（フラグか？...）．&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet tw-align-center&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;先日の飲みの席でみんなロマンを求めてるのを知ってそうだよなー！ってなった。ロマンは大事！&lt;br&gt;あとは物理世界でのML使ったサイエンスやセンシング技術を使った面白い取り組みは楽しそうという結論になった。&lt;&#x2F;p&gt;&amp;mdash; asteriam (@asteriam_fp) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asteriam_fp&#x2F;status&#x2F;1851614653132296362?ref_src=twsrc%5Etfw&quot;&gt;October 30, 2024&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;h3 id=&quot;owarini&quot;&gt;おわりに&lt;&#x2F;h3&gt;
&lt;p&gt;生成 AI の目覚ましい進歩を実感する1年だったような気がします．ChatGPT や Claude などのサービスに聞きたいことを投げれば回答が得られて素晴らしい体験を得られて，知識のショートカットが出来て，自分自身の可能性を広げてくれます．&lt;&#x2F;p&gt;
&lt;p&gt;一方で思うところとしては，自分への戒めでもありますが，何でもかんでも ChatGPT や Claude に投げてしまうと，自分の頭で考える癖が減ってしまうので，その辺りは注意していきたいです．考えることを放棄してしまうのはとても危険なことだと思い，僕の好きなブレーズ・パスカルの「&lt;strong&gt;人間は考える葦である&lt;&#x2F;strong&gt;」という言葉を反芻することが度々あります．考えたことが正しいとは限らないし，そもそも思考するには時間も労力もかかるので，聞いた方が早いじゃんとなりますが，自分自身の思想や感性，今までの経験や知見を持つのが人間らしさでもあると思うので，それによって組み立てた上で考えを補強・サポートするために上手く生成 AI の力を借りたいなと思います．&lt;&#x2F;p&gt;
&lt;p&gt;こう書いてますが，生成 AI による様々なサービスには助けられているし，今後も使っていくだろうし，もっと広まって人類が進歩していくことを期待しています🤖&lt;&#x2F;p&gt;
&lt;p&gt;余談ですが，先日の情熱大陸でイチローが話していた&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;news.yahoo.co.jp&#x2F;articles&#x2F;ffb5c3d0c80503ffab133108c4cd4f54d70678e7&quot;&gt;過度なデータ重視の現代野球に危機感を感じている&lt;&#x2F;a&gt;という話も上の話を考えていた時に見て，感覚的には分かる気がします．データや定量的に示されていることに疲れてしまって，もっと感性やアートな部分を求めているのかも知れないです．放送の中では，自分で考えることの大切さも話していたので，見ていない人は見てみると面白いかもです．&lt;&#x2F;p&gt;
&lt;p&gt;定量データをもちろん否定しているわけではないし，野球の話は個人の好き嫌い的な話になりますが，感覚的な部分や自分自身が五感で感じる要素も大事にする気持ちを持ち続けたいと，生成 AI の台頭により改めて思わせてくれました😊&lt;&#x2F;p&gt;
&lt;p&gt;ではでは今年はこの辺で👋&lt;&#x2F;p&gt;
&lt;p&gt;良いお年をお迎えください！&lt;br&#x2F;&gt;
Have a happy new year!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>マルチテナント環境における機械学習適用について考える</title>
        <published>2024-12-24T00:00:00+00:00</published>
        <updated>2024-12-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/multi-tenant-ml-pipeline/"/>
        <id>https://masatakashiwagi.com/blog/multi-tenant-ml-pipeline/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/multi-tenant-ml-pipeline/">&lt;p&gt;もう今年もあと数えるほどで終わってしまう😅（去年も同じこと書いている笑）&lt;&#x2F;p&gt;
&lt;!-- 最近は個人ブログをあまり書けていないのがよろしくないので，来年は定期的に書いて行きます（宣言！） --&gt;
&lt;p&gt;遅くなりましたが，この記事は &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;qiita.com&#x2F;advent-calendar&#x2F;2024&#x2F;mlops&quot;&gt;MLOps Advent Calendar 2024&lt;&#x2F;a&gt; の24日目の記事になります！&lt;&#x2F;p&gt;
&lt;p&gt;去年は「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masatakashiwagi.github.io&#x2F;portfolio&#x2F;post&#x2F;how-to-recreate-ml-pipeline&#x2F;&quot;&gt;機械学習パイプラインの作り方を改めて考えてみる&lt;&#x2F;a&gt;」というポストをしましたが，今年は「マルチテナント環境における機械学習適用」について考えていることや悩みを紹介します．&lt;&#x2F;p&gt;
&lt;p&gt;この内容を書こうと思ったモチベーションを最初に説明すると，昨今 SaaS でのプロダクトやサービス提供が増えていて，ソフトウェアなどを複数のクライアント企業で共有するモデルである&lt;strong&gt;マルチテナント&lt;&#x2F;strong&gt;方式が取られているが，プロダクトの機能として機械学習（ML）サービスをこのようなマルチテナント環境で提供する際の考え方や悩みどころに関する記事はあまり世の中で見かけない気がしています（以前からこのような方式で機械学習を提供している会社はたくさんありそうに思うのだが...）．そこで，参考になる記事が1つでもあればと思い，このブログを書くことにしました．&lt;&#x2F;p&gt;
&lt;p&gt;本ブログの構成としては，最初にマルチテナント環境での機械学習の話題が触れられている AWS の記事「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;jp&#x2F;blogs&#x2F;apn&#x2F;implementing-a-multi-tenant-mlaas-build-environment-with-amazon-sagemaker-pipelines&#x2F;&quot;&gt;Implementing a Multi-Tenant MLaaS Build Environment with Amazon SageMaker Pipelines&lt;&#x2F;a&gt;」と Azure の記事「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;architecture&#x2F;guide&#x2F;multitenant&#x2F;approaches&#x2F;ai-ml&quot;&gt;Architectural approaches for AI and ML in multitenant solutions&lt;&#x2F;a&gt;」を参考にマルチテナント環境での ML の考慮事項について紹介します．後半では，僕が経験してきた SaaS 提供での ML サービスの話題なども例として紹介していきます．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;marutitenantohuan-jing-deno-ml-shi-yong-notamenokao-lu-shi-xiang&quot;&gt;マルチテナント環境での ML 適用のための考慮事項&lt;&#x2F;h2&gt;
&lt;p&gt;ML 適用を考える際には，モデルの学習と推論という2つの大きなフェーズがあります．これらのフェーズには，モデルとデータ，そしてそれらを支えるインフラシステムが密接に関連してきます．&lt;&#x2F;p&gt;
&lt;p&gt;マルチテナント（複数の顧客が同一のシステムを共有する）環境では&lt;strong&gt;テナントの分離&lt;&#x2F;strong&gt;が重要な関心事になります．AWS のアーキテクチャガイドラインでは，これを Silo（完全分離）・Pool（共有）・Bridge（ハイブリッド）の3つのモデルとして紹介（&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;wellarchitected&#x2F;latest&#x2F;saas-lens&#x2F;silo-pool-and-bridge-models.html&quot;&gt;Silo, Pool, and Bridge Models&lt;&#x2F;a&gt;）しています．&lt;&#x2F;p&gt;
&lt;p&gt;ML の文脈では，データとモデルのセキュリティが特に重要で，具体的には，テナントが他のテナントのデータやモデルへ未承認または不正にアクセスできないようにする必要があります．例えば，投稿監視システムでは，テナント固有の監視ルールがある一方で，暴力的な投稿の検出など，すべてのテナントに共通する要件も存在します．このような共通要件に対しては，すべてのテナントのデータを統合して学習することで，より大規模なデータセットを活用でき，効果的なモデルを構築できる可能性があります．ただ，このようなデータ統合については，セキュリティ上問題ないか，契約的に大丈夫かといった制約を確認する必要が出てきます（安易にデータを使うことはできない）．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tenantonofen-li-patan&quot;&gt;テナントの分離パターン&lt;&#x2F;h3&gt;
&lt;p&gt;ここで話をテナントの分離に戻すと，マルチテナント環境における ML モデル・パイプラインの実装方式として，データとモデルの観点から主に下記2つのアプローチがあります．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;テナント専用のモデル&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;各テナントに専用リソースが提供されるモデルで，テナント固有のデータのみで学習を行い，テナントごとに独立したモデルが作成される&lt;&#x2F;li&gt;
&lt;li&gt;ML パイプラインの定義は複数のテナントで共有されることも多い&lt;&#x2F;li&gt;
&lt;li&gt;参考：AWS の MLaaS（Machine Learning as a Service）実装ガイドラインではテナント専用 ML モデルの具体的な構築例が載せられている&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;center&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024&#x2F;multi_tenant_ml_pipeline&#x2F;multi-tenant-tenant-specific-models.png&quot; alt=&quot;属性&quot;&gt;&lt;&#x2F;center&gt;
&lt;center&gt;&lt;figcaption&gt;テナント専用のモデルのパイプラインイメージ&lt;&#x2F;figcaption&gt;&lt;&#x2F;center&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;テナント共有のモデル&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;複数のテナントでリソースを共有しているモデルで，すべてのテナントのデータを用いて学習が行われ，単一の共有モデルが作成される&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;center&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024&#x2F;multi_tenant_ml_pipeline&#x2F;multi-tenant-shared-tenant-trained-models.png&quot; alt=&quot;属性&quot;&gt;&lt;&#x2F;center&gt;
&lt;center&gt;&lt;figcaption&gt;テナント共有のモデルのパイプラインイメージ&lt;&#x2F;figcaption&gt;&lt;&#x2F;center&gt;
&lt;ul&gt;
&lt;li&gt;テナント共有のモデルの例としては，事前学習済みの共通モデルを全テナントで利用するケースがある&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;center&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024&#x2F;multi_tenant_ml_pipeline&#x2F;multi-tenant-shared-pretrained-models.png&quot; alt=&quot;属性&quot;&gt;&lt;&#x2F;center&gt;
&lt;center&gt;&lt;figcaption&gt;テナント共有のモデルのパイプラインイメージ&lt;&#x2F;figcaption&gt;&lt;&#x2F;center&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;さらに，これらのハイブリッドアプローチとして，共有の事前学習済みモデルをベースにテナント固有のデータでファインチューニングを行う方式があります．この方式は，一般的な特徴を共有モデルで捉えつつ，テナント固有の要件に対応できる利点があります．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sukerabiriteihayao-zhu-yi&quot;&gt;スケーラビリティは要注意&lt;&#x2F;h3&gt;
&lt;p&gt;スケーラビリティは特に大事な要素で，サービスが拡大していくとテナントの数が増えていき，それに伴いテナントが保有するデータ量（ユーザー数，ログデータ）も増えていきます．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;テナント専用のモデル&lt;&#x2F;p&gt;
&lt;p&gt;必要なモデル数はテナント数に比例します．使用するデータについてはテナント毎でデータ量の差はあるものの，基本的には増加の一途を辿ることになるので，モデル学習時にどれだけのデータを使用するかの調整と，コンピューティングリソースの適切な割り当て（CPU, メモリ）が必要になり，コストにも関わってきます．また，テナント数に比例したモデル数になるので，マネージドサービスを使う場合は Quotas and limits が存在するため，システム設計をきちんと行う必要があります．&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;テナント共有のモデル&lt;&#x2F;p&gt;
&lt;p&gt;すべてのテナントデータを用いて学習を行うため，学習用のリソースがテナント数の増加と同じ速度でスケーリングされる可能性が低くなるが，その分データ量が専用モデルと比較して多くなり，モデルの学習時間も長くなる傾向にあります．これらは学習頻度にも影響してきます．&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;次に推論についても考えてみると，テナント専用のモデルを用意する場合が特に厄介で，方針は大きく2つあると思います．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;テナント毎に独立したサービングコンテナを用意する（単一モデルエンドポイント）&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Pros&lt;&#x2F;th&gt;&lt;th&gt;Cons&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;テナント毎のカスタマイズが容易で，リソースもテナント毎に適した配分をすることが可能になる&lt;&#x2F;td&gt;&lt;td&gt;テナント毎にサービングコンテナを用意する必要があるため，インフラコストが増加しがちで，デプロイメント作業やシステムの管理が複雑になる&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;複数のテナントモデルをホストできる共有サービングコンテナを用意する（マルチモデルエンドポイント）&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Pros&lt;&#x2F;th&gt;&lt;th&gt;Cons&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;インフラコストは効率的になる．アクセス頻度の高いモデルと低いモデルが混在している場合は，トラフィックが効率的に処理可能になる&lt;&#x2F;td&gt;&lt;td&gt;テナント間の分離レベルが低下するため，障害が発生した場合に影響範囲が全体に波及する．また &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;wellarchitected&#x2F;latest&#x2F;saas-lens&#x2F;noisy-neighbor.html&quot;&gt;Noisy Neighbors&lt;&#x2F;a&gt;（うるさい隣人）に注意が必要で，リソースをテナント間で共有している場合は，1つの大きなテナントによりリソースを過度に占有され，システム全体のパフォーマンスが低下する可能性がある&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;マルチエンドポイントと単一モデルエンドポイント（Dedicated Endpoint）の違いがわかりやすいです（AWS: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;sagemaker&#x2F;latest&#x2F;dg&#x2F;multi-model-endpoints.html&quot;&gt;Multi-model endpoints&lt;&#x2F;a&gt;）．&lt;&#x2F;p&gt;
&lt;center&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024&#x2F;multi_tenant_ml_pipeline&#x2F;multi-tenant-multi-model-endpoints-diagram.png&quot; alt=&quot;属性&quot;&gt;&lt;&#x2F;center&gt;
&lt;center&gt;&lt;figcaption&gt;Multi-model endpoints&lt;&#x2F;figcaption&gt;&lt;&#x2F;center&gt;
&lt;p&gt;どちらを選択しても一長一短あるので，自分たちのユースケースに応じた選択になります．マネージドサービスを利用している場合は，オートスケール設定にすることが多いが，気づいたら複数インスタンスが立ち上がってコストが爆発するケースもあるので，推論システムを用意する場合は慎重に進める必要があります．&lt;&#x2F;p&gt;
&lt;p&gt;推論システムの話は，「事例でわかる MLOps - 6.3.5 推論システム -デプロイと推論システム-」の章で解説されていて参考になります．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sonota-noyao-su&quot;&gt;その他の要素&lt;&#x2F;h3&gt;
&lt;p&gt;他には，パフォーマンスや実装の複雑さ，コストの話など考えることが多くあります．また，マルチテナントでは公平性についても議論されていて，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;jp&#x2F;builders-library&#x2F;fairness-in-multi-tenant-systems&#x2F;&quot;&gt;Fairness in multi-tenant systems&lt;&#x2F;a&gt; という AWS のアーキテクチャガイドラインが記された記事もあります．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;saas-purodakutodeno-ml-sabisuwokao-etemiru&quot;&gt;SaaS プロダクトでの ML サービスを考えてみる&lt;&#x2F;h2&gt;
&lt;p&gt;題材として推薦システムを取り上げ、以下の2つのユースケースについて検討してみます：&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;コンテンツ間の関連性に基づくレコメンド&lt;&#x2F;li&gt;
&lt;li&gt;ユーザーに応じたコンテンツのレコメンド（パーソナライズレコメンド）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;1-gong-you-moderuwoyong-itaguan-lian-kontentunotui-jian-sisutemu&quot;&gt;1. 共有モデルを用いた関連コンテンツの推薦システム&lt;&#x2F;h3&gt;
&lt;p&gt;関連コンテンツをどのような方法で実現するかは様々なアプローチがありますが，今回は一例としてコンテンツのタイトルや本文のテキスト情報の類似性を使った推薦を考えます．テキストの類似性を見るのであれば，学習済みの埋め込みモデルを用いて埋め込みベクトルを計算し，コサイン類似度で関連性の定量化を行うことができます．この場合は，テナント共有のモデルの章で紹介した共通の学習済みモデルから推論を行うパターンが考えられそうです．&lt;&#x2F;p&gt;
&lt;p&gt;提供する形態は，バッチ推薦として1日1回コンテンツに紐づいた推薦リストを用意してテナント毎にレコメンドを行います．&lt;&#x2F;p&gt;
&lt;p&gt;前処理や埋め込みベクトルの計算，レコメンド結果の保存といった一連の処理を毎日行う必要があるため，学習パイプラインを用意して処理をコンポーネント単位に分割して実行できると良さそうです．これをテナント毎にパイプラインを用意するか，それとも1つのパイプラインですべてのテナントのデータを処理するかは悩ましいところです．&lt;&#x2F;p&gt;
&lt;p&gt;悩ましい点としては，エラーハンドリングやリトライ処理の設計があるかと思います．エラーが発生した場合にどの時点から処理を再実行すべきなのか，すべての処理が完了しないとすべてのテナントに展開できないのかなど考えておくべきです．&lt;&#x2F;p&gt;
&lt;p&gt;また，データ量にも注意が必要で，テナント毎にコンテンツ量が違うため，あるテナントでは数千件，別のテナントでは数万件など考えられます．1つのパイプラインで全てを処理しようとしたら，推論時間も気にしないといけないです．&lt;&#x2F;p&gt;
&lt;center&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024&#x2F;multi_tenant_ml_pipeline&#x2F;multi-tenant-all-tenant-shared-ml-pipelines.png&quot; alt=&quot;Shared-ML-Pipelines&quot;&gt;&lt;&#x2F;center&gt;
&lt;center&gt;&lt;figcaption&gt;すべてのテナントのデータを一括で処理する vs. テナント毎にデータを処理する&lt;&#x2F;figcaption&gt;&lt;&#x2F;center&gt;
&lt;ol&gt;
&lt;li&gt;1つのパイプラインですべてのテナントのデータを処理
&lt;ul&gt;
&lt;li&gt;特定のテナントの処理でエラーが発生した際に，後続のテナントの処理に影響が出る&lt;&#x2F;li&gt;
&lt;li&gt;リトライ処理をどの位置から実行するか，それを容易に可能とする仕組みが必要になる&lt;&#x2F;li&gt;
&lt;li&gt;データ量がテナント毎で異なるため，マシンスペックなど適切なリソース設定が難しくテナント毎のコスト計算がしづらい&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;テナント毎のパイプラインでデータを処理
&lt;ul&gt;
&lt;li&gt;スケールする仕組みを用意しないと容易に破綻する．例えば，パイプラインを起動するスケジューラーをテナント毎に用意して起動させると考えた場合，テナント数だけ管理が必要で現実的ではない．またマネージドサービスを利用する場合は Quotas and limits が存在する&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;このため，モデルの定義やパイプラインの構成などは同一でもパイプライン自体をテナント毎に用意する選択肢が考えられます．これはテナントのデータ量に応じて適切なリソースを割り当てることができたり，エラーによる影響を最小限に留めるといったメリットがあります．&lt;&#x2F;p&gt;
&lt;center&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024&#x2F;multi_tenant_ml_pipeline&#x2F;multi-tenant-mlaas-aws.png&quot; alt=&quot;MLaaS-AWS&quot;&gt;&lt;&#x2F;center&gt;
&lt;center&gt;&lt;figcaption&gt;テナント毎のパイプラインでデータ処理を行うスケールするアーキテクチャ図（ref. AWS の記事）&lt;&#x2F;figcaption&gt;&lt;&#x2F;center&gt;
&lt;p&gt;このアーキテクチャでは，同時実行数を制御するために，Amazon SQS を活用して，Lambda によって実行状況を確認しながら，Amazon SageMaker Pipelines を起動する役割を担っています．&lt;&#x2F;p&gt;
&lt;p&gt;AWS ではなく，Google Cloud の Vertex AI Pipelines を活用する場合は，同時実行数の上限は300だが，上限を超えた場合は自動的にキューに入れてくれる設計になっています（参考：&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cloud.google.com&#x2F;vertex-ai&#x2F;docs&#x2F;quotas#vertex-ai-pipelines&quot;&gt;Vertex AI quotas and limits - Vertex AI Pipelines&lt;&#x2F;a&gt;）．そのため，Cloud Scheduler と Cloud Functions を用いて起動するタイミングを制御すれば良さそうです．&lt;&#x2F;p&gt;
&lt;p&gt;共有モデルを用いた場合は，モデルに関しては1つに定まるためそこに関しては考える要素が減ります．では，テナント専用のモデルを用いる場合はどうでしょうか？&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-zhuan-yong-moderuwoyong-itapasonaraizutui-jian-sisutemu&quot;&gt;2. 専用モデルを用いたパーソナライズ推薦システム&lt;&#x2F;h3&gt;
&lt;p&gt;専用モデルといった場合，データは1つのテナントのみを使用し，モデルアーキテクチャはすべてのテナント共通であるケースと，モデルアーキテクチャもテナント毎で異なるケースが考えられます．&lt;&#x2F;p&gt;
&lt;p&gt;機械学習を用いた推薦アルゴリズム特にディープラーニングを活用した場合は，精度にデータ量の問題が関わってきます．データ量が少ないと期待した精度が出ないため，テナントの属性データをクラスタリングしクラスター（大小の規模）に応じてより適切なアルゴリズムを選択したくなります．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;テナント毎のデータ量
&lt;ul&gt;
&lt;li&gt;多い場合：ディープラーニングによる複雑ではあるが効果的な手法&lt;&#x2F;li&gt;
&lt;li&gt;少ない場合：協調フィルタリングなどのオーソドックスな手法&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;このようなケースでは，設定ファイルやパラメータを渡せるようにしたり，テナント毎にメタデータを付与して動的にアルゴリズムを切り替えて管理する仕組みが必要とされるかもしれないです．専用モデルを用意するということは共通モデルと比べてモデルに関する要素が加わるため，より一層複雑性が増します．&lt;&#x2F;p&gt;
&lt;p&gt;専用モデルをオンライン推論したい場合は，「スケーラビリティは要注意」の章でも触れましたが，とにかく難易度が上がるので，可能ならなるべく避けたいです．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;マルチテナント環境での ML 適用を考えた場合の懸案事項について，主にデータとモデルの観点から考えてみました．テナント専用モデルと共有モデルそれぞれのアプローチには一長一短があり，サービスの要件や運用条件に応じて適切な選択が必要だと感じます．&lt;&#x2F;p&gt;
&lt;p&gt;今回はあまり触れていないですが，スケーラビリティだけなくセキュリティ・コストも重要な考慮すべき点として挙げられます．また推薦システムの例のように，実際のシステム設計では，要件に合わせたパイプラインの構成やエラーハンドリング・リソース管理など，様々な技術的な課題に直面しますが，クラウドサービスを組み合わせた適切なアーキテクチャ設計を行うことでこれらは対応できると思います．なので，もっと色々なユースケースが世の中に紹介されると嬉しいと個人的に感じます（toB 系のサービスの話は中々世に出せないケースもあると思うが...）．&lt;&#x2F;p&gt;
&lt;p&gt;マルチテナント環境は，1つの toC サービスで開発する場合とは考えることが変わってくるので，また違う難しさがあります．スケールアウト（マルチテナント）とスケールアップ（シングルサービス）のような感覚が個人的にあります😅&lt;&#x2F;p&gt;
&lt;p&gt;まだまだ綺麗に整理しきれていないと思いますが，また定期的にユースケースを整理したいです👋&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;jp&#x2F;blogs&#x2F;apn&#x2F;implementing-a-multi-tenant-mlaas-build-environment-with-amazon-sagemaker-pipelines&#x2F;&quot;&gt;Implementing a Multi-Tenant MLaaS Build Environment with Amazon SageMaker Pipelines&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;jp&#x2F;blogs&#x2F;apn&#x2F;implementing-saas-tenant-isolation-using-amazon-sagemaker-endpoints-and-iam&#x2F;&quot;&gt;Implementing SaaS Tenant Isolation Using Amazon SageMaker Endpoints and IAM&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;architecture&#x2F;guide&#x2F;multitenant&#x2F;approaches&#x2F;ai-ml&quot;&gt;Architectural approaches for AI and ML in multitenant solutions&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kspub.co.jp&#x2F;book&#x2F;detail&#x2F;5369562.html&quot;&gt;事例でわかる MLOps - 6章 顧客ごとに複数機械学習モデルを出し分ける学習と推論のアーキテクチャ&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>2024年4月から8月までの思い出プレイバック📘</title>
        <published>2024-09-08T00:00:00+00:00</published>
        <updated>2024-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/look-back-at-from-april-to-august-2024/"/>
        <id>https://masatakashiwagi.com/blog/look-back-at-from-april-to-august-2024/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/look-back-at-from-april-to-august-2024/">&lt;p&gt;前回の&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masatakashiwagi.com&#x2F;posts&#x2F;strawberry-picking-2024&quot;&gt;いちご狩り&lt;&#x2F;a&gt;からブログを更新出来ていなかったので，久しぶりに更新しようと思い筆を走らせています！一つ一つを細かく記すのは記憶が怪しいので笑，コンパクトに振り返ります．&lt;&#x2F;p&gt;
&lt;p&gt;時系列だと，こんな感じです．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;4月: 大阪（実家帰省）・ユニバーサルスタジオジャパン&lt;&#x2F;li&gt;
&lt;li&gt;5月: ヒノトントン ZOO（羽村市動物公園）&lt;&#x2F;li&gt;
&lt;li&gt;5月: ワンパーク・こども広場Ｂのくに（群馬県）&lt;&#x2F;li&gt;
&lt;li&gt;5月: 東京競馬場（府中競馬場）&lt;&#x2F;li&gt;
&lt;li&gt;6月: 川越（小江戸川越）&lt;&#x2F;li&gt;
&lt;li&gt;7月: 横浜アンパンマンこどもミュージアム&lt;&#x2F;li&gt;
&lt;li&gt;8月: 京王あそびの森 HUGHUG&lt;&#x2F;li&gt;
&lt;li&gt;9月: 伊豆熱川温泉（静岡県） → 子供の体調不良により中止&lt;&#x2F;li&gt;
&lt;li&gt;10月: 大阪（実家帰省）・神戸須磨シーワールド → 予定&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;では，それぞれの月の出来事を振り返っていきます．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zhen-rifan-ri-4yue-bian&quot;&gt;振り返り: 4月編&lt;&#x2F;h2&gt;
&lt;p&gt;半年に一度のペースぐらいで大阪の実家に帰省していて，今回のメインイベントはユニバーサルスタジオジャパン（USJ）に行くことです．3月は春休みの学生多め，5月は GW で人多めと判断し，ちょうど間で暑くなり過ぎる前の4月に行くことに決めました！（ユニバに行った日は快晴で日差しも強くめちゃくちゃ暑かったです🥵）&lt;&#x2F;p&gt;
&lt;p&gt;初日はぶらっと難波に観光しに行きました．久しぶりになんばグランド花月の方に行くと，まず高島屋の前の通りが広場になっていて車が通れなくなっていたのは衝撃でした！テラス席があったり広々としていてとても開放感があり良かったです．&lt;&#x2F;p&gt;
&lt;p&gt;そこからなんばグランド花月の横にある &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tabelog.com&#x2F;osaka&#x2F;A2701&#x2F;A270202&#x2F;27002320&#x2F;&quot;&gt;わなか&lt;&#x2F;a&gt;&quot; にたこ焼きを食べに行ったり（昔はもっとカリカリやったような気もします），なんばグランド花月の公演表を覗くと，面白そうな公演がやってそうでした！（金属バットは前々職の仲の良かった人に教えて貰って好きだったので，結構見たかった笑）※ たこ焼きは &quot;わなか&quot; か &quot;くくる&quot; が難波辺りだと有名で無難かな👍&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024&#x2F;look_back_at_from_april_to_august_2024&#x2F;osaka1.jpg&quot; alt=&quot;なんば&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;その後は，マルイで涼んだり，551を買って食べ歩きをしたり，戎橋筋商店街は，ほぼ外国人しか居なくて少し前は中国人だらけでしたが，ヨーロッパ系の人達も多く日本人が少数ぐらいでびっくりしました！&lt;&#x2F;p&gt;
&lt;p&gt;2日目はユニバでガッツリ遊びました！快晴なのは良かったですが，思ったより気温が高くて園内で長時間歩くのはこたえました...ちょうどイースターのイベントがやっていて，ミニオンエリアはイースター仕様のミニオン達で溢れ返っていました☺️&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024&#x2F;look_back_at_from_april_to_august_2024&#x2F;osaka2.jpg&quot; alt=&quot;ユニバーサルスタジオ1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024&#x2F;look_back_at_from_april_to_august_2024&#x2F;osaka3.jpg&quot; alt=&quot;ユニバーサルスタジオ2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;学生の時以来のユニバでかなり久々だったので，エリアも様変わりしてました．マリオの新エリアは結構中が狭くて人が多く，かなりごちゃごちゃしていてちょっと子連れにはしんどかったです．あとこのエリアに入るのに入場整理券が必要で，確約券を買うとかなりのお値段になってビビりました...&lt;&#x2F;p&gt;
&lt;p&gt;個人的に今回満足度高かったのは &quot;ウォーターワールド&quot; です！コールアンドレスポンスがあったり，笑いもありつつハラハラ感もありで，会場と一体感のある迫力あるショーとしてとても楽しかったです！なんやかんやで十分楽しめてトータルでは満足度高めでした！！&lt;&#x2F;p&gt;
&lt;p&gt;3日目は万博記念公園にある子供向け遊具があるエリアに遊びに行ったり，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mitsui-shopping-park.com&#x2F;lalaport&#x2F;expocity&#x2F;&quot;&gt;EXPOCITY&lt;&#x2F;a&gt; で軽くショッピングしたりしました．本当は&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nifrel.jp&#x2F;&quot;&gt;ニフレル&lt;&#x2F;a&gt;に行こうとしましたが，子供が急にグズリ出したので，やめました😥（ニフレルは次回リベンジしたい．あとは場所は違いますが，天王寺動物園とかも行きたい）&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zhen-rifan-ri-5yue-bian&quot;&gt;振り返り: 5月編&lt;&#x2F;h2&gt;
&lt;p&gt;5月編はサクッと，まずゴールデンウィークに羽村市にある通称ヒノトントン ZOO（羽村市動物公園）に行きました！かなり小ぢんまりした動物園で数時間でざーっと園内を見れるのと，全く混んで居なかったので，とても快適に回れました！鯉やモルモットへの餌やり体験などもできるので，面白かったですが，娘は餌やりにかなりビビっていました笑&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024&#x2F;look_back_at_from_april_to_august_2024&#x2F;zoo1.jpg&quot; alt=&quot;動物園&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;ゴールデンウィークの別日には，群馬県にある &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;won-park.com&#x2F;&quot;&gt;ワンパーク・こども広場Ｂのくに&lt;&#x2F;a&gt;&quot; という日本最大級の屋内子供施設に行きました！とにかく広くゴールデンウィークでもそれほど混んで居なかったので，屋内で快適に遊べました．2~3歳ぐらいの子供の場合は，年長や小学校低学年の結構走り回る子供が多い場所だとぶつかったりする心配や不安がありますが，その辺を感じさせないぐらいとにかく大きいので，素晴らしかったです！（動画ばかり撮っていて写真がありませんでした😥）滑り台の種類も多く子供と一緒に何回も滑って遊びました☺️&lt;&#x2F;p&gt;
&lt;p&gt;ここはリピート確定です！！！&lt;&#x2F;p&gt;
&lt;p&gt;5月のイベント最後は，初めて競馬場に行きました（混雑回避のため，オークス前日の土曜日に行ってきた）．東京競馬場は車でも行けて，場内に子供が遊ぶことができる遊具が色々と配置されていて，大人は競馬，子供は遊具遊びをできる感じに整ってました笑（メインスタンドの反対側に遊ぶところがあります）&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet tw-align-center&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;東京競馬場に遊びに来た！キッズスペースが充実してて娘っちも楽しそう！ &lt;a href=&quot;https:&#x2F;&#x2F;t.co&#x2F;WlzWefgzAc&quot;&gt;pic.twitter.com&#x2F;WlzWefgzAc&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (@asteriam_fp) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asteriam_fp&#x2F;status&#x2F;1791640817943392659?ref_src=twsrc%5Etfw&quot;&gt;May 18, 2024&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;いくつかのレースに賭けましたが，払い戻しは0円でした😂&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zhen-rifan-ri-6yue-bian&quot;&gt;振り返り: 6月編&lt;&#x2F;h2&gt;
&lt;p&gt;川越に行く予定は全くしてませんでしたが，お昼ご飯を食べて帰っていたところ，自宅到着の直前で子供が寝たので，昼寝している間にドライブがてら川越まで行ってみました！川越には，以前一度本川越の駅前で日本酒が飲める場所があり，そこで友人と飲んだことはありましたが，観光地の小江戸川越の方は行ったことがありませんでした．&lt;&#x2F;p&gt;
&lt;p&gt;さつまいものお菓子屋スイーツがいっぱいあり，芋好きにはたまりません．大きいふ菓子を持ってる人が多くてこの辺は有名なのでしょうか？道路沿いにお店がありますが，歩道部分が狭いので，子供連れの方は注意が必要です．&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet tw-align-center&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;週末はドライブがてら川越まで行って芋スイーツ食べて来ました。 &lt;a href=&quot;https:&#x2F;&#x2F;t.co&#x2F;unFh3dZccj&quot;&gt;pic.twitter.com&#x2F;unFh3dZccj&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (@asteriam_fp) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asteriam_fp&#x2F;status&#x2F;1807593403712213021?ref_src=twsrc%5Etfw&quot;&gt;July 1, 2024&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;※ X のポストは7&#x2F;1ですが，行ったのは6&#x2F;29です．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zhen-rifan-ri-7yue-bian&quot;&gt;振り返り: 7月編&lt;&#x2F;h2&gt;
&lt;p&gt;7月は子供が以前から行きたがっていた横浜にあるアンパンマンミュージアムに行ってきました！アンパンマンミュージアムは全国に5ヶ所あり，仙台・横浜・名古屋・神戸・福岡とあります．&lt;&#x2F;p&gt;
&lt;p&gt;子供はコキンちゃんとドキンちゃんが好きで，2体の人形も携えて参戦しました！ショーは最前列で見れて大興奮で，ほっこりしました☺️&lt;&#x2F;p&gt;
&lt;p&gt;施設自体は思ったより大きくなく，子供が楽しめる場所がワンフロアで，1階にはフードコートとお土産屋さんとパン工場があるぐらいでした．メインはショーを楽しむ感じです．&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet tw-align-center&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;今日は横浜のアンパンマンミュージアムに来てます！ &lt;a href=&quot;https:&#x2F;&#x2F;t.co&#x2F;2XnZjWJpk4&quot;&gt;pic.twitter.com&#x2F;2XnZjWJpk4&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (@asteriam_fp) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asteriam_fp&#x2F;status&#x2F;1807970227277517274?ref_src=twsrc%5Etfw&quot;&gt;July 2, 2024&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;h2 id=&quot;zhen-rifan-ri-8yue-bian&quot;&gt;振り返り: 8月編&lt;&#x2F;h2&gt;
&lt;p&gt;8月は多摩動物公園の前にある&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.keio-hughug.jp&#x2F;&quot;&gt;京王あそびの森 HUGHUG&lt;&#x2F;a&gt;という所に行ってみました．以前&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masatakashiwagi.com&#x2F;posts&#x2F;stroll-to-tama-zoological-park&quot;&gt;多摩動物公園に遊びに行った&lt;&#x2F;a&gt;時に存在を知って，また行こうと話していてそれで今回行きました．&lt;&#x2F;p&gt;
&lt;p&gt;中には室内で遊ぶ所がありますが，今回は週末に行ったのもあり人が多く，また年齢層も未就学児から小学生ぐらいまで居て，同一空間内で遊ぶので，2歳児の子供にはヒヤヒヤする場面が多かったです．X のポストでは，程よく遊べたと書きましたが，遊具などはそこまで多くないので，子供によっては物足りない &amp;amp; 混雑時は人の多さであまり遊べないかもという感じです．&lt;&#x2F;p&gt;
&lt;p&gt;館内に併設されているハグハグカフェは待ち人数がすごいですが，味は結構美味しかったです☺️（もし，ここを利用される場合は，先に待ち予約してから遊んだ方がいいです）&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet tw-align-center&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;京王あそびの森 HUGHUGと隣にある京王れーるランド行ってきたけど、2歳児には程よく遊べた。 &lt;a href=&quot;https:&#x2F;&#x2F;t.co&#x2F;NHn3klr8K0&quot;&gt;pic.twitter.com&#x2F;NHn3klr8K0&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (@asteriam_fp) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asteriam_fp&#x2F;status&#x2F;1825113378874184007?ref_src=twsrc%5Etfw&quot;&gt;August 18, 2024&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;9月は温泉旅行の計画が子供の体調不良で中止になり，10月は予定なので，次回は12月ぐらいにイベント振り返りブログは書こうと思います！&lt;&#x2F;p&gt;
&lt;p&gt;あまりどこかに行った感覚はありませんでしたが，近場多めでちょくちょく出かけているなと振り返って思いました．1ヶ月最低1イベントを心掛けているので，引き続き子供が楽しめる場所を探して遊びに行きたいと思います！冬場は温泉でリフレッシュでもしたいです😊&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>娘待望のいちご🍓狩りに行ってきた</title>
        <published>2024-03-30T00:00:00+00:00</published>
        <updated>2024-03-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/strawberry-picking-2024/"/>
        <id>https://masatakashiwagi.com/blog/strawberry-picking-2024/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/strawberry-picking-2024/">&lt;p&gt;3月24日の日曜日に前々から行きたかったいちご狩りに行ってきました！いちご大好きな娘にとっては待望でした！どれだけいちごが好きかというと，ここ数週間はほぼ毎日いちごを食べるぐらいには好きで，「ぃちご，たびる！」って毎日言っています笑&lt;&#x2F;p&gt;
&lt;h2 id=&quot;jin-nian-chu-dai-wang-noitigoshou-ri&quot;&gt;今年初待望のいちご狩り&lt;&#x2F;h2&gt;
&lt;p&gt;前々からいちご狩りに行きたいと話していましたが，なかなか行く機会が無くて行けていませんでした．この度ようやく家族の予定が合い自宅から近くのいちご農園がやっているところに行ってきました！&lt;&#x2F;p&gt;
&lt;p&gt;料金は30分食べ放題で，大人は2500円&#x2F;人・3歳以下は無料という料金設定でした．恐らく家族の中で一番食べていたのは娘だったと思います笑&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024&#x2F;strawberry_picking&#x2F;strawberry1.jpg&quot; alt=&quot;いちご狩り&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;いちごの種類は，「紅ほっぺ」・「かおり野」・「章姫」・「おいCベリー」の4種類．&lt;&#x2F;p&gt;
&lt;p&gt;いちごの食べ頃というのがあり，「先っぽからヘタの下まで赤く色づきツヤがあるいちごが​甘く美味しく食べ頃です。またヘタの下部分に割れ目が入ったものが熟していて特に甘いです。」という説明がありましたが，とりあえず大きいやつを食べていました笑&lt;&#x2F;p&gt;
&lt;p&gt;個人的には，「おいCベリー」が酸っぱさと甘さがちょうど良く美味しく，またビタミンCも豊富ということで免疫力の強化をできたんじゃないかなと思います笑&lt;&#x2F;p&gt;
&lt;p&gt;また，練乳も無料で貰えたので，適度に味変して食べていました！&lt;&#x2F;p&gt;
&lt;p&gt;30分は短いのかなと思いましたが，意外とあっという間でお腹も良い感じに膨れました．しかし，少し時間が経つとお腹が減ってきたので，腹持ちはそこまで良くありませんでした☺️&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今年も毎月楽しい思い出を作ろうと思っていますが，近場を考えると行く場所も枯渇したりするので，こういった季節のイベント系は良いなと思いました．&lt;&#x2F;p&gt;
&lt;p&gt;4月は大阪に帰省して USJ に行く予定なので，またポエムを書きます！5, 6月はどこで何をしようかな？🤔&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>「Azure OpenAI Service ではじめる ChatGPT&#x2F;LLM システム構築入門」を読んでの書評</title>
        <published>2024-01-21T00:00:00+00:00</published>
        <updated>2024-01-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/review-azure-openai-service-book/"/>
        <id>https://masatakashiwagi.com/blog/review-azure-openai-service-book/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/review-azure-openai-service-book/">&lt;p&gt;2024年1月24日に発売される「&lt;strong&gt;Azure OpenAI Service ではじめる ChatGPT&#x2F;LLM システム構築入門&lt;&#x2F;strong&gt;」を著者の一人である立脇さんから献本いただいたので，書評を書いていきます！&lt;&#x2F;p&gt;
&lt;div class=&quot;iframely-embed&quot;&gt;&lt;div class=&quot;iframely-responsive&quot; style=&quot;height: 140px; padding-bottom: 0;&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;gihyo.jp&#x2F;book&#x2F;2024&#x2F;978-4-297-13929-2&quot; data-iframely-url=&quot;&#x2F;&#x2F;cdn.iframe.ly&#x2F;api&#x2F;iframe?card=small&amp;url=https%3A%2F%2Fgihyo.jp%2Fbook%2F2024%2F978-4-297-13929-2&amp;key=1ac31cfb1f29f0cc6c5c03e9b56116df&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;div&gt;&lt;&#x2F;div&gt;&lt;script async src=&quot;&#x2F;&#x2F;cdn.iframe.ly&#x2F;embed.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;改めて，出版おめでとうございます🎉&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet tw-align-center&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;Azure OpenAI Serviceではじめる ChatGPT&#x2F;LLMシステム構築入門（AOAIドーナツ本）を著者の立脇さんから献本頂きました🎉&lt;br&gt;Azure上でのChatGPTを用いたシステム構築の話はもちろんのこと、ガバナンスやResponsible AIにも言及していて興味深く読ませて頂いてます！後ほど書評ブログも書かせて頂きます。 &lt;a href=&quot;https:&#x2F;&#x2F;t.co&#x2F;oRqcYAV0gr&quot;&gt;pic.twitter.com&#x2F;oRqcYAV0gr&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (@asteriam_fp) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asteriam_fp&#x2F;status&#x2F;1748572342912262254?ref_src=twsrc%5Etfw&quot;&gt;January 20, 2024&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;h2 id=&quot;shu-ji-nomu-ci&quot;&gt;書籍の目次&lt;&#x2F;h2&gt;
&lt;p&gt;目次は以下のように全体は4部構成（+付録）になっています．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;第1部: Microsoft Azure での ChatGPT 活用
&lt;ul&gt;
&lt;li&gt;第1章: 生成 AI と ChatGPT&lt;&#x2F;li&gt;
&lt;li&gt;第2章: プロンプトエンジニアリング&lt;&#x2F;li&gt;
&lt;li&gt;第3章: Azure OpenAI Service&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;第2部: RAG による社内文章検索の実装
&lt;ul&gt;
&lt;li&gt;第4章: RAG の概要と設計&lt;&#x2F;li&gt;
&lt;li&gt;第5章: RAG の実装と評価&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;第3部: Copilot stack による LLM アプリケーションの実装
&lt;ul&gt;
&lt;li&gt;第6章: AI オーケストレーション&lt;&#x2F;li&gt;
&lt;li&gt;第7章: 基盤モデルと AI インフラストラクチャ&lt;&#x2F;li&gt;
&lt;li&gt;第8章: Copilot フロントエンド&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;第4部: ガバナンスと責任ある AI
&lt;ul&gt;
&lt;li&gt;第9章: ガバナンス&lt;&#x2F;li&gt;
&lt;li&gt;第10章: 責任ある AI&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;付録
&lt;ul&gt;
&lt;li&gt;付録 A: サンプルコード実行環境の準備&lt;&#x2F;li&gt;
&lt;li&gt;付録 B: ChatGPT の仕組み（詳細編）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;nei-rong-noshao-jie-togan-xiang&quot;&gt;内容の紹介と感想&lt;&#x2F;h2&gt;
&lt;p&gt;各章の概要について簡単に触れつつ，個人的に興味深かった点や印象に残った点を紹介します．&lt;&#x2F;p&gt;
&lt;p&gt;本書は初めに読者の目的とレベル感に合わせてどの章から読めば良いかが示されていて，全体の見通しがクリアになるように設計されています．そのため，目的に合わせて必要な章を効率良く読むことができます．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;di-1bu-microsoft-azure-deno-chatgpt-huo-yong&quot;&gt;第1部: Microsoft Azure での ChatGPT 活用&lt;&#x2F;h3&gt;
&lt;p&gt;第1部は，最初に生成 AI と ChatGPT 基礎的な概念と仕組みを紹介しています．ChatGPT がどういったタスクをこなすことができるかについてもまとめられていて，ユースケースの例もあるので，活用のイメージを膨らませることができます．&lt;&#x2F;p&gt;
&lt;p&gt;また，生成 AI の出力に関係してくるプロンプトの基本的な書き方の紹介，気をつけるべき観点が整理されていて，プロンプトエンジニアリングも学ぶことができます．&lt;&#x2F;p&gt;
&lt;p&gt;第1部の最後は，Azure OpenAI Service の使い方が書かれています．Open AI が開発した AI モデルをマネージドサービスとして使用することができ，Azure OpenAI の始め方が図を使って丁寧に解説されています．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;di-2bu-rag-niyorushe-nei-wen-zhang-jian-suo-noshi-zhuang&quot;&gt;第2部: RAG による社内文章検索の実装&lt;&#x2F;h3&gt;
&lt;p&gt;第2部は，ChatGPT を使った社内文章検索システムを題材にして，RAG の説明から実際に Azure 上でどういったサービスを組み合わせてシステムを構築するかについても丁寧に説明されています．後半には，RAG の評価の仕方も記載されていて，とても好感が持てます．&lt;&#x2F;p&gt;
&lt;p&gt;また，Azure Machine Learning プロンプトフローを使って効率良くプロンプトの検証・開発をする方法も紹介されています．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;di-3bu-copilot-stack-niyoru-llm-apurikesiyonnoshi-zhuang&quot;&gt;第3部: Copilot stack による LLM アプリケーションの実装&lt;&#x2F;h3&gt;
&lt;p&gt;第3部は，ChatGPT などの LLM を組み込んだアプリである Copilot を開発するための話が，Copilot フロントエンド・AI オーケストレーション・基盤モデルの3段階で紹介されています．&lt;&#x2F;p&gt;
&lt;p&gt;Copilot フロントエンドの説明では，UX 向上のためにストリーミング処理の実装や参考資料などが紹介されていて，ユーザビリティの重要性を教えてくれます．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;di-4bu-gabanansutoze-ren-aru-ai&quot;&gt;第4部: ガバナンスと責任ある AI&lt;&#x2F;h3&gt;
&lt;p&gt;第4部は，生成 AI のサービスや機能を開発・運用していく上でのガバナンスの話や責任ある AI に対する Microsoft の取り組みなどが紹介されています．ガバナンスの話では，認証周りや課金，アクセス制限など組織で活用していく上で考慮すべき問題を取り上げています．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;xing-wei-shen-katutadian-yin-xiang-nican-tutadian&quot;&gt;興味深かった点&#x2F;印象に残った点&lt;&#x2F;h3&gt;
&lt;p&gt;ここからは個人的な感想を書いていこうと思います．&lt;&#x2F;p&gt;
&lt;p&gt;まず全体的に注釈で細く補足がなされていたり，参考文献が挙げられていてとても親切です．タイトルにも含まれるように Azure を使った内容にはなっていますが，プロンプトエンジニアリングや RAG の設計・評価，基盤モデルの話など ChatGPT&#x2F;LLM をサービスに活用する上で知っておくべき一般的な内容についてもしっかりと説明がされていて，まだまだキャッチアップ不足の僕にはとても参考になりました！&lt;&#x2F;p&gt;
&lt;p&gt;後半ではガバナンスや責任ある AI (Responsible AI) を取り上げていて，これらについて言及している書籍はまだまだ少ない状況なので，とても有益です．サービスとして機械学習を提供するのであれば，こういった内容についても理解を深め取り組んでいくべき（自戒を込めて）で，それを助ける参考文献が色々と記載されています．&lt;&#x2F;p&gt;
&lt;p&gt;以下は，特に個人的な推しポイントを3つ紹介します．&lt;&#x2F;p&gt;
&lt;h4 id=&quot;1-rag-woshi-tutajian-suo-sisutemunoshe-ji-toping-jia&quot;&gt;1. RAG を使った検索システムの設計と評価&lt;&#x2F;h4&gt;
&lt;p&gt;Retrieval-Augumented Generation (RAG) を使うメリットやアーキテクチャを最初に説明することで，これからどういったものを考えていくのかがわかりやすかったです．コンテキストが示されて体系的に説明がされているので，テックブログのように断片的なものよりは理解が進みやすいです．&lt;&#x2F;p&gt;
&lt;p&gt;特に検索システムの説明が厚くてとても良かったです！Azure AI Search を題材にしていますが，インデックス作成・ドキュメント検索の流れを図を用いて丁寧に解説されています．インデックス作成の流れは別の検索システムを使うにしても参考となりそうです．特に RAG を使った検索では，&lt;strong&gt;ドキュメントの文字数&lt;&#x2F;strong&gt;と&lt;strong&gt;文の意味に基づいた検索&lt;&#x2F;strong&gt;が重要であるという内容がしっかり書かれていて理解が深まりました．&lt;&#x2F;p&gt;
&lt;p&gt;また，Azure AI Search では，フルテキスト検索とベクトル検索のハイブリッド検索を利用することができ，&lt;strong&gt;ハイブリッド検索とセマンティックランカーを行うことでより高精度な検索が実現可能&lt;&#x2F;strong&gt;とのことです（下図）．こういった柔軟な検索手法の組み合わせが，比較的簡単にマネージドサービスとして実装できるのは楽だなと感じます．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024&#x2F;review_azure_openai_service_book&#x2F;review-aoai-book-img1.png&quot; alt=&quot;ハイブリッド+セマンティックランカー&quot; title=&quot;review-aoai-book&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;参考: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;techcommunity.microsoft.com&#x2F;t5&#x2F;ai-azure-ai-services-blog&#x2F;azure-ai-search-outperforming-vector-search-with-hybrid&#x2F;ba-p&#x2F;3929167&quot;&gt;Azure AI Search: Outperforming vector search with hybrid retrieval and ranking capabilities&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;RAG の評価についても書かれていて，RAG の評価では，&lt;strong&gt;検索精度の問題&lt;&#x2F;strong&gt;と&lt;strong&gt;生成精度の問題&lt;&#x2F;strong&gt;の２つがあります．特に生成精度の評価はまだまだスタンダードな方法がなく難しいですが，その一例として，OSS で RAG 用の評価フレームワークである &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;explodinggradients&#x2F;ragas&quot;&gt;Ragas&lt;&#x2F;a&gt; があるよと紹介されています．単一のメトリクスで判断するのではなく，複数の組み合わせがおすすめされてて，&lt;strong&gt;関連性・一貫性・類似性の評価&lt;&#x2F;strong&gt;について解説もされています．評価方法どうすればいいかあまり理解していなかった自分にとっては良い示唆をもらえました！&lt;&#x2F;p&gt;
&lt;h4 id=&quot;2-okesutoretazuo-cheng-notameno-azure-machine-learning-puronputohuro&quot;&gt;2. オーケストレータ作成のための Azure Machine Learning プロンプトフロー&lt;&#x2F;h4&gt;
&lt;p&gt;Azure Machine Learning プロンプトフローはローコードでオーケストレータを作成できるサービスで GUI&#x2F;CLI で利用できるとのことです．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;実行フローの可視化&lt;&#x2F;li&gt;
&lt;li&gt;チームでの共有やデバッグ&lt;&#x2F;li&gt;
&lt;li&gt;複数のプロンプトを試せるプロンプトバリアント機能&lt;&#x2F;li&gt;
&lt;li&gt;etc...&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;特に興味を持ったのは，&lt;strong&gt;プロンプトバリアント機能&lt;&#x2F;strong&gt;で，プロンプトは色々と試行錯誤して良さげなものを探すと思いますが，これらを一度に複数パターンを定義できて実行できるとのことで，実験速度がめっちゃくちゃ上がりそうだなと感じました！改善しやすい仕組みが自分で整備しなくても整えられているので，やりたいことに集中できて，開発者体験としてとても良さそうに思います！&lt;&#x2F;p&gt;
&lt;h4 id=&quot;3-ze-ren-aru-ai-responsible-ai-noqu-rizu-mi&quot;&gt;3. 責任ある AI (Responsible AI) の取り組み&lt;&#x2F;h4&gt;
&lt;p&gt;Microsoft では，責任ある AI (Responsible AI) として，以下の6つの原則を掲げています．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;公平性&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;AI システムはすべての人を公平に扱う必要がある&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;信頼性と安全性&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;AI システムは信頼でき安全に実行する必要がある&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;プライバシーとセキュリティ&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;AI システムは安全であり，プライバシーを尊重する必要がある&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;包括性&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;AI システムはあらゆる人に力を与え，人々を結びつける必要がある&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;透明性&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;AI システムは理解しやすい必要がある&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;アカウンタビリティ&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;AI システムにはアカウンタビリティが必要である&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;参考: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;ja-jp&#x2F;azure&#x2F;cloud-adoption-framework&#x2F;innovate&#x2F;best-practices&#x2F;trusted-ai&quot;&gt;責任ある信頼された AI - Cloud Adoption Framework&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;詳細は上記参考ドキュメントを読むとわかりやすいです．これらを定義し，それをどのように実践するかといったことについても公式ドキュメントとしてまとめられていて素晴らしいです．信頼性と安全性は MLOps とも関連性が高い項目です．&lt;&#x2F;p&gt;
&lt;p&gt;本書では，取り組みの紹介として，コンテンツフィルタリングの例があります．生成 AI が不正利用されるとサービスに大きな影響が及びます．これに対して，Azure OpenAI では入出力にフィルタリング機能が実装されていて，適切でない内容対しては処理がストップされるようになっています．こういったことをマネージドサービスとして提供してくれるのかと感心したと同時に，サービスを使う側にとって安心で心強いと感じました．仮にこういったことを自前で実装するとなると，かなりしんどくて（どういった項目を扱うか，実装や運用はどうするかなど），素早くサービスを展開しづらくなります．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;qi-ninatutadian&quot;&gt;気になった点&lt;&#x2F;h3&gt;
&lt;p&gt;気になった点を強いて言うなら，LLM 開発する上で有用な Microsoft 製の OSS がいくつか紹介されていて，それについて付録などでもう少し使い方や組み合わせ方があっても面白いかなと思いました．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回献本いただいて書籍を読むまで Azure, Azure OpenAI Service のことはほぼ知りませんでした🙇‍♂️&lt;&#x2F;p&gt;
&lt;p&gt;ただ本書を読んでいくことで，Azure OpenAI Service の使い勝手の良さや導入のしやすさなどはとても感じることができました！興味深かった点&#x2F;印象に残った点でも書きましたが，Azure Machine Learning プロンプトフローを使った開発は非常に開発者体験が良さそうに感じるため，これを機に是非触ってみたいと感じさせられるものでした💪（まだ時間が取れず，実際には触れていないのですが...）&lt;&#x2F;p&gt;
&lt;p&gt;他にも Microsoft の OSS が所々で紹介されていて知らないものも多かったので，参考になりました！&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;microsoft&#x2F;DeepSpeed&quot;&gt;DeepSpeed&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Deep Learning モデルの学習・推論を高速化するフレームワーク&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;microsoft&#x2F;semantic-kernel&quot;&gt;Semantic Kernel&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;LLM を自分のアプリに簡単に統合できる SDK&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Azure を既に使っている人はもちろんのこと，使ったことが無い人も本書を通して Azure OpenAI Service を使った ChatGPT&#x2F;LLM のシステム開発に挑戦してみると楽しいと思います！&lt;&#x2F;p&gt;
&lt;p&gt;もしこれらに興味がある人は是非手に取って見てください！！&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>2023年の振り返り🚀</title>
        <published>2023-12-31T00:00:00+00:00</published>
        <updated>2023-12-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/look-back-on-this-year-2023/"/>
        <id>https://masatakashiwagi.com/blog/look-back-on-this-year-2023/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/look-back-on-this-year-2023/">&lt;p&gt;1年早いもので今年も今日で終わります．今年は4月に3回目の転職をしたり，子供が1歳になって外出したりする機会が増えたりして楽しい1年になりました☺️&lt;&#x2F;p&gt;
&lt;h2 id=&quot;shi-shi-bian&quot;&gt;仕事編&lt;&#x2F;h2&gt;
&lt;p&gt;4月に転職して，今まで以上にチャレンジングな1年で，1人目の機械学習（ML）エンジニアとして，プロダクトや組織に ML をインストールしてプレゼンスをあげることに力を入れた年でした．&lt;&#x2F;p&gt;
&lt;p&gt;何も無いところから全てを作り上げて行くことは結構大変で，仲間も居ない状況だと，相談する人もおらず自分の取り組みが間違っていないかなど疑心暗鬼になったりもしました．プロダクトに ML として何を提供するか，そしてそれは何故かをきちんと定義し，プロダクトオーナー・プロダクトマネージャーと協議することを丁寧に行うことを心掛けました．&lt;&#x2F;p&gt;
&lt;p&gt;また，今のフェーズで会社としてチームとして ML がすべきことを意識してプロジェクトを進めていました．例えば，ML がコストセンターであることを理解し，技術選定において必要以上のことをしない，手に余るサービスや技術を使用しないなどは常に念頭において動きました．&lt;&#x2F;p&gt;
&lt;p&gt;来年は引き続き種蒔きをしつつ，チャレンジしていくべきところは大胆に動いて継続的な価値を提供していきたいと思います！&lt;&#x2F;p&gt;
&lt;p&gt;あと，個人的には「&lt;strong&gt;選択と集中&lt;&#x2F;strong&gt;」&#x2F;「&lt;strong&gt;意思決定&lt;&#x2F;strong&gt;」というワードを意識して個人アップデートを試みた年でした．特に1人しか居ない状況で，より限られた時間の中で成果を出す，サービスを提供することを考えると，今何をすべきか何をすべきでないかを整理し，その中で優先順位を決めて最終的な意思決定をする機会が多く，「選択と集中」&#x2F;「意思決定」辺りの力は鍛えられた1年だったかなと思います．&lt;&#x2F;p&gt;
&lt;p&gt;自分は役割を明確にする方が力を発揮するタイプなので，プロダクトにおける ML の機能に対する責任を自分自身が負うことでより責任感が生まれたと感じます．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;puraibetobian&quot;&gt;プライベート編&lt;&#x2F;h2&gt;
&lt;p&gt;今年の初めに書いたブログ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masatakashiwagi.com&#x2F;posts&#x2F;personal-goals-for-2023&quot;&gt;2023年の個人目標を立てた&lt;&#x2F;a&gt; を見てみると，全然達成していません笑&lt;&#x2F;p&gt;
&lt;p&gt;X (旧 Twitter) のフォロワーが&lt;strong&gt;1136人&lt;&#x2F;strong&gt;で1000人を超えたのと，家族と毎月記念になる遊びや行事をすることは達成できたかなと...&lt;&#x2F;p&gt;
&lt;p&gt;冒頭にも書きましたが，子供が1歳になって徐々に遠出も含めて外出することが増えた1年でした．東京以外で泊まりで出かけた所をあげてみると，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ディズニーランド&amp;amp;シー&lt;&#x2F;li&gt;
&lt;li&gt;大阪の実家帰省&lt;&#x2F;li&gt;
&lt;li&gt;沖縄旅行（おばあに会いに）&lt;&#x2F;li&gt;
&lt;li&gt;和歌山白浜旅行（実家帰省のついで）&lt;&#x2F;li&gt;
&lt;li&gt;淡路島旅行（実家帰省のついで）&lt;&#x2F;li&gt;
&lt;li&gt;千葉ゾウの国旅行&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;これに加えて近場での公園や動物園なども行けてとても楽しい思い出を作ることができました！来年も引き続き，毎月何かしらの記念になる遊びや行事をしていきたいと思います🎉&lt;&#x2F;p&gt;
&lt;p&gt;あとは，Podcast も継続して1年間実施することが出来たり，12月には近くのジムを契約して筋トレや有酸素運動を週に2~3回ぐらい始められています！（続けて行きたい...😅）&lt;&#x2F;p&gt;
&lt;p&gt;MLOps 勉強会の運営も1年間継続することが出来て，去年よりも多くの人と知り合える機会が増えたり，運営を通して僕のことを認知してくれてる人が増えて嬉しい限りです🙏&lt;&#x2F;p&gt;
&lt;p&gt;個人的な取り組みとして10月ぐらいから月に1回フォロワーさんと飲みに行く会を実施していて，今年は2回実施できました！！ここ数年はコロナ禍で飲み会に行くことが難しく，その間に X で知り合った方も多かったので，実際に飲みに行ってお話したいとずっと思っていました．特に1人 MLE をやっていると，他社さんはどういったことをしているのか，めっちゃ知りたかったりするので，そういった動機もあります☺️&lt;&#x2F;p&gt;
&lt;p&gt;来年も継続して1ヶ月か2ヶ月に1度の頻度で開催したいと考えていて，突然 DM させて貰うかタイムラインで募集するかもしれませんので，その時はよろしくお願いします🙇‍♂️&lt;&#x2F;p&gt;
&lt;p&gt;書籍をいっぱい読んだり，ブログをいっぱい書いたり，登壇をいっぱいしたりなどやりたいことは山ほどありますが，健康第一で無理せず焦らず1つ1つ積み重ねて行きたいと思います👍&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;来年は仕事面では，チームをより大きくしつつ，AI&#x2F;ML の価値をプロダクトに載せてより多くのユーザーに届けたいと思います．また，登壇やテックブログなどを通してプロダクトでの AI&#x2F;ML の取り組みを外部に発信し，コミュニティへの還元や多くの人に会社やプロダクトを知ってもらう機会を増やしていきたいと思います！&lt;&#x2F;p&gt;
&lt;p&gt;プライベートでは，&lt;strong&gt;家族を第一優先&lt;&#x2F;strong&gt;で引き続き思い出を作って行きます！あとは&lt;strong&gt;人と会う&lt;&#x2F;strong&gt;機会を今年以上に作ろうと考えていたり，引き続き MLOps の啓蒙というか取り組みも続けて行きたいと思います．&lt;&#x2F;p&gt;
&lt;p&gt;良いお年をお迎えください！&lt;br&#x2F;&gt;
Have a happy new year!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>機械学習パイプラインの作り方を改めて考えてみる</title>
        <published>2023-12-15T00:00:00+00:00</published>
        <updated>2023-12-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/how-to-recreate-ml-pipeline/"/>
        <id>https://masatakashiwagi.com/blog/how-to-recreate-ml-pipeline/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/how-to-recreate-ml-pipeline/">&lt;p&gt;もう今年もあと数週間ということで，1年があっという間に終わってしまいますね😅&lt;&#x2F;p&gt;
&lt;p&gt;この記事は &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;qiita.com&#x2F;advent-calendar&#x2F;2023&#x2F;mlops&quot;&gt;MLOps Advent Calendar 2023&lt;&#x2F;a&gt; の15日目の記事になります！アドベントカレンダーの日付を選ぶ際についつい自分の好きな数字を選びがちですが，皆さんはどうですか？笑&lt;&#x2F;p&gt;
&lt;p&gt;最近，機械学習（ML）パイプラインの良い構成やパイプラインとコンポーネントの良い組み方に興味があり，それをどう管理するかのディレクトリ構成などを考えたりしていますが，きっかけとしては参考にも載せている「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.hopsworks.ai&#x2F;post&#x2F;mlops-to-ml-systems-with-fti-pipelines&quot;&gt;From MLOps to ML Systems with Feature&#x2F;Training&#x2F;Inference Pipelines&lt;&#x2F;a&gt;」という Hopsworks の CEO である Jim Dowling さんが書いた記事を以前読んでとても共感したことにあります．&lt;&#x2F;p&gt;
&lt;p&gt;また，AB テストなどのオンライン検証を見据えた時に，どういったディレクトリ構成だとスムーズに開発ができたり，実施までの工程を減らして素早くデプロイし，検証できるかも考えることが多々あり，良い方法を模索しているのもあります．この記事では，その辺りの自分が今考えている内容について紹介しようと思います！技術検証系の記事ではなく，考え方の一例を紹介する形になります．&lt;&#x2F;p&gt;
&lt;p&gt;僕の中の現時点の結論では，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;コンポーネント単位ではなく，パイプライン単位で管理し，パイプラインは程よくモジュール化する&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;です．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;paipurain-chu-li-dan-wei-defen-keraretakonponentodegou-cheng&quot;&gt;パイプライン: 処理単位で分けられたコンポーネントで構成&lt;&#x2F;h2&gt;
&lt;p&gt;ML パイプラインを組み立てる時，大抵の場合は処理単位で分けられたコンポーネントを用意し，それを有向グラフで繋げてパイプラインを構成することが多いかと思います．下図は学習パイプラインや推論パイプラインの例を書いています．パイプラインの中には，ストレージやデータベースからデータを抽出する処理だったり，推論や予測結果をデータベースに保存する処理が加わるかもしれないです．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;how_to_recreate_ml_pipeline&#x2F;pipeline-img1.png&quot; alt=&quot;Pipeline&quot; title=&quot;Pipeline&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;処理をコンポーネントもしくはモジュールというかもしれないが，それ毎に分けて I&#x2F;O を定義し，管理することはとても良いことです．疎結合になっていることで，処理の入れ替えなどが容易でメンテナンスもしやすくなります．&lt;&#x2F;p&gt;
&lt;p&gt;一方で，こんな疑問や悩みを持ったりもしています．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;どこまで細かくコンポーネントに分けて使うのが良いか？
&lt;ul&gt;
&lt;li&gt;どの程度，共通化や汎用化を考えるのが良いか&lt;&#x2F;li&gt;
&lt;li&gt;過度なコンポーネント化は逆に管理しづらくなる？&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;チーム開発を考えた場合にコンポーネント単位での分割は効率的なのか？&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;li&gt;
&lt;li&gt;バッチ&#x2F;リアルタイムの両方を満たすことを考えるとどうだろうか？&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;（共通化や汎用化を行い再利用することを意識して設計開発することはとても大事です．一方で，最初からそれを意識しすぎると中途半端なものができたりして，逆に使いづらいことが過去の経験としてあるので，何度か使われる内に共通化を進めて行く方がユースケースに合ったものが出来て良いかなと最近は思っています．）&lt;&#x2F;p&gt;
&lt;p&gt;コンポーネント単位での接続では，インターフェイスがコンポーネント間でのやり取りになり，先行するコンポーネントの出力結果に応じて後続のコンポーネントに微調整が入ることもあります．例えば，AB テストをするのに，ちょこっとだけ先行のコンポーネントを変えたことで，後続のコンポーネントにも修正が入り，それが元で既存のパイプラインに影響が出たりして厄介だなと感じたことがあります．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;feature-training-inference-pipelines-toha&quot;&gt;Feature&#x2F;Training&#x2F;Inference Pipelines とは？&lt;&#x2F;h2&gt;
&lt;p&gt;冒頭紹介したブログでは，&lt;strong&gt;Feature&#x2F;Training&#x2F;Inference (FTI) Pipelines&lt;&#x2F;strong&gt; というものを紹介しています．これは独立した3つのパイプラインから構成されていて，それぞれが独立して開発や運用ができる点が良く，役割もパイプライン毎に明確になっています．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;how_to_recreate_ml_pipeline&#x2F;pipeline-img2.png&quot; alt=&quot;Pipeline&quot; title=&quot;Pipeline&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;記事では，バッチ&#x2F;リアルタイムの ML システムの例を紹介した後に，その両方に対応した &lt;strong&gt;Unified Architecture for ML Systems&lt;&#x2F;strong&gt; として紹介されています．&lt;&#x2F;p&gt;
&lt;p&gt;それぞれのパイプライン間のインターフェースがこの例だと，Feature Store&#x2F;Model Registry になっています．これは彼らの製品である Feature Store を上手く活用する仕組みになっていて，なかなか考えられているなと感じました．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sorezorenopaipurainnoyi-ge-hadounatuteiruka&quot;&gt;それぞれのパイプラインの役割はどうなっているか&lt;&#x2F;h3&gt;
&lt;p&gt;役割は以下のように説明されています．&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;a feature pipeline that takes as input raw data that it transforms into features (and labels)&lt;&#x2F;li&gt;
&lt;li&gt;a training pipeline that takes as input features (and labels) and outputs a trained model&lt;&#x2F;li&gt;
&lt;li&gt;an inference pipeline that takes new feature data and a trained model and makes predictions.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;feature pipeline: 生データを入力として受け取り，特徴量（とラベル）に変換する&lt;&#x2F;li&gt;
&lt;li&gt;training pipeline: （feature pipeline で生成された）特徴量（とラベル）を入力として受け取り，学習済みモデルを出力する&lt;&#x2F;li&gt;
&lt;li&gt;inference pipeline: （feature pipeline で生成された）新しい特徴量と学習済みモデルを受け取り，予測を返す&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;例えば，レコメンドシステムのバッチ推論で良くあるパターンだと，下図&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;のように feature pipeline, training pipeline, inference pipeline を3つ繋げて（上側の点線）最終的に結果をストレージやデータベースに保存しておくという流れです．&lt;&#x2F;p&gt;
&lt;p&gt;また，リアルタイムレコメンドのパターンだと，feature pipeline, inference pipeline の2つが繋がり（下側の点線）結果をアプリケーションに返す流れになります．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;how_to_recreate_ml_pipeline&#x2F;pipeline-img3.png&quot; alt=&quot;Pipeline&quot; title=&quot;Pipeline&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;パイプラインは適度にコンポーネント化されていて，それぞれのステージで明確なインターフェースを持っています．個々のパイプライン内でさらにコンポーネント化されていても良いですが，あくまでパイプライン間での関係を見るので，内部は柔軟になっていて良いと思います．&lt;&#x2F;p&gt;
&lt;p&gt;特に ML パイプラインはスクラップ &amp;amp; ビルドされることも多いので，そこまで内部をコンポーネントに分けても恩恵が無いかもしれないです．むしろ，チームで1つのパイプラインを開発するケースでは，これぐらいの粒度の方が開発効率が良いのではないかなと思います．&lt;&#x2F;p&gt;
&lt;p&gt;ありがちなモノリシックなバッチパイプライン（下図&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;）よりは遥かに使いやすく，リアルタイムへの移行もスムーズになり，開発スピードは上がるはず．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;how_to_recreate_ml_pipeline&#x2F;pipeline-img4.png&quot; alt=&quot;Pipeline&quot; title=&quot;Pipeline&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;paipurainjian-nointahuesu&quot;&gt;パイプライン間のインターフェース&lt;&#x2F;h3&gt;
&lt;p&gt;Feature&#x2F;Training&#x2F;Inference (FTI) Pipelines の考え方の場合，各パイプライン間のインターフェースはデータに関しては，Feature Store や Object Storage (S3, GCS ...etc) などになるかと思います．&lt;&#x2F;p&gt;
&lt;p&gt;僕はマネージドサービスでパイプラインを組むことが多いですが，AWS と GCP だと以下のような感じでできるのではないでしょうか．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;AWS:
&lt;ul&gt;
&lt;li&gt;パイプライン: SageMaker + Step Functions (or SageMaker Pipelines)&lt;&#x2F;li&gt;
&lt;li&gt;構造: Step Functions では，ステートマシン同士の接続が可能なので，パイプライン同士の接続は容易にできる&lt;&#x2F;li&gt;
&lt;li&gt;パイプライン間のインターフェース: S3，Amazon SageMaker Feature Store&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;GCP:
&lt;ul&gt;
&lt;li&gt;パイプライン: Vertex AI Pipelines&lt;&#x2F;li&gt;
&lt;li&gt;構造: コンポーネント同士はオブジェクトで繋がる仕組み．Step Functions のようにパイプライン同士の接続ができるかは把握できていない&lt;&#x2F;li&gt;
&lt;li&gt;パイプライン間のインターフェース: GCS，Vertex AI Feature Store&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;fti-pipelines-deyi-wen-yanao-mihajie-xiao-surunoka&quot;&gt;FTI Pipelines で疑問や悩みは解消するのか&lt;&#x2F;h2&gt;
&lt;p&gt;最初に挙げていたいくつかの疑問や悩みについて，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;どこまで細かくコンポーネントに分けて使うのが良いか？
&lt;ul&gt;
&lt;li&gt;→ &lt;strong&gt;より少ない単位（パイプライン単位）で管理可能&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;チーム開発を考えた場合にコンポーネント単位での分割は効率的なのか？
&lt;ul&gt;
&lt;li&gt;→ &lt;strong&gt;パイプライン単位で分割することである程度は効率的に開発できそう&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;バッチ&#x2F;リアルタイムの両方を満たすことを考えるとどうだろうか？
&lt;ul&gt;
&lt;li&gt;→ &lt;strong&gt;バッチからリアルタイムへの移行などもパイプライン単位ならしやすい&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;バッチ&#x2F;リアルタイムのアーキテクチャどうするか問題は，Lambda&#x2F;Kappa Architecture の話などもあるので，またどこかでブログにまとめたいです&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;また，AB テストを実施する場合は，パイプラインを AB テスト用にもう1セット準備することで比較的容易に対応できるのではないでしょうか．最後にディレクトリ構成をどんな感じにするのが良いか紹介しようと思いましたが，まだ整理できていないのですいません🙏&lt;&#x2F;p&gt;
&lt;p&gt;LayerX さんのこちらの記事&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#5&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;で紹介されているモノレポの構成は参考になるところが多いです．&lt;&#x2F;p&gt;
&lt;p&gt;あとは，パイプラインでまとめている今回の構成において，エラーが発生した場合のリカバリー方法やエラー箇所の特定をどうするかについてはまた別途考える必要があると感じています．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回紹介した内容がどのような場合でも上手く機能するかは正直わからないですが，こういった選択肢もあるという形で見て頂ければと思います．チーム規模や体制次第ではワークするかもしれないですが，より大きな規模になると別かもしれないです．僕も1年後には別の方法が良いかもなと感じているかもしれないので，またその時に良い方法を模索して考えたいです．&lt;&#x2F;p&gt;
&lt;p&gt;もし他にもこういった考え方や構成が良いよなどあったら，是非聞かせて下さい🙏&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.hopsworks.ai&#x2F;post&#x2F;mlops-to-ml-systems-with-fti-pipelines&quot;&gt;From MLOps to ML Systems with Feature&#x2F;Training&#x2F;Inference Pipelines&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;チームで分担した場合には分担の仕方にもよるが，例えば，前後のコンポーネントの用意が遅れたりして，なかなかパイプラインを動かせないなどもありうる&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;バッチの場合，一度に大量のデータを処理することを想定するが，リアルタイムの場合，ストリーミングデータを想定するので，入口の扱いが異なるが処理は一貫したものにすべき&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;3&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;3&lt;&#x2F;sup&gt;
&lt;p&gt;(From MLOps to ML Systems with Feature&#x2F;Training&#x2F;Inference Pipelines) Figure 11: The Feature&#x2F;Training&#x2F;Inference (FTI) pipelines Mental Map for building ML Systems&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;4&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;4&lt;&#x2F;sup&gt;
&lt;p&gt;(From MLOps to ML Systems with Feature&#x2F;Training&#x2F;Inference Pipelines) Figure 4: A monolithic batch ML system that can run in either (1) training mode or (2) inference mode.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;5&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;5&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tech.layerx.co.jp&#x2F;entry&#x2F;2023&#x2F;11&#x2F;16&#x2F;185944#%E5%AE%9F%E9%9A%9B%E3%81%AE%E9%81%8B%E7%94%A8%E6%96%B9%E9%87%9D&quot;&gt;Vertex AI Pipelinesを用いて爆速ML開発の仕組みを構築する - 実際の運用方針&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>良い天気だったので多摩動物公園へ🐯</title>
        <published>2023-11-23T00:00:00+00:00</published>
        <updated>2023-11-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/stroll-to-tama-zoological-park/"/>
        <id>https://masatakashiwagi.com/blog/stroll-to-tama-zoological-park/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/stroll-to-tama-zoological-park/">&lt;p&gt;11月19日に秋晴れでとても良い天気でしたので，家族で「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.tokyo-zoo.net&#x2F;zoo&#x2F;tama&#x2F;&quot;&gt;&lt;strong&gt;多摩動物公園&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;」に行ってきました！車で行きましたが，京王線の多摩モノレールの多摩動物公園駅で降りてすぐのところにありますので，比較的行きやすい動物公園です！&lt;&#x2F;p&gt;
&lt;p&gt;車は周辺にパーキングがたくさんありますので，大体1000~1500円ぐらいで駐車することができます．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;tama_zoological_park&#x2F;zoo1.jpg&quot; alt=&quot;動物公園1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ban-gaduo-idong-wu-gong-yuan&quot;&gt;坂が多い動物公園&lt;&#x2F;h2&gt;
&lt;p&gt;日野市の山間にありますので，園内は結構坂が多めで，普段運動不足の身としては足が痛くなりました😅&lt;&#x2F;p&gt;
&lt;p&gt;序盤は子供も歩いてくれましたが，途中から抱っこが始まったので，グスケットを持ってきておいて良かったです（ベビーカーも持って来ていましたが，園内でも借りられるみたいでした）．&lt;&#x2F;p&gt;
&lt;p&gt;子供は以前に市原ぞうの国で象を見たのを覚えていたのか，見るととても興奮していました．子供の反応を見ると面白くて和みますね☺️&lt;&#x2F;p&gt;
&lt;p&gt;個人的に一畫の発見は，&lt;strong&gt;四不像&lt;&#x2F;strong&gt;（しふぞう）という動物（下の写真）が飼育されていて，蹄はウシ・頭はウマ・角はシカ・体はロバに似ているというキメラみたいな動物を初めて知りました！野生のものは絶滅していて，動物園で飼育されているものしか存在していないそうです．&lt;&#x2F;p&gt;
&lt;p&gt;参考：&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.tokyo-zoo.net&#x2F;encyclopedia&#x2F;species_detail?code=43&quot;&gt;どうぶつ図鑑 - シフゾウ&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;tama_zoological_park&#x2F;zoo2.jpg&quot; alt=&quot;動物公園2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;まだまだ自分が知らない・聞いたことのない動物が動物園にもいるので，こういった発見は面白いです！&lt;&#x2F;p&gt;
&lt;p&gt;トラは昼寝していたり，キリンはかなり近くで見ることができ &amp;amp; 数も多くて迫力がありました！宿舎も綺麗になったみたいで快適そうに過ごしていました笑&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;tama_zoological_park&#x2F;zoo3.jpg&quot; alt=&quot;動物公園3&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;tama_zoological_park&#x2F;zoo4.jpg&quot; alt=&quot;動物公園4&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;あと見れて良かったのはサイで，勇ましく立っていて，ポケモンのサイホーンそのものでした笑&lt;&#x2F;p&gt;
&lt;p&gt;しっかり観察したのは初めてかもしれませんが，サイの身体（皮膚？）はまさに鎧みたいで，ゴツゴツしくてどういった過程であの姿になったのか気になりました．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;tama_zoological_park&#x2F;zoo5.jpg&quot; alt=&quot;動物公園5&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;全体的に楽しめましたが，所々檻はあるけれど動物がいなかったりして，維持費や繁殖なども大変なんだろうなと感じました．一方で，宿舎を新しく建設予定の動物もあったので，四季の変わった頃に訪れて，また変化を楽しみたいと思います．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;少し朝は遅めの11時ぐらいに到着して，大体15時半ぐらいまで楽しみました！冬は16時近くなると日も翳ってきて暗く寒くなりますので，15時ぐらいまでがちょうど良いかなと感じました．暗くなると動物も見れなくなったり，室内に入ってしまうので，早めが良いかもしれません！&lt;&#x2F;p&gt;
&lt;p&gt;自然豊かで上の方には芝生のエリアもありますので，今度はピクニックをしに来ても楽しいかもしれません．&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>去年と同じ時期に沖縄旅行へ！🌺</title>
        <published>2023-11-18T00:00:00+00:00</published>
        <updated>2023-11-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/travel-to-okinawa-2023/"/>
        <id>https://masatakashiwagi.com/blog/travel-to-okinawa-2023/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/travel-to-okinawa-2023/">&lt;p&gt;ちょうど1年ぶりに11月10~13日の間で沖縄に旅行へ行ってきました！今回は妻の両親&amp;amp;弟家族と共に沖縄のおばあへ会いに行きました．&lt;&#x2F;p&gt;
&lt;p&gt;人数が多いので，スケジュール通りの移動が大変でしたが，楽しい旅行になりました！やっぱり沖縄は暖かくて良いです😉&lt;&#x2F;p&gt;
&lt;p&gt;ちなみに今回の日記は写真多めです．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bian-nahoteruniqian-bo&quot;&gt;変なホテルに前泊&lt;&#x2F;h2&gt;
&lt;p&gt;今回は朝8時の羽田発の飛行機でしたので，空港近くのホテルに前泊して行くことにしました．何気に前泊は初めてな気がします．&lt;&#x2F;p&gt;
&lt;p&gt;泊まったのが「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.hennnahotel.com&#x2F;haneda&#x2F;&quot;&gt;変なホテル&lt;&#x2F;a&gt;」というホテルでした笑&lt;&#x2F;p&gt;
&lt;p&gt;名前から変わっていますが，大鳥居駅から10分ぐらいのところにあって空港への利便性が良く値段も1万円（大人2名，子供1名）程度でした．ホテルが無人（実際は，裏側に待機しているスタッフはいます）で，ロビーの写真を貼っておきますが，ロボットのお姉さんと何故か恐竜がいました笑&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;hotel1.jpg&quot; alt=&quot;変なホテルのロビー&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;この受付が話題で面白そうでしたので泊まってみましたが，まー普通のホテルでした．強いて言うなら，外国の方が多く泊まっている感じでした．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;chong-nawa-1ri-mu-dong-jing-chong-nawa-ming-hu-ben-bu&quot;&gt;沖縄1日目（東京→沖縄:名護&amp;amp;本部）&lt;&#x2F;h2&gt;
&lt;p&gt;去年ぶりに見ためんそーれが出迎えてくれました！飛行機の到着出口のここで毎回写真を撮ってしまいます笑&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;okinawa1.jpg&quot; alt=&quot;めんそーれ&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;1日目は名護の方まで移動してそこで1泊しました！名護の方に妻のおばあの家がありますので，会うためにそこまで移動して徐々に南下するのが沖縄旅行の王道になっている気がします．&lt;&#x2F;p&gt;
&lt;p&gt;名護へ行くまでの道中，去年は食べられなかった浦添市にある &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tabelog.com&#x2F;okinawa&#x2F;A4703&#x2F;A470404&#x2F;47000071&#x2F;&quot;&gt;&lt;strong&gt;高江洲そば&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; で沖縄そばを食べました！ここは &lt;strong&gt;ゆし豆腐そば&lt;&#x2F;strong&gt; が有名で検索したら上位に出てきます！（僕は普通の沖縄そばにしましたが笑，妻はゆし豆腐そばを食べていました）写真は沖縄そばです．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;soba1.jpg&quot; alt=&quot;高江洲そば&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;soba2.jpg&quot; alt=&quot;高江洲そば&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;お昼ご飯を食べた後は，僕たちの家族は去年美ら海水族館に行ったので，今年は &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nagopine.com&#x2F;index.html&quot;&gt;&lt;strong&gt;ナゴパイナップルパーク&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; へ行くことにしました！途中高速の最終地点を降りたら見えてくる &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.yanbaru-b.co.jp&#x2F;&quot;&gt;&lt;strong&gt;道の駅許田&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; で入園チケットを買いました．ここは美ら海水族館などのチケットが最安値で買うことができますので，オススメです！ナゴパイナップルパークのチケットも買うことができます（1200円&#x2F;人ぐらいだったと思います）．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;okinawa2.jpg&quot; alt=&quot;道の駅許田&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;天ぷらやおっぱアイスとかの食べ物もあるし，お土産も買えるので，途中に寄り道すると楽しいと思います！いつもここに立ち寄って何かつまみ食いしている気がします笑&lt;&#x2F;p&gt;
&lt;p&gt;目的地のナゴパイナップルパークは写真のような感じの場所でした．最初はあまり期待していませんでしたが，意外と楽しめました🍍&lt;&#x2F;p&gt;
&lt;p&gt;敢えてどんな感じでしたかは触れませんので，気になる人は是非行って確かめて欲しいです！（別にマイナスの意味ではなく普通に楽しめます☺️）園内を回った後は割り箸に刺さったパイナップルを食べたり，ワイナリーがあってワインの試飲もしました．オリジナルのワインもあったりしますので，ワイン好きの人も是非行ってみて欲しいです！&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;nago1.jpg&quot; alt=&quot;ナゴパイナップルパーク1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;nago2.jpg&quot; alt=&quot;ナゴパイナップルパーク2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;一番の思い出は，園内でひたすら流れてる「パッパ パイナップル」．脳内で無限再生されるので，中毒性がやばい笑&lt;&#x2F;p&gt;
&lt;iframe style=&quot;width:100%;height:auto;aspect-ratio:16&#x2F;9;&quot; src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;KmvmBokC39I?si=T7OdgGxyIdS4th__&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;見学が終わった後は1日目の宿泊先である「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.mahaina.co.jp&#x2F;&quot;&gt;&lt;strong&gt;ホテルマハイナ ウェルネスリゾートオキナワ&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;」に行って，夕食のバイキングを食べたりしてのんびり過ごしました．以前も泊まったことがあるホテルで，ホテルの真ん中にでかいプールがあって夏場は泳ぐこともできます．部屋は和洋室もあり，小さい子供連れにはありがたいです．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;okinawa3.jpg&quot; alt=&quot;BLUESEALBUS&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;ホテルの横に&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hanasaki-marche.com&#x2F;&quot;&gt;ハナサキマルシェ&lt;&#x2F;a&gt;というのがあって，そこにオシャレな BLUE SEAL のバスが停まってたので，パシャリしました🍨（ちなみに，スタバやゴンチャもある！）&lt;&#x2F;p&gt;
&lt;h2 id=&quot;chong-nawa-2ri-mu-bei-gu&quot;&gt;沖縄2日目（北谷）&lt;&#x2F;h2&gt;
&lt;p&gt;2日目は，朝におばあの家に寄ってみんなで顔を見せてきました！娘っちは相変わらず抱っこされるとギャン泣きしてました笑（いつになったら慣れてくれるのだろうか...😅）最近は徐々に人見知りをするようになってきたので，見慣れない人がおるなーという感じなのかなと思ったり．&lt;&#x2F;p&gt;
&lt;p&gt;その後は，お昼頃にライカム（イオンモール）にあるポケモンセンターオキナワに行って，子供が最近ハマってるポッチャマのぬいぐるみを買ったのですが，ポッチャマのぬいぐるみを見つけた時の興奮具合が凄かったです笑（ナゴパイナップルパークでもパイナップルのぬいぐるみを買ったので，ぬいぐるみが家の中に溢れかえってる☺️）&lt;&#x2F;p&gt;
&lt;p&gt;そんなこんなでいい時間になったので，2日目のホテルがある北谷まで行くと，ちょうど花火の時間で5分ぐらい音だけ聞けました😅（土日は結構花火が上がってるみたい）&lt;&#x2F;p&gt;
&lt;p&gt;北谷のこの時期は既にクリスマス雰囲気が出ていて，建物の装飾がとても綺麗で夜はライトアップもされるので，オススメです！あと，北谷にはポケモンスポットがあるので，行った際は色んなポケモンを見つけてみると良いかも！&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;chatan1.jpg&quot; alt=&quot;北谷1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;夜は，義父の知り合いがやってる&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tabelog.com&#x2F;okinawa&#x2F;A4703&#x2F;A470304&#x2F;47000420&#x2F;&quot;&gt;和和&lt;&#x2F;a&gt;という居酒屋でご飯を食べました．定番のゴーヤーチャンプルーも美味しかったですが，魚が刺身味含めて最高でした🎉&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;chatan2.jpg&quot; alt=&quot;北谷2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;chatan3.jpg&quot; alt=&quot;北谷3&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;北谷に来るとホテルは大体「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.vessel-hotel.jp&#x2F;campana&#x2F;okinawa&#x2F;&quot;&gt;&lt;strong&gt;ベッセルホテルカンパーナ沖縄&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;」に泊まってます．ここの朝食バイキングが個人的に美味しくて好きで，ブルーシールのアイスクリームも5種類ぐらいあって良きです！ホテルで言うと，近くにヒルトンホテルもあるので，一度はそこにも泊まってみたいなと思ったりもしてます．いっぱい稼げるように頑張るぞい😉&lt;&#x2F;p&gt;
&lt;h2 id=&quot;chong-nawa-3ri-mu-na-ba&quot;&gt;沖縄3日目（那覇）&lt;&#x2F;h2&gt;
&lt;p&gt;3日目は，リクエストを聞いてもらい宜野湾にある僕が好きなタコス屋である「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tabelog.com&#x2F;okinawa&#x2F;A4703&#x2F;A470404&#x2F;47000173&#x2F;&quot;&gt;&lt;strong&gt;メキシコ&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;」に朝から行きました！3つ食べたが，ペロッといけるのでもっと注文して食べても良かったです😊&lt;&#x2F;p&gt;
&lt;p&gt;ここのタコスは絶品なので，是非食べて欲しい！&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;tacos1.jpg&quot; alt=&quot;メキシコ1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;tacos2.jpg&quot; alt=&quot;メキシコ2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;タコスを食べ終えると，たまたま隣にあって目に入った「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tabelog.com&#x2F;okinawa&#x2F;A4703&#x2F;A470404&#x2F;47030143&#x2F;&quot;&gt;&lt;strong&gt;ふわこっぺ&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;」と言うコッペパン屋さんがとても美味しそうだったので，流れで入って買ってしまいました笑&lt;&#x2F;p&gt;
&lt;p&gt;ここはとにかく種類があるので，迷うと思う笑．僕はスタンダードなシュガーを頼んだが，他のも美味しそうでした！&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;koppepan1.jpg&quot; alt=&quot;ふわこっぺ&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;食べた後はさらに奥武島に行き，有名な天ぷらも食べました！ここは猫もいっぱい居て，猫を見ながら「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tabelog.com&#x2F;okinawa&#x2F;A4704&#x2F;A470403&#x2F;47009272&#x2F;&quot;&gt;&lt;strong&gt;大城てんぷら店&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;」と言うお店で，もずく天ぷらなどいくつか食べました！&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;okinawa4.jpg&quot; alt=&quot;天ぷら&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;時間もお昼過ぎになっていたので，最終宿泊地である那覇まで戻ってきました．沖縄に来るとおもろまちにある結婚指輪を作った場所に行って，指輪をメンテナンスするのが恒例になっているので，今回も磨いて貰いに行きました．偶然去年と同じ担当者の人だったので，1年ぶりに話も弾んで楽しかったです．また来年も来ようと思います！&lt;&#x2F;p&gt;
&lt;p&gt;最後の宿泊先は「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hyattregencynaha.jp&#x2F;&quot;&gt;&lt;strong&gt;ハイアット リージェンシー 那覇 沖縄&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;」でカクテルタイムを楽しんだりして，夜は国際通りで買い物などして終わりました！&lt;&#x2F;p&gt;
&lt;h2 id=&quot;chong-nawa-4ri-mu-chong-nawa-dong-jing&quot;&gt;沖縄4日目（沖縄→東京）&lt;&#x2F;h2&gt;
&lt;p&gt;4日目は最終日で，昼過ぎの飛行機だったので，朝の空き時間に新しくなった「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.makishi-public-market.jp&#x2F;&quot;&gt;&lt;strong&gt;那覇市第一牧志公設市場&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;」に行きました．色んなものが売っていて見学するだけでも面白いです．2階は食堂もあるので，沖縄そばとかも食べることができるます！&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;naha1.jpg&quot; alt=&quot;牧志公設市場&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回の沖縄旅行は総じて天気があまり良くありませんでした😭&lt;&#x2F;p&gt;
&lt;p&gt;でしたが，ナゴパイナップルパークとか行ったことのない場所にも行けて楽しかったのと，大勢での家族旅行もにぎやかで良かったです．次回は海に入れる季節に来ようと思います！笑&lt;&#x2F;p&gt;
&lt;p&gt;P.S. 那覇空港で帰りに A&amp;amp;W のハンバーガーを食べようとしたら激混みだったので，食べられずで残念でした...食べたい人は路面店などで食べておくことを強くオススメします！！&lt;&#x2F;p&gt;
&lt;p&gt;国際通りにあるウインディのマンホールも載せておきます．シーサーに似ているからかポケモンセンターオキナワにもウインディが出迎えてくれるので，興味がある方は行ってみ下さい．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;naha2.jpg&quot; alt=&quot;ウインディ&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;天気が終始芳しくなかったですが，飛行機の上空では，Bluesky でした！&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;okinawa&#x2F;sky1.jpg&quot; alt=&quot;Bluesky&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>MLOps 勉強会で2回目の登壇した感想</title>
        <published>2023-11-03T00:00:00+00:00</published>
        <updated>2023-11-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/speaking-at-the-mlops-study-2nd/"/>
        <id>https://masatakashiwagi.com/blog/speaking-at-the-mlops-study-2nd/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/speaking-at-the-mlops-study-2nd/">&lt;p&gt;10月31日に &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mlops.connpass.com&#x2F;event&#x2F;297976&#x2F;&quot;&gt;第35回の MLOps 勉強会&lt;&#x2F;a&gt;で久しぶりに登壇させて貰ったので，その感想です！&lt;&#x2F;p&gt;
&lt;p&gt;現職に転職してからは初めての登壇でしたが，実は今年で登壇は3回目です☺️&lt;&#x2F;p&gt;
&lt;p&gt;今回の登壇では，転職してから初めての仕事でプロダクトに初の機械学習によるレコメンド機能を導入した話をさせて貰いました！&lt;&#x2F;p&gt;
&lt;script defer class=&quot;speakerdeck-embed&quot; data-id=&quot;5a104d1912824f10b0d1e3d43391ecce&quot; data-ratio=&quot;1.7772511848341233&quot; src=&quot;&#x2F;&#x2F;speakerdeck.com&#x2F;assets&#x2F;embed.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;もう一人の登壇者は知り合いの &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;jy_msc&quot;&gt;@jy_msc&lt;&#x2F;a&gt; san (hakubishin3) だったので，あまり緊張せず楽しめたかなと思います．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;donoyounipu-duan-deng-tan-surunoka&quot;&gt;どのように普段登壇するのか&lt;&#x2F;h2&gt;
&lt;p&gt;登壇が決まる前に&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tech.commmune.jp&#x2F;entry&#x2F;2023&#x2F;09&#x2F;27&#x2F;173000&quot;&gt;こちらのテックブログ&lt;&#x2F;a&gt;を9月末に出していて，ちょうど10月の登壇者が一人まだ決まっていなかったので，空いてる枠に僕が登壇させて頂く流れになりました．&lt;&#x2F;p&gt;
&lt;p&gt;テックブログを書くとその内容で登壇できたり，登壇資料作成中もブログをベースに作ることができるので，1から作るよりかは圧倒的に早く作ることができるのを何回か経験していて，おすすめです．&lt;&#x2F;p&gt;
&lt;p&gt;ここで，僕の登壇する時の流れを簡単に紹介しておくと，&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;テックブログを書く&lt;&#x2F;li&gt;
&lt;li&gt;登壇申し込む&lt;&#x2F;li&gt;
&lt;li&gt;登壇資料を作る&lt;&#x2F;li&gt;
&lt;li&gt;登壇練習を行う&lt;&#x2F;li&gt;
&lt;li&gt;登壇する&lt;&#x2F;li&gt;
&lt;li&gt;感想を書く&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;大体こんな感じです．テックブログを書いて，登壇後の感想を書くまでが一連の流れです．&lt;&#x2F;p&gt;
&lt;p&gt;ネタの構想段階で登壇を申し込む人も居ますが，僕の場合はそれだと焦りがあったり&#x2F;仕事が立て込んで時間を確保できないとかが起きた場合に対応が大変なので，登壇依頼が無い限りは，テックブログなどでベースがある状態の時しか登壇の申し込みはしないようにしてます．そうすることで心理的なハードルを下げるようにしてます．&lt;&#x2F;p&gt;
&lt;p&gt;そこからはベースがあるので，資料作成も発表練習もそこまでの時間をかけなくても大枠は出来上がるので，あとは細かい部分を詰めていく感じで，最後に反省を書くというのも恒例にしてます☺️&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zao-kou-ninatutesimatutanohafan-sheng-dian&quot;&gt;早口になってしまったのは反省点&lt;&#x2F;h2&gt;
&lt;p&gt;今回の発表では，スライドを盛り盛りに作ってしまったので，時間が足りずに早口になったのは，今回の反省点でした．紹介したいことが多くて30分の発表時間で60枚ぐらいのスライドを作ってしまったので，もう少し絞るべきだったかなと思います...&lt;&#x2F;p&gt;
&lt;p&gt;僕のスライドは後で見返してもわかるような作りを意識しているので，文字数とかスライドが多くなる傾向があります．実際自分自身が一番自分の過去資料を見返して流用したり参考にしたりしているので，それはそれでいいかなという気持ちです（笑）&lt;&#x2F;p&gt;
&lt;p&gt;P.S. X (旧 Twitter) やアンケートで登壇内容に関してポジティブな感想（意思決定やアーキテクチャなど）を貰えて嬉しかったです！&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;久しぶりの登壇で今仕事で何をやってるのかを紹介できて，取り組みを知って貰えたかなと思います！マルチテナントでの機械学習の取り組み事例は，まだまだそこまで無いのと方法が確立しているわけではなさそうなので，これからも積極的に情報を出せるように頑張りたいと思います．&lt;&#x2F;p&gt;
&lt;p&gt;もし登壇依頼や相談があれば，気軽に X (旧 Twitter) の DM から連絡ください！&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>マットレスを最近買い替えて腰痛が緩和された🛏</title>
        <published>2023-10-09T00:00:00+00:00</published>
        <updated>2023-10-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/improved-back-pain-by-replacing-mattress/"/>
        <id>https://masatakashiwagi.com/blog/improved-back-pain-by-replacing-mattress/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/improved-back-pain-by-replacing-mattress/">&lt;p&gt;タイトルにもあるように最近夫婦でマットレスを買い替えて寝起きの腰痛が緩和された話です．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;qin-qi-kinoyao-tong&quot;&gt;寝起きの腰痛&lt;&#x2F;h2&gt;
&lt;p&gt;最近夫婦ともに寝起きの腰痛で悩んでいました．酷い時には起き上がれないぐらいで，朝起きると腰回りが凝り固まっていてかなり辛い状況でした．&lt;&#x2F;p&gt;
&lt;p&gt;マットレスは元々ニトリのものを使っていて，僕は5年ぐらい，妻は3年ぐらい買ってから経過していました．使っていて感じたのは，マットレスの上に立ったり寝てると少し沈みが深いかなという感覚で，こんなものかなと思っていましたが，長時間寝てると明らかに腰に負担が掛かってる感覚があったので，良いのがあれば買い替えたいなーという感じでした．&lt;&#x2F;p&gt;
&lt;p&gt;そういった時にネットやテレビなどでもマットレスの広告が目に入ることが多くなり（意識してたから余計に目に止まったんだと思う笑），妻も買い替えたいと思っていたらしく，思い切って買い換えることにしました！&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dokonomatutoresuwomai-tutaka&quot;&gt;どこのマットレスを買ったか&lt;&#x2F;h2&gt;
&lt;p&gt;ネットを見てると，大体以下の3つぐらいがランキング上位に来ていました．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nell.life&#x2F;mattress&quot;&gt;NELL マットレス&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;koala.com&#x2F;ja-jp&#x2F;mattresses&quot;&gt;コアラマットレス&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;emma-sleep-japan.com&#x2F;products&#x2F;mattress&quot;&gt;エママットレス&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;他にも，シモンズやエアウィーヴなど CM でも聞いたことあるメーカーもありますが，高級というのもあり，上にあげた3つの中から選ぶことにしました．定価は上の3つのマットレスもそれなりに高いが，僕が購入した時は半額セールがあったので，どこも6~8万ぐらいのレンジの金額でした（これでも決して安い買い物ではない😅）．&lt;&#x2F;p&gt;
&lt;p&gt;その中で，僕は &quot;&lt;strong&gt;エママットレス&lt;&#x2F;strong&gt;&quot; を，妻は &quot;&lt;strong&gt;NELL マットレス&lt;&#x2F;strong&gt;&quot; を購入することにしました！どこもトライアル期間として100~120日程度あるのと，保証も10年ぐらい付いていたので，あとは金額や反発感（低反発&#x2F;高反発）などの構造とかになると思います．&lt;&#x2F;p&gt;
&lt;p&gt;購入理由は，妻は元々 NELL マットレスに興味があったみたいで，そのままそれに決めてました．僕は比較していた3つの中だと，定価が一番高いものを単純に選んだ感じです笑（エママットレスは13万円ぐらいのものが60%オフぐらいになっていた）&lt;&#x2F;p&gt;
&lt;p&gt;補足ですが，NELL マットレスは使ってみた感覚だと，高反発な構造になっていて高反発系が良い人はオススメで，他の2つは低反発になっています．&lt;&#x2F;p&gt;
&lt;p&gt;買ってみて改めて感じたのは，めっちゃくちゃ厚さがあるということ！25cmぐらいあるので，ニトリのマットレスと比べたら1.5倍ぐらいあった😂&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1keyue-cheng-du-shi-tutemite&quot;&gt;1ヶ月程度使ってみて&lt;&#x2F;h2&gt;
&lt;p&gt;明らかに朝起きた時の腰痛は無くなって，快適に起きれるようになり，睡眠の質も上がったように感じます．睡眠は人生の三分の一程度を費やすとも言われているので，決して安い買い物ではなかったですが，満足感は高めです！寝てる時の腰痛を感じる方は是非一度検討しても良いと思います．マットレスを購入したことで，QOL が爆増したので，少し使い続けてどうかはまた感想でも書きたいです．&lt;&#x2F;p&gt;
&lt;p&gt;普段デスクワークなので，腰への負担はそれなりに掛かっているので，少しでも負担軽減できて良きかなと．ただ根本的には運動やストレッチなどを継続して改善するのが良さそうではある...😅&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>半年ぶりの大阪帰省と和歌山アドベンチャーワールド旅行🐼</title>
        <published>2023-10-07T00:00:00+00:00</published>
        <updated>2023-10-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/go-back-home-and-travel-to-wakayama-adventure-world/"/>
        <id>https://masatakashiwagi.com/blog/go-back-home-and-travel-to-wakayama-adventure-world/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/go-back-home-and-travel-to-wakayama-adventure-world/">&lt;p&gt;9月15~18日の間に家族で大阪に帰省したので，その時の旅の思い出を認めておきます．前回は転職するタイミングの3月あたりで帰省したので，大体半年ぶりぐらいになります．今回のメインは実は大阪ではなく和歌山旅行で，和歌山にあるアドベンチャーワールドに行くために1泊2日で両親 &amp;amp; 姉家族で和歌山旅行に行ってきました！&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dong-jing-da-ban-1ri-mu&quot;&gt;東京~大阪：1日目&lt;&#x2F;h2&gt;
&lt;p&gt;1日目は移動で，午前中に飛行機で羽田空港から大阪伊丹空港まで移動しました．今回はモニターがある席だったので，何か面白い映画があるかなと思ってリストを眺めていたら，以前から観たかった &quot;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nintendo.co.jp&#x2F;smbmovie&#x2F;index.html&quot;&gt;ザ・スーパーマリオブラザーズ・ムービー&lt;&#x2F;a&gt;&quot; があったので，ひたすら観てました笑&lt;&#x2F;p&gt;
&lt;p&gt;娘は飛行機は3,4回ぐらい乗っていて，慣れたのか泣かなくなったのでとても助かっています☺️&lt;&#x2F;p&gt;
&lt;p&gt;最近は大阪帰省でも新幹線ではなく，飛行機を選んでいます．早めに空港まで行く必要はありますが，フライト時間が1時間弱で，荷物も預けるので移動するとなったら新幹線より楽に感じます．新幹線の場合は荷物を足元や棚の上に載せないとで，キャリーバッグが大きいと棚の上に載らないので，足元が非常に窮屈でその状態で2時間半はかなりしんどいです...&lt;&#x2F;p&gt;
&lt;p&gt;大阪に着いたら昼ぐらいだったので，お昼ご飯を食べて&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.pokemon.co.jp&#x2F;shop&#x2F;pokecen&#x2F;osaka&#x2F;&quot;&gt;大丸梅田にあるポケモンセンター&lt;&#x2F;a&gt;に行って，ピカチュウのぬいぐるみとかを買ったりしました．&lt;&#x2F;p&gt;
&lt;p&gt;写真はお昼に食べた阪急梅田にある&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.hanamidori.net&#x2F;store&#x2F;archives&#x2F;55&quot;&gt;博多鶏ソバ 華味鳥&lt;&#x2F;a&gt;のラーメンと親子丼のセットで，香ばしくて風味良くとても美味しかったです！&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;osaka&#x2F;ramen1.jpg&quot; alt=&quot;お昼ご飯のラーメン&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;※ 阪神優勝の翌日でしたが，平日というのもあってかそこまで混んではなかったです🐯&lt;&#x2F;p&gt;
&lt;p&gt;あとは，実家に帰ったら全盛期の僕の懐かしい賞状が置いてありました笑&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet tw-align-center&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;実家帰って来たら懐かしい中学の体育祭の賞状が出てきた！ &lt;a href=&quot;https:&#x2F;&#x2F;t.co&#x2F;9tIxthZNm4&quot;&gt;pic.twitter.com&#x2F;9tIxthZNm4&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (@asteriam_fp) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asteriam_fp&#x2F;status&#x2F;1702592142248702237?ref_src=twsrc%5Etfw&quot;&gt;September 15, 2023&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;h2 id=&quot;da-ban-he-ge-shan-2ri-mu&quot;&gt;大阪~和歌山：2日目&lt;&#x2F;h2&gt;
&lt;p&gt;1日目は午前中に出発して，和歌山で泊まるホテルを目指しました．昼頃に和歌山に到着して，ホテル近くの魚市場的な店で海鮮丼を食べました！（写真撮ってなかった汗）やっぱり和歌山は海鮮がめちゃくちゃ美味しくて，新鮮でネタも大きくて大満足でした．&lt;&#x2F;p&gt;
&lt;p&gt;ホテルにチェックインしてからは，ホテルに併設されているプールに入ったり，夜はバイキングでたらふくご飯を食べたり，あと温泉も気持ちよかったです！バイキングってなんであんなにもテンション上がって楽しんでしょうかね？☺️&lt;&#x2F;p&gt;
&lt;p&gt;泊まったホテルには和室があったので，小さい子供がいる家族にはとても助かりました．まだまだ寝ている時に動き回ったりでベッドだと落ちる不安があるので，和室が用意されているホテルがベストです👌&lt;&#x2F;p&gt;
&lt;h2 id=&quot;he-ge-shan-adobentiyawarudo-da-ban-3ri-mu&quot;&gt;和歌山アドベンチャーワールド~大阪：3日目&lt;&#x2F;h2&gt;
&lt;p&gt;ホテルをチェックアウトして朝イチでアドベンチャーワールドに行きましたが，日曜日なので園内の駐車場に入るのにかなり混雑しました．
園内に入ったら，入り口でよくある写真を撮ってくれるスペースでスタッフに写真を撮ってもらい（以前沖縄の美ら海水族館でも撮って貰ったが，我が家の定番になりつつある笑），アドベンチャーワールドといえばの，ジャイアントパンダ🐼を見ました！！ちょうど食事中みたいで笹を食べていました笑&lt;&#x2F;p&gt;
&lt;p&gt;パンダエリアが一番来場客が居た気がしますが，上野動物園では予約しないと見れない時があったとのことで，普通に見れるのは良かったです！&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;osaka&#x2F;panda1.jpg&quot; alt=&quot;アドベンチャーワールドのパンダ&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;アドベンチャーワールドはジャイアントパンダが有名で頭数は少し前まで日本で一番多かったみたい．現在日本でパンダに会える場所は3ヶ所のみで，上野動物園（東京都）・アドベンチャーワールド（和歌山県）・神戸市立王子動物園（兵庫県）とのことです（参考：&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;report.iko-yo.net&#x2F;articles&#x2F;12804&quot;&gt;【2023最新】パンダが見られる動物園3選 全9頭を写真付で網羅&lt;&#x2F;a&gt;）．&lt;&#x2F;p&gt;
&lt;p&gt;パンダを見た後は，バスでサファリゾーンを1週してライオンやトラなどの肉食動物を見つつ，この日は結構暑かったのでかき氷を食べながらイルカショーを観覧しました．&lt;&#x2F;p&gt;
&lt;p&gt;イルカショーは特にお姉さんがマイクを持って説明するわけではなく，淡々とショーが進んでいく感じでした．最後には，関西の人なら何度も聞いたことがある名曲の「Always Together」が流れたので，久しぶりに聞いて少し感動しました笑&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet tw-align-center&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;アドベンチャーワールドのイルカショー良きでした！ &lt;a href=&quot;https:&#x2F;&#x2F;t.co&#x2F;WgfX7An2r7&quot;&gt;pic.twitter.com&#x2F;WgfX7An2r7&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (@asteriam_fp) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asteriam_fp&#x2F;status&#x2F;1703274450056356016?ref_src=twsrc%5Etfw&quot;&gt;September 17, 2023&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;この辺でみんな疲れたので，お土産を買って実家への帰路へ着きました．本当は帰りに&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;toretore.com&#x2F;ichiba&#x2F;&quot;&gt;とれとれ市場&lt;&#x2F;a&gt;で海鮮のお昼ご飯を食べようとしたのですが，めちゃくちゃに混んでいたのでやめて帰りのサービスエリアでお昼を食べました😅&lt;&#x2F;p&gt;
&lt;p&gt;あと，この日はちょうど地元での花火大会があって，今年初の花火大会を観て夏の終わりを感じました🎆&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet tw-align-center&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;枚方の花火大会で夏を感じてる！ &lt;a href=&quot;https:&#x2F;&#x2F;t.co&#x2F;qNsao2EynB&quot;&gt;pic.twitter.com&#x2F;qNsao2EynB&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (@asteriam_fp) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asteriam_fp&#x2F;status&#x2F;1703358691666473255?ref_src=twsrc%5Etfw&quot;&gt;September 17, 2023&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;h2 id=&quot;da-ban-dong-jing-4ri-mu&quot;&gt;大阪~東京：4日目&lt;&#x2F;h2&gt;
&lt;p&gt;この日は特に何もなく，大阪から東京に帰る日という感じで，伊丹空港で定番の551の豚まんをお土産に買ったり，自分たちのお昼ご飯にしたりして，無事家路に着きました．ちなみに551の豚まんを買うのに，長蛇の列で駅からの連絡通路のところまで列ができていて，みんな551好きですね☺️&lt;&#x2F;p&gt;
&lt;p&gt;今回も半年ぶりに実家に帰って両親に成長した孫の姿を見せられて，和やかなひと時を過ごすことができたかなと．&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Netflix の事例から RecSysOps を学ぶ</title>
        <published>2023-10-02T00:00:00+00:00</published>
        <updated>2023-10-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/learning-recsysops-from-netflix-practices/"/>
        <id>https://masatakashiwagi.com/blog/learning-recsysops-from-netflix-practices/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/learning-recsysops-from-netflix-practices/">&lt;p&gt;Netflix は RecSys のトップランナーの1社であり，そこで行われているオペレーションに以前から興味があり気になってました．そこで，2022年のテックブログで紹介された RecSysOps に関する取り組みからノウハウを学ぼうと思い，記事の内容を取り上げながら，所感を書いていきます．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;netflixtechblog.medium.com&#x2F;recsysops-best-practices-for-operating-a-large-scale-recommender-system-95bbe195a841&quot;&gt;RecSysOps: Best Practices for Operating a Large-Scale Recommender System&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;Large-Scale&lt;&#x2F;code&gt; と書かれていますが，Netflix のような規模でなくても試せることは多いと感じます．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;recsysops-toha-sorenibi-yao-nayao-su-toha&quot;&gt;RecSysOps とは？それに必要な要素とは？&lt;&#x2F;h2&gt;
&lt;p&gt;RecSysOps (= Recommender Systems Operations) という言葉はこのブログが初かなと思います．もちろんこういった言葉で表現されていないけど，各社推薦システムの運用を通して何かしらのプラクティスを持っているはずです．&lt;&#x2F;p&gt;
&lt;p&gt;RecSysOps が何を指すかは，動画で以下のように述べられています．&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;RecSysOps: Lessons we learned while operating a large RecSys&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;多くのリクエストに応えたり，安定的に稼働させ続ける（可用性）推薦システムを運用する上で得られたプラクティスを RecSysOps として紹介してくれています．&lt;&#x2F;p&gt;
&lt;p&gt;この取り組みを行うことで，以下の点で役立ったと書かれています．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reduce&lt;&#x2F;strong&gt; our firefighting time&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Focus&lt;&#x2F;strong&gt; on innovations&lt;&#x2F;li&gt;
&lt;li&gt;Build &lt;strong&gt;trust&lt;&#x2F;strong&gt; with our stakeholders&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;RecSysOps には4つの主要な取り組みがあり，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Issue Detection&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Issue Prediction&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Issue Diagnosis&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Issue Resolution&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;これらを通して，Netflix のような大規模な推薦システムを健全に運用できているとのことです．&lt;&#x2F;p&gt;
&lt;p&gt;こういった取り組みは自分達が本来集中したいこと，また検証したいことだったりクリエイティブな活動に時間を割けるようにする上でも大事な取り組みだなと感じます．機械学習システムは本番環境に導入されてからが &lt;strong&gt;本番&lt;&#x2F;strong&gt; なので，最初は上手くいってても，時間が経過するにつれて綻びというか予期せぬこと・開発時には想像していなかった事象は平気で起きるので，これらを検知したり予測して，適切に対処していく活動は尊いなと感じます．&lt;&#x2F;p&gt;
&lt;p&gt;モニタリングして，検知できる状態にするまではよく行われるが，じゃあ検知した後にそれらが分析できる状態になっているか，Runbook のような形でオペレーション手順にまで落とし込めているか，これらができている会社はまだまだ多くない印象です．&lt;&#x2F;p&gt;
&lt;p&gt;では，それぞれ4つのトピックを見ていきます．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;issue-detection&quot;&gt;Issue Detection&lt;&#x2F;h2&gt;
&lt;p&gt;RecSysOps における最初のフェーズで，「&lt;strong&gt;Issue Detection = 問題の検出&lt;&#x2F;strong&gt;」が最も重要な要素だと語られています．理由としては，これが後続ステップのトリガーとなるため，これが行われないと後続ステップは意味がないとのこと．&lt;&#x2F;p&gt;
&lt;p&gt;この取り組みとしては，3ステップ紹介されています．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sutetupu1-guan-lian-surufen-ye-karaji-zhi-noquan-tenobesutopurakuteisuwoqu-riru-reru&quot;&gt;ステップ1: 関連する分野から既知の全てのベストプラクティスを取り入れる&lt;&#x2F;h3&gt;
&lt;p&gt;最初のステップとして，&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The very first step is to incorporate all the known best practices from related disciplines.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;「&lt;strong&gt;関連する分野から既知の全てのベストプラクティスを取り入れる&lt;&#x2F;strong&gt;」ということで，推薦システムの場合だと，ソフトウェアエンジニアリングと機械学習が含まれるため，DevOps と MLOps の両方のプラクティスを取り入れることが示されています．ここでも &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;research.google&#x2F;pubs&#x2F;pub46555&#x2F;&quot;&gt;ML Test Score&lt;&#x2F;a&gt; をチェックリストとして活用できるよと紹介されています．&lt;&#x2F;p&gt;
&lt;p&gt;本番環境で発生する問題は無数にある &amp;amp; 未知なる問題もあるため全てに対応することは難しいと感じるが，問題に気づくための取り組み・検出範囲を拡げるための教訓は先人の知恵から学ぶことができるので，これらをリサーチすることも重要だと思う．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sutetupu2-sisutemuwozi-fen-tatinoshi-dian-karaendotuendodejian-shi-suru&quot;&gt;ステップ2: システムを自分たちの視点からエンドツーエンドで監視する&lt;&#x2F;h3&gt;
&lt;p&gt;2番目のステップとして，&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The second step is to monitor the system end-to-end from your perspective.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;「&lt;strong&gt;システムを自分たちの視点からエンドツーエンドで監視する&lt;&#x2F;strong&gt;」ということで，大規模な推薦システムの場合，多くのチームが開発や運用に関わってきます．ML チームの視点から見ると，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;アップストリームチーム
&lt;ul&gt;
&lt;li&gt;データを提供するチーム&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;ダウンストリームチーム
&lt;ul&gt;
&lt;li&gt;モデルを使用するチーム&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;がある．データチームや自分たちのモデルを使いたい別チームが社内に居るかもしれない．それぞれのチームが独自にモニタリングなどの監視をしているかもしれないが，&lt;strong&gt;そのチームの取り組みだけに頼らずに自分たちの視点からも必要な情報（入力と出力など）をモニタリングするのが良い&lt;&#x2F;strong&gt;と紹介されています．&lt;&#x2F;p&gt;
&lt;p&gt;この教訓は，ML Test Score の「Monitor 1: Dependency changes result in notification」でも似たようなことが述べられています．例えば，データチームや開発チームと連携して，スキーマ変更や保存されるデータが変わる場合は連携するようにオペレーションを整えるべきだったりが挙げられます．&lt;&#x2F;p&gt;
&lt;p&gt;データチームはデータ全体を見ているので，ML だけが使う一部のデータをどこまで感知しているかはわからないので，ML で使用するデータに関しては ML 側できちんと把握して必要なことは自分たちで率先して動くことが大事だと感じる．&lt;&#x2F;p&gt;
&lt;p&gt;他チームに任せるのではなく，オーナーシップを持って自分たちの範疇で取り組めることに関しては積極的に行っていく姿勢は素晴らしい！&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sutetupu3-sutekuhorudanoxuan-nian-woli-jie-suru&quot;&gt;ステップ3: ステークホルダーの懸念を理解する&lt;&#x2F;h3&gt;
&lt;p&gt;3番目のステップとして，&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The third step for getting a comprehensive coverage is to understand your stakeholders’ concerns.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;「&lt;strong&gt;ステークホルダーの懸念を理解する&lt;&#x2F;strong&gt;」ということで，推薦システムの文脈では，主要な視点として，メンバー（ユーザー）とアイテムがある．この取り組みは問題の検出要素のカバー範囲を拡げるのに良いと書かれています．&lt;&#x2F;p&gt;
&lt;h4 id=&quot;menba-yuza-shi-dian&quot;&gt;メンバー（ユーザー）視点&lt;&#x2F;h4&gt;
&lt;p&gt;提供している推薦モデルによって高く評価されていないアイテムを選択している場合，何かしらの潜在的な問題があるかもしれないです．また，これは将来の優れたインスピレーションの源になるとも書かれています．&lt;&#x2F;p&gt;
&lt;h4 id=&quot;aitemushi-dian&quot;&gt;アイテム視点&lt;&#x2F;h4&gt;
&lt;p&gt;Netflix の場合，アイテムに責任を持つチームはアイテムのコールドスタートと潜在的な本番バイアスに関する懸念を持っています．彼らの懸念に関してサポートするために，メトリクスの定義・モニタリングツールの提供だけでなく，問題がアイテムごとに発生しているかどうかについてのインサイトの提供などもしているとのこと．これらを通して，アイテムに関連する主要な問題に積極的に対処し，ステークホルダーとの信頼関係を構築していると書かれています．&lt;&#x2F;p&gt;
&lt;p&gt;Netflix のようなアイテムに責任を持つチームやカスタマーサクセス・サポートチームのようにユーザーのことを常に考えているステークホルダーの懸念や悩みをヒアリングしたり，サポートすることは自分たちが気づいていない新しい視点を提供してくれるので，とても参考になると日々の業務でも感じます．こういったチームからの要望などを元にモニタリングすべき項目を追加したり参考にしたりしているので，ホットラインを築いて協力していくことで問題に気づくことはあると思います．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;issue-prediction&quot;&gt;Issue Prediction&lt;&#x2F;h2&gt;
&lt;p&gt;2つ目のトピックは，「&lt;strong&gt;Issue Prediction = 問題の予測&lt;&#x2F;strong&gt;」で，問題が本番環境で起こる前に予測して修正することを紹介しています．&lt;&#x2F;p&gt;
&lt;p&gt;Netflix では，アイテムのコールドスタート問題が重要なテーマになっています．この問題を過去のデータを使用して，ローンチ当日の本番モデルの行動統計を予測できるモデルを構築して予測しているとのことで，これによりアイテムのコールドスタートに関連する潜在的な問題を一週間以上前に検出し，問題を修正する時間を確保できているとのことです．&lt;&#x2F;p&gt;
&lt;p&gt;この取り組みは正直かなり難易度が高いと感じました．アイテムに関する事前の情報やメタデータを駆使しながら，類似アイテムとの関連性を見つけて予測するのが良いのかな？正直これに関するアイデアは現時点だとあまりないです😅&lt;&#x2F;p&gt;
&lt;h2 id=&quot;issue-diagnosis&quot;&gt;Issue Diagnosis&lt;&#x2F;h2&gt;
&lt;p&gt;3つ目のトピックは，「&lt;strong&gt;Issue Diagnosis = 問題の原因特定&lt;&#x2F;strong&gt;」で，3つステップに分けて取り組みを紹介している．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wen-ti-wofen-li-sitezai-xian-suru&quot;&gt;問題を分離して再現する&lt;&#x2F;h3&gt;
&lt;p&gt;まず最初のステップとして，&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;the next phase is to find its root cause.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;「&lt;strong&gt;問題を分離して再現すること&lt;&#x2F;strong&gt;」ということで，問題を再現するには事前に適切なログ設定を行う必要があると書かれています．これは何かしら問題がある場合に，単純にコードを再実行しても問題が再現できない状況があるということです．そのため，問題を理解するための再現に必要なログを出力しておくのが大事です．ただし，コストを削減するためにトラフィックの一部に対してログの記録を行っているとのことで，この場合には，適切なスライスでカバレッジを満たせるサンプリング方法を設計する必要になります．&lt;&#x2F;p&gt;
&lt;p&gt;Netflix レベルになると，全部をロギングしておくとコストが尋常じゃないぐらい増えるので，こういった観点も必要になるんだなと感じました．ロギングは完全に同意で，問題の再現だけでなくモデル改善・分析観点でも必須ですね．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wen-ti-gamlmoderunoru-li-matahamoderuzi-ti-toguan-lian-siteirukadoukawoli-jie-suru&quot;&gt;問題がMLモデルの入力またはモデル自体と関連しているかどうかを理解する&lt;&#x2F;h3&gt;
&lt;p&gt;2つ目のステップとして，&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The next step after reproducing the issue is to figure out if the issue is related to inputs of the ML model or the model itself.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;「&lt;strong&gt;問題がMLモデルの入力またはモデル自体と関連しているかどうかを理解すること&lt;&#x2F;strong&gt;」ということで，入力データに関連しているかどうかは，入力が正確で有効であることを検証する必要があるので，非常に難しい問題とのこと．&lt;&#x2F;p&gt;
&lt;p&gt;これは難しくて，データ全体でスケーリングしたりする処理を入れているとそのモデルも持っておかないで，ある特徴量を生成するのに別の特徴量を使っている場合は，その追跡やリネージュ関係を理解する必要があるので，より複雑な問題になりそうです．そういったこともあり，データのバリデーションは大事な取り組みの1つになってくると思います．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mlmoderutosonoxue-xi-detanonei-bu-woxiang-sikudiao-betewen-ti-nogen-ben-yuan-yin-wojian-tukeru&quot;&gt;MLモデルとその学習データの内部を詳しく調べて問題の根本原因を見つける&lt;&#x2F;h3&gt;
&lt;p&gt;3つ目のステップとして，&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;the next step is to dig deep inside the ML model and its training data to find the root cause of the issue.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;「&lt;strong&gt;MLモデルとその学習データの内部を詳しく調べて問題の根本原因を見つける&lt;&#x2F;strong&gt;」ということで，ここでは例えば，モデルを解釈するために SHAP &#x2F; LIME などの可視化ツールを使ったり，決定気のノードやニューラルネットワークのレイヤーを可視化する方法などを述べています．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;issue-resolution&quot;&gt;Issue Resolution&lt;&#x2F;h2&gt;
&lt;p&gt;最後のトピックは，「&lt;strong&gt;Issue Resolution = 問題の解決&lt;&#x2F;strong&gt;」で，解決には短期的で緊急度が高いものから，長期的に取り組む必要があるものが考えられます．ML モデルは高度に最適化されているので，気軽に手動で変更することはできないし，しても適切な推薦を提供できない可能性が生じるということ．&lt;&#x2F;p&gt;
&lt;p&gt;ここでは，事前に緊急に解決すべきかどうかの選択肢やトレードオフを用意しておくというのが紹介されています．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;検出または予測コンポーネントのチェックが定期的に自動実行されているか&lt;&#x2F;li&gt;
&lt;li&gt;人間の判断が必要な場合に，その人が必要な情報をすぐに手に入れるようになっているか&lt;&#x2F;li&gt;
&lt;li&gt;Hotfix が必要な時に，デプロイを数クリックで簡単に適用することができるか&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;後半2つは非常に刺さる．例えば，データを集めるだけでなくすぐに使える状態に整理されているか，対応時のレポートラインやステークホルダーとの調整が事前にされているか，優先度の応じて対応できるようにオペレーションが確立されているかなど色々とありそうで，こういったことを事前に準備しておけると，いざその問題に直面した時に自分たちが楽になるし，変に焦る必要もなくなるので，動きやすいし信頼感もあるだろうな感じます．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;RecSysOps という推薦システムに焦点を当てているが，これは別に推薦システム特有のものではなく，他の機械学習システムにおける MLOps として，適用できる話だと感じました．泥臭いオペレーションや関連するチームとの信頼関係を通して，日々の運用やサービスが安定稼働しているのを感じます．Issue Detection の3つのステップに全てが詰まってますね．&lt;&#x2F;p&gt;
&lt;p&gt;機械学習の場合は，データ・コード・モデルの三大要素があるので，問題を検知していく上でこれらの「&lt;strong&gt;Versioning・Reproducibility・Monitoring&lt;&#x2F;strong&gt;」への取り組みはより必要だと改めて感じました．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;RecSysOps: Best Practices for Operating a Large-Scale Recommender System
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.slideshare.net&#x2F;Ehsan38&#x2F;recsysops-best-practices-for-operating-a-largescale-recommender-system&quot;&gt;SlideShare&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;TDCpTHwfpqg&quot;&gt;YouTube&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>初めてのドメイン購入を機に日常ブログを移行🚚</title>
        <published>2023-09-10T00:00:00+00:00</published>
        <updated>2023-09-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/new-domain-for-personal-blog/"/>
        <id>https://masatakashiwagi.com/blog/new-domain-for-personal-blog/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/new-domain-for-personal-blog/">&lt;p&gt;最近初めてドメインを購入してみました！というのも以前から独自ドメインを使って個人サイトを運営したいなと思い，そのためにドメインを買おうか迷っていましたが，この度やっと重い腰を上げて購入してみました！というのも，広告で流れてきて，夜中のテンションでつい買ってしまいました笑&lt;&#x2F;p&gt;
&lt;p&gt;なので，せっかくドメインを購入したので，個人ブログの日常を綴る内容をこれを機に移行しようと考えています．ただ，今も使っている テックブログの &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masatakashiwagi.github.io&#x2F;portfolio&#x2F;&quot;&gt;masatakashiwagi.github.io&#x2F;portfolio&#x2F;&lt;&#x2F;a&gt; は引き続き技術系の内容を中心に書いていく予定です．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;oming-qian-com-dedomeinwogou-ru&quot;&gt;お名前.com でドメインを購入&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.onamae.com&#x2F;&quot;&gt;お名前.com&lt;&#x2F;a&gt; が簡単に購入できそうだったので，こちらを利用しました．丁度 &lt;code&gt;.com&lt;&#x2F;code&gt; のドメインを無料で購入できるタイミングだったので，今回は無料のドメインにしました．ただこれは初期費用が0円で，1年後の更新費用は1,400円程度かかるようです．&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.onamae.com&#x2F;service&#x2F;d-price&#x2F;&quot;&gt;ドメイン料金一覧&lt;&#x2F;a&gt;を見ていると，&lt;code&gt;.red&lt;&#x2F;code&gt;, &lt;code&gt;.green&lt;&#x2F;code&gt; みたいな色のドメインがあったり，&lt;code&gt;.fitness&lt;&#x2F;code&gt; みたいな変わったものまで色々あり眺めていて楽しかったです．今回購入したドメインは，&lt;code&gt;masatakashiwagi.com&lt;&#x2F;code&gt; で，やっと自分の独自ドメインを個人ウェブサイトに登録できるようになりました！&lt;&#x2F;p&gt;
&lt;h2 id=&quot;uebusaitonoyin-tuyue-siwokao-eteruli-you&quot;&gt;ウェブサイトの引っ越しを考えてる理由&lt;&#x2F;h2&gt;
&lt;p&gt;今までは &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gohugo.io&#x2F;&quot;&gt;Hugo&lt;&#x2F;a&gt; を使って運用していて，これも慣れれば使い勝手は良くシンプルなウェブサイトを作れます．なので，このまま使うことも考えてドメインの設定を GitHub Pages でしようとしたところ，上手く設定できずで，それならいっそのこと新しく作り直すかーという流れになりました．&lt;&#x2F;p&gt;
&lt;p&gt;※ GitHub Pages でのホスティングが上手くいかなかったのはおそらく，アカウント名.github.io というリポジトリでないと無理で，アカウント名.github.io&#x2F;portfolio などのサブディレクトリでやろうとすると独自ドメインの設定ができないっぽい気がしています...もしやり方知ってる人居れば教えて欲しいです🙏&lt;&#x2F;p&gt;
&lt;h2 id=&quot;astro-vercel-dehosuteinguwoshi-meta&quot;&gt;Astro &amp;amp; Vercel でホスティングを始めた&lt;&#x2F;h2&gt;
&lt;p&gt;簡単にブログをデプロイできるホスティング先として，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vercel.com&#x2F;&quot;&gt;Vercel&lt;&#x2F;a&gt; は前から知っていたので，そのページを眺めていたら，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vercel.com&#x2F;templates&#x2F;astro&quot;&gt;Astro starter templates and themes&lt;&#x2F;a&gt; というブログテンプレートを発見したので，そこから &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vercel.com&#x2F;templates&#x2F;astro&#x2F;astro-paper&quot;&gt;AstroPaper&lt;&#x2F;a&gt; というデザインを選びました．ページに行くと，Vercel で簡単にデプロイする方法が載ってるので，手順に従えばというかボタン1つでデプロイできました笑．無料で使えて独自ドメインも設定できるのでオススメです！&lt;&#x2F;p&gt;
&lt;p&gt;コードは GitHub で管理することになりますが，コードを修正してコミットしたら，Vercel 上でビルド→デプロイと走るので，めっちゃ楽に修正した結果が反映されたページを確認することができます．もちろん記事を書いたりしている時や，レイアウトを修正している時は，ローカルでプレビューしながら開発することができます．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は初めて独自ドメインを購入して，新しい個人ウェブサイトに登録したブログを書きました．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ドメイン購入：お名前.com&lt;&#x2F;li&gt;
&lt;li&gt;ブログテーマ：AstroPaper&lt;&#x2F;li&gt;
&lt;li&gt;ホスティング：Vercel&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;で始めていきます．&lt;&#x2F;p&gt;
&lt;p&gt;ちなみに，最初は Tailwind Nextjs Starter Blog という Nextjs と Tailwind CSS を使って構築されたものを使おうとしましたが，上手く Twitter, Speaker Deck の埋め込みが作れなかったりしたので，諦めました😅&lt;&#x2F;p&gt;
&lt;p&gt;React, TypeScript ら辺を勉強して使いこなせたら良いなと思いましたが，また別の機会にチャレンジしようと思います！&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Vertex AI Pipelines のサービスアカウントで少しつまずいたので整理した</title>
        <published>2023-08-14T00:00:00+00:00</published>
        <updated>2023-08-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/service-account-for-vertex-ai-pipelines/"/>
        <id>https://masatakashiwagi.com/blog/service-account-for-vertex-ai-pipelines/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/service-account-for-vertex-ai-pipelines/">&lt;p&gt;Vertex AI Pipelines のサービスアカウント周りが少し分かりづらかったのと，GCP の他のサービスへの権限付与（IAM ロールの付与）の方法について備忘録として残しておきます．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;vertex-ai-pipelines-niguan-lian-suru3tunosabisuakaunto&quot;&gt;Vertex AI Pipelines に関連する3つのサービスアカウント&lt;&#x2F;h2&gt;
&lt;p&gt;Vertex AI Pipelines に関連するサービスアカウントは下記の3つがあります．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;① パイプライン実行時に指定できるサービスアカウント&lt;&#x2F;li&gt;
&lt;li&gt;パイプラインの各コンポーネントが各種リソースにアクセスするために GCP 側が用意したサービスアカウント（サービスエージェント）
&lt;ul&gt;
&lt;li&gt;② Vertex AI Service Agent&lt;&#x2F;li&gt;
&lt;li&gt;③ Vertex AI Custom Code Service Agent&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;paipurainshi-xing-shi-nizhi-ding-dekirusabisuakaunto&quot;&gt;パイプライン実行時に指定できるサービスアカウント&lt;&#x2F;h3&gt;
&lt;p&gt;Vertex AI Pipelines の &lt;code&gt;job.submit&lt;&#x2F;code&gt; に指定できるサービスアカウントでパイプライン実行をするために使用されます．これを指定しない場合は，Compute Engine のデフォルトのサービスアカウントを使用してパイプラインが実行されます．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# sample code&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;SERVICE_ACCOUNT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; os.environ[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;SERVICE_ACCOUNT&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;PROJECT_ID&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; os.environ[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;PROJECT_ID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;job&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aiplatform.PipelineJob(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;    display_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;sample-pipelines&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;    template_path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;sample-pipelines.json&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;    project&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;PROJECT_ID&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;    location&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;asia-northeast1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;    enable_caching&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;False&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;job.submit(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;service_account&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;SERVICE_ACCOUNT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;僕はこのサービスアカウントを開発時に勘違いしていて，&lt;strong&gt;ここのサービスアカウントに指定したもので，パイプラインの全てのコンポーネントが動く&lt;&#x2F;strong&gt;と思ってました．なので，ML 用にカスタマイズした（必要な IAM ロールを付与）サービスアカウントを指定して実行したものの，権限エラーで動かずという感じで困っていました．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cloud.google.com&#x2F;vertex-ai&#x2F;docs&#x2F;pipelines&#x2F;configure-project#service-account&quot;&gt;Configure a service account with granular permissions&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;次に説明する2つのサービスアカウントが実際の各コンポーネントを動かすサービスアカウントになっています．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gcp-ce-gayong-yi-sitasabisuakaunto-sabisueziento&quot;&gt;GCP 側が用意したサービスアカウント（サービスエージェント）&lt;&#x2F;h3&gt;
&lt;p&gt;Vertex AI に関する GCP 側が用意したサービスアカウント（サービスエージェント）は2つあります．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Vertex AI Custom Code Service Agent&lt;&#x2F;li&gt;
&lt;li&gt;Vertex AI Service Agent&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;IAM ロールの画面上では，以下のような登録になっています．&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left&quot;&gt;Principal&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Name&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Role&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;service-&amp;lt;PROJECT_NUMBER&amp;gt;@gcp-sa-aiplatform-cc.iam.gserviceaccount.com&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;AI Platform Custom Code Service Agent&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Vertex AI Custom Code Service Agent&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;service-&amp;lt;PROJECT_NUMBER&amp;gt;@gcp-sa-aiplatform.iam.gserviceaccount.com&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;AI Platform Service Agent&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Vertex AI Service Agent&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h4 id=&quot;vertex-ai-custom-code-service-agent&quot;&gt;Vertex AI Custom Code Service Agent&lt;&#x2F;h4&gt;
&lt;p&gt;このロールは&lt;strong&gt;カスタムトレーニングコードを実行する&lt;&#x2F;strong&gt;ために使用され，付与されているロールは &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cloud.google.com&#x2F;vertex-ai&#x2F;docs&#x2F;general&#x2F;access-control#aiplatform.customCodeServiceAgent&quot;&gt;Vertex AI Custom Code Service Agent (roles&#x2F;aiplatform.customCodeServiceAgent)&lt;&#x2F;a&gt; ドキュメントから確認できます．&lt;&#x2F;p&gt;
&lt;h4 id=&quot;vertex-ai-service-agent&quot;&gt;Vertex AI Service Agent&lt;&#x2F;h4&gt;
&lt;p&gt;このロールは&lt;strong&gt;Vertex AI 全般の機能を動作させる&lt;&#x2F;strong&gt;ために使用され，付与されているロールは &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cloud.google.com&#x2F;vertex-ai&#x2F;docs&#x2F;general&#x2F;access-control#aiplatform.serviceAgent&quot;&gt;Vertex AI Service Agent (roles&#x2F;aiplatform.serviceAgent)&lt;&#x2F;a&gt; ドキュメントから確認できます．&lt;&#x2F;p&gt;
&lt;p&gt;実際のパイプラインの各コンポーネントの権限は，上記2つのサービスアカウントのどちらかが使われることになるので，このどちらかのサービスアカウントに予め付与されていないサービスを使う場合は権限エラーになってしまいます．そのため，使用したいサービスの権限がリンク先のアクセスコントロールのページで付与されていない場合は，IAM ロールの画面から追加する必要があります．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gcp-ce-gayong-yi-sitasabisuakauntoni-iam-roruwofu-yu-surufang-fa&quot;&gt;GCP 側が用意したサービスアカウントに IAM ロールを付与する方法&lt;&#x2F;h2&gt;
&lt;p&gt;2つのサービスアカウントのうち使用されるアカウントに対して，適宜必要なロールを付与することで権限がなかったサービスにもアクセスすることができます．&lt;&#x2F;p&gt;
&lt;p&gt;例えば，Firestore へのアクセスは上記2つのアカウントには付与されていないため，デフォルトの状態だと権限不足でアクセスできないです．そのため read&#x2F;write できる &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cloud.google.com&#x2F;iam&#x2F;docs&#x2F;understanding-roles#datastore.user&quot;&gt;Cloud Datastore User (roles&#x2F;datastore.user)&lt;&#x2F;a&gt; のロールを追加で付与することで Firestore への読み書きができるようになります．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2023&#x2F;service_account_for_vertex_ai_pipelines&#x2F;service-account-img1.png&quot; alt=&quot;IAM ロールの設定画面&quot; title=&quot;IAM ロールの設定画面&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;画面上からだと，上図の「&lt;strong&gt;Include Google-provided role grants&lt;&#x2F;strong&gt;」にチェックを入れることで，GCP 側が用意したサービスアカウントが表示されます．上記2つのサービスアカウントを探して必要な権限を編集して追加することで権限エラーを回避することができます．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;code&gt;job.summit&lt;&#x2F;code&gt; 時に指定したサービスアカウントでパイプラインのコンポーネント動かせると思い込んでいて，実際はパイプラインを実行するだけだったので，若干混乱しました．&lt;&#x2F;p&gt;
&lt;p&gt;パイプラインを動かす実際のサービスアカウントは別で2つ存在しており，このドキュメントを見つけることがすぐにできず，時間を消費してしまったのもあり，もしこの辺りで悩んでいる人が居れば参考になるかなと思い，備忘録として今回残すことにしました．&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>ANN ライブラリの Annoy で build index する時に Illegal Instruction Error が発生した</title>
        <published>2023-08-09T00:00:00+00:00</published>
        <updated>2023-08-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/annoy-lib-illegal-instruction-error/"/>
        <id>https://masatakashiwagi.com/blog/annoy-lib-illegal-instruction-error/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/annoy-lib-illegal-instruction-error/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;spotify&#x2F;annoy&quot;&gt;Annoy&lt;&#x2F;a&gt; という Spotify が開発している Python 製の ANN (Approximate Nearest Neighbors) のライブラリがあり，それを使ってレコメンドアイテムの類似度を計算する機会があったのですが，コンテナ化したものを Vertex AI Pipelines 上で動かしていたところ，&lt;code&gt;Fatal Python error: Illegal instruction&lt;&#x2F;code&gt; というエラーが発生して困っていたので，今回はこのエラーの対処方法について書いていきます．&lt;&#x2F;p&gt;
&lt;!-- 結論としては，ローカルの M1 Mac と GitHub Actions 経由での docker build を両立するためには，Dockerfile に Annoy のライブラリをインストールする時に使用する `ANNOY_COMPILER_ARGS` という環境変数を追加することで解決できました🎉 --&gt;
&lt;p&gt;※ Annoy については，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;techblog.zozo.com&#x2F;entry&#x2F;annoy-explanation&quot;&gt;こちらの ZOZO さんの記事&lt;&#x2F;a&gt;が詳しく解説してくれているので，ここでは説明は割愛します．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;docker-build-shi-nohuan-jing-niyoruwen-ti&quot;&gt;docker build 時の環境による問題？&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;fa-sheng-sitashi-xiang&quot;&gt;発生した事象&lt;&#x2F;h3&gt;
&lt;p&gt;Annoy のライブラリを含んだ Docker イメージを作り，それを元に作成したコンポーネントを機械学習パイプラインである Vertex AI Pipelines で動かしたところ，&lt;code&gt;Fatal Python error: Illegal instruction&lt;&#x2F;code&gt; というエラーが発生しました．これは具体的には，&lt;code&gt;AnnoyIndex&lt;&#x2F;code&gt; を構築する際に発生します．&lt;&#x2F;p&gt;
&lt;p&gt;※ 前提として，Annoy を含む Python ライブラリは poetry で管理し，Dockerfile 内で &lt;code&gt;poetry install&lt;&#x2F;code&gt; しています．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;eranoyuan-yin&quot;&gt;エラーの原因&lt;&#x2F;h3&gt;
&lt;p&gt;今回の問題は，Docker コンテナのイメージをビルドする時に指定するオプションが原因でした．&lt;&#x2F;p&gt;
&lt;p&gt;ローカル環境は Apple M1 Max (ARM アーキテクチャ) で開発していたため，イメージ作成時に以下のオプションを指定してビルドしています．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; --platform&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; linux&#x2F;amd64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; sample-recsys:latest&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; .&#x2F;Dockerfile .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;AMD 環境でも動くように &lt;code&gt;--platform&lt;&#x2F;code&gt; フラグにターゲットプラットフォームである &lt;code&gt;linux&#x2F;amd64&lt;&#x2F;code&gt; を指定してビルドしていました．このビルドしたイメージを GCP の Artifact Registry にプッシュし，そのイメージを使って Vertex AI Pipelines で各コンポーネントの検証を行っています．&lt;&#x2F;p&gt;
&lt;p&gt;一方で，&lt;code&gt;--platform&lt;&#x2F;code&gt; フラグを付けずに M1 Mac からビルドしたイメージを使った場合には，&lt;code&gt;exec format error&lt;&#x2F;code&gt; というエラーが発生します．&lt;&#x2F;p&gt;
&lt;p&gt;検証時には，ローカル環境から直接イメージをビルド &amp;amp; プッシュし，そのイメージを使ったコンポーネントを Vertex AI Pipelines 上で動かして検証を行っており，その際に使用していたスクリプトをそのまま GitHub Actions での CI&#x2F;CD 構築時に使用したことで，今回の &lt;code&gt;Fatal Python error: Illegal instruction&lt;&#x2F;code&gt; という事象が発生することになります．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;Illegal instruction&lt;&#x2F;code&gt; というエラーが発生するという事象はいくつか Issue が上がっていました．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;spotify&#x2F;annoy&#x2F;issues&#x2F;492&quot;&gt;Error: illegal hardware instruction (core dumped) #492&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;spotify&#x2F;annoy&#x2F;issues&#x2F;513&quot;&gt;&quot;Illegal instruction: 4&quot; when trying to build index (Python 3.7, Annoy version 1.17.0, macOS 10.14.6) #513&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;--platform&lt;&#x2F;code&gt; フラグを付けてイメージをビルドしても問題ないライブラリも多数ありますが，Annoy では &lt;code&gt;linux&#x2F;amd64&lt;&#x2F;code&gt; を指定したのを GitHub Actions の Runner (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;actions&#x2F;runner-images&#x2F;blob&#x2F;main&#x2F;images&#x2F;linux&#x2F;Ubuntu2204-Readme.md&quot;&gt;ubuntu-latest&lt;&#x2F;a&gt;) で動かしたのがどうも上手く行かなかったみたいです...&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;spotify&#x2F;annoy&#x2F;issues&#x2F;472&quot;&gt;Initializing an AnnoyIndex crashes on AMD processors #472&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;jie-jue-fang-fa&quot;&gt;解決方法&lt;&#x2F;h2&gt;
&lt;p&gt;僕の例では，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;spotify&#x2F;annoy&#x2F;issues&#x2F;472&quot;&gt;Initializing an AnnoyIndex crashes on AMD processors #472&lt;&#x2F;a&gt; の Issue に記載されている方法で解決することができました．&lt;&#x2F;p&gt;
&lt;p&gt;Annoy のライブラリをインストールする際に，コンパイルパラメータである &lt;code&gt;ANNOY_COMPILER_ARGS&lt;&#x2F;code&gt; を Dockerfile 内に環境変数として指定することで解決できます．&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;spotify&#x2F;annoy&#x2F;blob&#x2F;main&#x2F;setup.py&quot;&gt;annoy&#x2F;setup.py&lt;&#x2F;a&gt; を見ると良いかもしれないです．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;ENV&lt;&#x2F;span&gt;&lt;span&gt; ANNOY_COMPILER_ARGS -D_CRT_SECURE_NO_WARNINGS,-DANNOYLIB_MULTITHREADED_BUILD,-mtune=native&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;この環境変数を Dockerfile にセットすると，&lt;code&gt;--platform&lt;&#x2F;code&gt; に &lt;code&gt;linux&#x2F;amd64&lt;&#x2F;code&gt; を付け Docker イメージを GitHub Actions 経由でビルドしたものを Vertex AI Pipelines で使用しても，エラー無く処理が完了しました．&lt;&#x2F;p&gt;
&lt;p&gt;あとは，そもそもこれはローカルの M1 Mac と GitHub Actions の両方で同一のスクリプトを使用したいが為に行っている対応策なので，スクリプトを別々にすれば，GitHub Actions でビルドする際には，上記の &lt;code&gt;ANNOY_COMPILER_ARGS&lt;&#x2F;code&gt; を設定することなく，シンプルに以下のビルドコマンドだけでいけます．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; sample-recsys:latest&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; .&#x2F;Dockerfile .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;また，，&lt;code&gt;--platform&lt;&#x2F;code&gt; のオプションを付けてビルドすると時間が余計にかかるので，無駄なものは付けない方が良さそうに思います．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は思いもよらないエラーで悩んでいたので，こうして無事？エラーの原因と解決策が分かって良かったです．全然このことに気づかなかったので，Annoy をやめて Faiss を使用することも考えたりしていました．コンテナイメージをビルドする際のローカルとプロダクション適用時のマシンスペックが違うことも考えた上で，再現性を意識したコードを書かなければと改めて感じたので，良い教訓となりました．&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>データフレームでリストを ndarray にした値を csv ファイルで保存する場合の注意</title>
        <published>2023-07-31T00:00:00+00:00</published>
        <updated>2023-07-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/save-array-list-in-dataframe/"/>
        <id>https://masatakashiwagi.com/blog/save-array-list-in-dataframe/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/save-array-list-in-dataframe/">&lt;p&gt;Python のデータフレームを使ってレコメンドリストを生成した場合に遭遇した内容で，備忘録として筆を取っています．内容としては，リストを ndarray に変換して，それらの値が入ったデータフレームを csv ファイルとして保存し，再度ロードする場合に発生する事象への対応方法になります．&lt;&#x2F;p&gt;
&lt;p&gt;結論は，データフレームにリスト形式のデータを保存したい場合は，str 型に変換してから保存するようにしましょう！これは csv のカンマ区切りでの保存による影響を受けてしまうからです．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fa-sheng-sitashi-xiang&quot;&gt;発生した事象&lt;&#x2F;h2&gt;
&lt;p&gt;例えば，各ユーザーに対してアイテムをレコメンドしたい場合を考えてみます．各ユーザーに対して用意されたレコメンドリストがあるとする．10人ユーザーが存在するとしてサンプルデータを作って考えてみると，&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; random&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pandas&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; numpy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;user_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [random.randint(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 99999&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;recommend_items&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [np.array([random.randint(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 99999&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;)])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# recommend_itemsのカラムには，リストをndarrayに変換したデータが入っている&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_rec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd.DataFrame({&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;user_id&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: user_id,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;recommend_items&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: recommend_items})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(df_rec[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;recommend_items&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; array([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;4775&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 44953&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 85874&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;  # 数値は適当に入れてます&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(df_rec[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;recommend_items&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; numpy.ndarray&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;データフレームの中身を見ると，以下のようなデータが入っています．&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: center&quot;&gt;&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;user_id&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;recommend_items&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;0&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;8482&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;[4775, 44953, 85874]&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;1&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;83899&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;[96090, 53639, 82456]&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;93606&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;[8355, 76477, 58666]&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;recommend_items のカラムのデータの実態は ndarray になっていますが，見た目はリスト型のデータが入っていると勘違いが起きたりします．特に色々な処理を行っていくと，途中で型が変わっていることに気づいていない場合もあるかと思います．&lt;&#x2F;p&gt;
&lt;p&gt;ここで，各ユーザーのレコメンドリストをデモ的に ndarray に変換していますが，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;BigQuery に配列で格納されているデータをロードした場合&lt;&#x2F;li&gt;
&lt;li&gt;処理過程で，Numpy 配列に変換した方が高速に処理でき，結果をそのまま格納した場合&lt;&#x2F;li&gt;
&lt;li&gt;etc...&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;などの場合で生じることがあるかなと思います．&lt;&#x2F;p&gt;
&lt;p&gt;このデータフレームを csv ファイルに保存して，ロードすると，&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# csvファイルで結果を保存&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_rec.to_csv(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;.&#x2F;tmp_recommend_results1.csv&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; index&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;False&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# 保存したcsvファイルをデータフレームとしてロードする&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tmp_df_rec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd.read_csv(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;.&#x2F;tmp_recommend_results1.csv&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(tmp_df_rec[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;recommend_items&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 4775 44953 85874&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;要素を1つ取り出してみると，カンマが取れて右詰めのような形式で表示されます．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ndarray-wo-csv-huairunibao-cun-suruqian-nirisutonibian-huan-suru&quot;&gt;ndarray を csv ファイルに保存する前にリストに変換する&lt;&#x2F;h2&gt;
&lt;p&gt;ndarray のまま csv ファイルに保存してしまうと，ロード時に意図しない形式で処理ができなくなってしまうので，簡単な方法としては，事前にリストに変換してからデータフレームに入れることが望ましいです．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;recommend_items_list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;list&lt;&#x2F;span&gt;&lt;span&gt;(arr)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; arr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; df_rec[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;recommend_items&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_rec[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;recommend_items&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; recommend_items_list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(df_rec[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;recommend_items&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_rec.to_csv(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;.&#x2F;tmp_recommend_results2.csv&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; index&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;False&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tmp_df_rec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd.read_csv(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;.&#x2F;tmp_recommend_results2.csv&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(tmp_df_rec[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;recommend_items&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;str&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;リストに変換してから csv ファイルで保存すると，値は文字列になります．リストとして再度使いたい場合は，以下のように組み込み関数の &lt;code&gt;eval()&lt;&#x2F;code&gt; か，&lt;code&gt;ast.literal_eval()&lt;&#x2F;code&gt; を使って文字列をリストに変換するのが良いです．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; ast&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# 以下のどちらかを使うと良い&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tmp_df_rec[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;recommend_items&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tmp_df_rec[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;recommend_items&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;].apply(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;eval&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tmp_df_rec[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;recommend_items&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tmp_df_rec[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;recommend_items&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;].apply(ast.literal_eval)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(tmp_df_rec[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;recommend_items&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;])))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;eval()&lt;&#x2F;code&gt; と &lt;code&gt;ast.literal_eval()&lt;&#x2F;code&gt; の違いは，&lt;code&gt;ast.literal_eval()&lt;&#x2F;code&gt; はリテラルのみを含む式を評価するのに対して，&lt;code&gt;eval()&lt;&#x2F;code&gt; はリテラルに加え変数およびそれらの演算を含んだ式を評価することができます．&lt;&#x2F;p&gt;
&lt;p&gt;これでリストとして元の値を使うことができます．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回の事象に全然気づかずにそのままデータを保存していて，いざ分析しようとした時に，あれ？なんかおかしいぞとなり発覚しました．正規表現などを使えば無理やりできるのかもしれませんが，あまり好ましいやり方ではないと思うので，今回のように忘れずにリストに変換するのが良いと思います．&lt;&#x2F;p&gt;
&lt;p&gt;あとはそもそも csv ファイルに保存せずに別のファイル形式で保存するやり方もあります．エンジニアリング的には pickle ファイルの方が好ましいと感じます．&lt;&#x2F;p&gt;
&lt;p&gt;最近 csv ファイル絡みでの予期せぬことに遭遇することが多くて嫌になりつつあります...😅&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;note.nkmk.me&#x2F;python-ast-literal-eval&#x2F;&quot;&gt;Pythonのast.literal_eval()で文字列をリストや辞書に変換&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>2023年の個人目標を立てた💪</title>
        <published>2023-01-28T00:00:00+00:00</published>
        <updated>2023-01-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/personal-goals-for-2023/"/>
        <id>https://masatakashiwagi.com/blog/personal-goals-for-2023/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/personal-goals-for-2023/">&lt;p&gt;年初に立てようと思っていた2023年の個人目標が，あれよあれよと2月に入ろうとしているので，慌ててまだ間に合う1月中にブログに残しておこうと思います😅&lt;&#x2F;p&gt;
&lt;p&gt;定性的に「ほげほげを頑張るぞー！」とかでもいいですが，どちらかというと定量的なものを立てようと思います！あとで差分を計測しやすいからです．iPad で書いた直筆のものを載せようと思いましたが，編集しやすいように列挙して書きます笑&lt;&#x2F;p&gt;
&lt;p&gt;これは個人目標なので，仕事とは完全に切り離したプライベートの目標にしています．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2023nian-noge-ren-mu-biao&quot;&gt;2023年の個人目標&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;書籍を毎月最低1冊読む&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;毎月というのが大事で，継続して読み続けたいです&lt;&#x2F;li&gt;
&lt;li&gt;工夫ポイント：毎日仕事を始める前の30分や就寝前の時間を利用します！（個人スケジュールに入れておきます）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;毎日ダンベル上げ50回以上の筋トレ&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;年々体力が衰えてきていて，子供を抱っこしたりするとすぐに疲れてしまうので，腕の筋力を中心にまずはつけたいです&lt;&#x2F;li&gt;
&lt;li&gt;工夫ポイント：毎日休憩中には必ずダンベルを上げるようにするのと，それを妻に宣言しやっていなかったら指摘してもらいます&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;ブログ12本&lt;&#x2F;strong&gt;（できれば毎月1本，技術的な記事をメインに）
&lt;ul&gt;
&lt;li&gt;日頃から情報を収集するのはもちろんですが，実際に手を動かす部分を臆せずやりたいです&lt;&#x2F;li&gt;
&lt;li&gt;工夫ポイント：あまり記事の長さは気にしません（しっかりしたものを残そうというよりは自分の備忘録程度ぐらいのノリで）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;家族と毎月記念になる遊びや行事をする！&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;人生いつどうなるかわからないので，毎月家族との思い出をしっかり残します（よく寝てよく遊ぶ！）&lt;&#x2F;li&gt;
&lt;li&gt;工夫ポイント：面白そうな場所やイベントをキュレートしながら，積極的に動きます！&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Twitter のフォロワー1000人！&lt;&#x2F;strong&gt;（あと40人ぐらい）
&lt;ul&gt;
&lt;li&gt;工夫ポイント：地道に読んだ技術記事の情報などを流していきます&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;fan-wai-bian&quot;&gt;番外編&lt;&#x2F;h3&gt;
&lt;p&gt;メインの目標は上に置いたものかなと思いつつ番外編として，&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Podcast を2023年も継続する&lt;&#x2F;li&gt;
&lt;li&gt;イベント登壇を年間5件以上する（既に2件達成🎉）&lt;&#x2F;li&gt;
&lt;li&gt;プログラミング言語の Go を勉強して使えるようになる&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;なども頑張っていきたいです！&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;1月が終わる前に一旦目標を置くことが出来たので，これを意識しつつ頑張って行きます！めっちゃ色々と目標を立ててしまった感がありますが...&lt;&#x2F;p&gt;
&lt;p&gt;今年の年末にどれぐらい達成しているか楽しみです！😇（フラグ...）&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>「JAWS-UG AI&#x2F;ML」と「プロダクト開発での苦労話をする」で登壇した感想</title>
        <published>2023-01-27T00:00:00+00:00</published>
        <updated>2023-01-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/speaking-at-jawsug-aiml15-and-products-hardship-story/"/>
        <id>https://masatakashiwagi.com/blog/speaking-at-jawsug-aiml15-and-products-hardship-story/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/speaking-at-jawsug-aiml15-and-products-hardship-story/">&lt;p&gt;先週今週と2週連続でイベント登壇したので，その感想を備忘録がてら残しておこうと思います．ちなみに今週は勉強会での運営司会もやっていて非常に疲れました😇&lt;&#x2F;p&gt;
&lt;p&gt;イベントは以下の2つでした．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;2023年1月17日: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jawsug-ai.connpass.com&#x2F;event&#x2F;263957&#x2F;&quot;&gt;JAWS-UG AI&#x2F;ML #15&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;2023年1月26日: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kanmu.connpass.com&#x2F;event&#x2F;270440&#x2F;&quot;&gt;MoT&#x2F;コネヒト&#x2F;Kanmu が語るプロダクト開発xデータ分析&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;deng-tan-sitemite&quot;&gt;登壇してみて&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;jaws-ug-ai-ml-15-denodeng-tan&quot;&gt;「JAWS-UG AI&#x2F;ML #15」での登壇&lt;&#x2F;h3&gt;
&lt;p&gt;1つ目は AWS の AI&#x2F;ML のユーザーグループのイベントで，10分間の LT をしてきました．&lt;&#x2F;p&gt;
&lt;p&gt;内容としては，以前テックブログでも紹介した SageMaker Experiments で始める機械学習モデルのミニマムな実験管理という内容です．ただ，去年の12月に AWS re:Invent 2022 が開催されて，その後 SageMaker 関連にもアップデートが色々と入り，その一つに SageMaker Experiments の大幅アップデートがあって，以前とは見違えるほど使いやすくなったという情報を届けることが出来なかったのは残念でした（検証間に合わなかったです）．&lt;&#x2F;p&gt;
&lt;p&gt;僕の発表内容は，アップデート以前の情報が含まれていて，Experiments 特有のお作法や枠組みの話もしたのですが，今回のアップデートでよりモダンな方法で簡単に情報を記録できるようになったみたいです．あと何気に UI がリッチになっていてめっちゃ見やすくなったので，時間があれば確認しておきたいなと思います！&lt;&#x2F;p&gt;
&lt;p&gt;当日は，以前から交流がある杉山さんや Twitter で絡みがあった AWS の本橋さんとご一緒出来てとても熱かったです！&lt;&#x2F;p&gt;
&lt;p&gt;本橋さんからは SageMaker 関連のアップデートの話が聞けたり，杉山さんからは &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;wellarchitected&#x2F;latest&#x2F;machine-learning-lens&#x2F;machine-learning-lens.html&quot;&gt;Machine Learning Lens&lt;&#x2F;a&gt; の話を杉山さん目線での思いなども含めて聞けたので，とても参考になりました！僕もこのドキュメントは目を通しておきたいなと改めて話を聞いて思いました．&lt;&#x2F;p&gt;
&lt;script async class=&quot;speakerdeck-embed&quot; data-id=&quot;759b3046628b48e7aac423cc6f91b374&quot; data-ratio=&quot;1.77725118483412&quot; src=&quot;&#x2F;&#x2F;speakerdeck.com&#x2F;assets&#x2F;embed.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;h3 id=&quot;mot-konehito-kanmu-gayu-rupurodakutokai-fa-xdetafen-xi-denodeng-tan&quot;&gt;「MoT&#x2F;コネヒト&#x2F;Kanmu が語るプロダクト開発xデータ分析」での登壇&lt;&#x2F;h3&gt;
&lt;p&gt;2つ目は以前オンライン飲み会をした際に流れで決まったイベントで20分間話してきました．以前から Twitter で知り合っていてオフラインでも飲みに行ったことがあるメンツだったので，軽いノリでイベントしましょうとなった感じです（笑）&lt;&#x2F;p&gt;
&lt;p&gt;パネルディスカッションは初めてだったので，どういった流れかあまり把握してなかったのですが，お互いの発表を聞いての質問を投げる感じで進んで行きました． Twitter とかの質問を拾ったりもできるとより良かったのかなとも思いますが，運営をやってる身としては，進行は色々と大変で余裕がなかったりもするので，事前に流れを決めてても良かったかもしれません．&lt;&#x2F;p&gt;
&lt;p&gt;内容は今の会社で経験した様々なロールでの立ち振る舞い，やるべきことが多くてコンテキストの切り替えなど苦労した部分があったので，取り組みと大変だった部分をいくつか紹介できて良かったかなと思います．&lt;&#x2F;p&gt;
&lt;script async class=&quot;speakerdeck-embed&quot; data-id=&quot;c811197258284a77b1754190e90df2c4&quot; data-ratio=&quot;1.77725118483412&quot; src=&quot;&#x2F;&#x2F;speakerdeck.com&#x2F;assets&#x2F;embed.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;ここ1,2週間は登壇もあったのですが，色々と業務以外の時間でもスライド作成などしていたので，疲れたというのもあり，久しぶりにイベント後は檸檬堂のはちみつレモンを飲みました😇&lt;&#x2F;p&gt;
&lt;p&gt;勉強会やイベント登壇中は家事を出来ないので，妻に子供のお風呂・ご飯・寝かしつけという3大育児をお願いすることになって負担をかけたので，しばらくはのんびり過ごそうと思います🙇‍♂️&lt;&#x2F;p&gt;
&lt;p&gt;もし，依頼があれば対応したいのですが，家族に相談してからにしようと思います（笑）&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet tw-align-center&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;流石に2週連続登壇&amp;amp;運営司会やると色々と疲れた。家族にも負担かけたので、当分はひっそりしておこうと思います笑&lt;&#x2F;p&gt;&amp;mdash; asteriam (@asteriam_fp) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asteriam_fp&#x2F;status&#x2F;1618585734377791488?ref_src=twsrc%5Etfw&quot;&gt;January 26, 2023&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Step Functions から Glue のジョブパラメータを指定して実行する方法</title>
        <published>2022-11-16T00:00:00+00:00</published>
        <updated>2022-11-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/glue-job-params-and-stepfunctions-execution/"/>
        <id>https://masatakashiwagi.com/blog/glue-job-params-and-stepfunctions-execution/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/glue-job-params-and-stepfunctions-execution/">&lt;p&gt;Glue を使ってデータ連携する際に，例えばデータ連携したい期間を変えたり，環境情報を渡したり，パラメータを与えて実行したい場合の方法に関する備忘録を書きました．特に，Step Functions (SFn) 経由で Glue を実行する場合に，インプットパラメータに必要な情報を渡してそれを Glue にどう紐付けるかに関する内容になっています．今回の内容は，実務で発生した検索エンジンのインデックスに簡単にデータを流せるように，SFn のパイプラインのインプットにパラメータを渡すだけで実行できるようにしたかったので，その時に実施した内容です．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;glue-noziyobuparametashe-ding&quot;&gt;Glue のジョブパラメータ設定&lt;&#x2F;h2&gt;
&lt;p&gt;ジョブパラメータは Glue 実行時に渡すことができるパラメータで，デフォルトでもいくつか用意されています（参考：&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;glue&#x2F;latest&#x2F;dg&#x2F;aws-glue-programming-etl-glue-arguments.html&quot;&gt;Job parameters used by AWS Glue&lt;&#x2F;a&gt;）．&lt;&#x2F;p&gt;
&lt;p&gt;これに自前で用意したパラメータを受け取りたい場合，&lt;code&gt;getResolvedOptions&lt;&#x2F;code&gt; の第二引数にリストに渡されてくるパラメータを定義します．これは後ほどの SFn のインプットに与えて Glue で受け取ります．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# JobName: sample_glue_job&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; sys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; awsglue.utils&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; getResolvedOptions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# 動的に切り替えたい or 環境により変化する部分をパラメータとして受け取る&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; getResolvedOptions(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sys.argv,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;period_date&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;index_name&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# データ連携したい期間&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;period_date&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;(args[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;period_date&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# データを投入する検索エンジンのインデックス名&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;index_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; args[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;index_name&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;...&lt;&#x2F;span&gt;&lt;span&gt;(実際の処理が続く)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;パラメータは文字列のみ&lt;&#x2F;strong&gt;しか受け付けないので，期間を数値で使いたい場合は，上記コードのように数値型に変換する必要があります．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-functions-no-input-nidetawodu-site-glue-deshi-ufang-fa&quot;&gt;Step Functions の input にデータを渡して Glue で使う方法&lt;&#x2F;h2&gt;
&lt;p&gt;Glue ジョブが作成できたら，それを Step Functions で動かしていきます．以下に Step Functions の State Machine のサンプルコードを載せていますが，ポイントは &lt;code&gt;glue:startJobRun.sync&lt;&#x2F;code&gt; アクションの Parameters にある Arguments の設定になります．input パラメータを渡す場合は，&lt;code&gt;$&lt;&#x2F;code&gt;を key の末尾と value の先頭に付与する必要があります（参考：&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;step-functions&#x2F;latest&#x2F;dg&#x2F;connect-parameters.html&quot;&gt;Pass Parameters to a Service API&lt;&#x2F;a&gt;）．&lt;&#x2F;p&gt;
&lt;p&gt;また，key の先頭に&lt;code&gt;--&lt;&#x2F;code&gt;を付与しないとパラメータと認識されずにエラーになります．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Glueでデータ連携を行うステートマシン&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;StartAt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Glue-Job&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;States&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Glue-Job&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::glue:startJobRun.sync&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        &amp;quot;JobName&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;sample_glue_job&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        &amp;quot;Arguments&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;--period_date.$&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.period_date&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;--index_name.$&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.index_name&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Catch&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;ErrorEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;            &amp;quot;States.ALL&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;FailState&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;データ連携用のGlueジョブ&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Success&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Success&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Succeed&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;FailState&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Fail&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Cause&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Error&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Error&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Error&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;SFn のコンソールから実行する場合，下図のように実行前の画面で JSON 形式で必要なパラメータを渡すことで，SFn で定義した Glue のジョブパラメータに値がセットされます．今回の場合だと，&lt;code&gt;period_date&lt;&#x2F;code&gt; と &lt;code&gt;index_name&lt;&#x2F;code&gt; をパラメータとして SFn の input から渡して，Glue でそれらを受け取り ETL 処理を実行していきます．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;glue_job_params_and_stepfunctions_execution&#x2F;glue-job-params-sfn-img1.png&quot; alt=&quot;SFn のコンソール実行画面&quot; title=&quot;SFn のコンソール実行画面&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は Step Functions の input パラメータを変更することで，簡単に Glue のジョブパラメータに値を渡してパイプラインを実行する方法を紹介しました．Glue Studio からコードを直接変更することでもできますが，毎回コードを変更するのはバグが混入する可能性もあるので，パイプライン実行時の input で制御できた方が汎用性があり，シンプルかなと思い試してみました．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;glue&#x2F;latest&#x2F;dg&#x2F;aws-glue-programming-etl-glue-arguments.html&quot;&gt;Job parameters used by AWS Glue&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;step-functions&#x2F;latest&#x2F;dg&#x2F;connect-parameters.html&quot;&gt;Pass Parameters to a Service API&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Step Functions での Opensearch Package の更新は直列 or 並列どちらが良いか？</title>
        <published>2022-10-29T00:00:00+00:00</published>
        <updated>2022-10-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/series-or-parallel-pipeline-for-updating-opensearch-package/"/>
        <id>https://masatakashiwagi.com/blog/series-or-parallel-pipeline-for-updating-opensearch-package/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/series-or-parallel-pipeline-for-updating-opensearch-package/">&lt;p&gt;OpenSearch の Package 更新，つまりユーザー辞書やシノニム辞書の更新を Step Functions で行う場合に，直列で行うのが良いか並列で行うのが良いかメモ程度の備忘録として残しておきます．&lt;&#x2F;p&gt;
&lt;p&gt;結論としては，OpenSearch の Package 更新は同時に複数更新すると，関連付けでエラーが発生する可能性があるので，&lt;strong&gt;直列&lt;&#x2F;strong&gt;でパイプラインを組みのが良さそうです．特にインスタンススペックが低いとドメインへの負荷でエラーになる可能性が高くなります．&lt;&#x2F;p&gt;
&lt;p&gt;以下のようなエラーが発生する場合があります．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;series_or_parallel_pipeline_for_updating_opensearch_package&#x2F;opensearch-error-img1.png&quot; alt=&quot;関連付けエラー&quot; title=&quot;関連付けエラー&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-functions-niyoruci-shu-geng-xin-paipurain&quot;&gt;Step Functions による辞書更新パイプライン&lt;&#x2F;h2&gt;
&lt;p&gt;まず初めに OpenSearch の Package を API で更新する手順を説明すると&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;OpenSearch: UpdatePackage&lt;&#x2F;code&gt;: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;ja_jp&#x2F;cli&#x2F;latest&#x2F;reference&#x2F;opensearch&#x2F;update-package.html&quot;&gt;update-package&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;API パラメータとして以下の JSON を渡す&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;OpenSearchのドメインに関連付けられたパッケージの内部ID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;PackageSource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;S3BucketName&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージが置かれているバケット名&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;S3Key&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージのファイル名&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;OpenSearch: AssociatePackage&lt;&#x2F;code&gt;: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;ja_jp&#x2F;cli&#x2F;latest&#x2F;reference&#x2F;opensearch&#x2F;associate-package.html&quot;&gt;associate-package&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;APIパラメータとして以下の JSON を渡す&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;DomainName&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;関連付けを行う OpenSearch のドメイン名&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;OpenSearch のドメインに関連付けられたパッケージの内部 ID &amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;この2つを実行するだけです．&lt;&#x2F;p&gt;
&lt;p&gt;一方で，それぞれのAPIを実行すると処理が走りますが，更新や関連付けには一定の時間が必要になります．そのため，&lt;code&gt;OpenSearch: ListDomainsForPackage&lt;&#x2F;code&gt; でドメインとパッケージの状態を確認し，&lt;code&gt;ACTIVE&lt;&#x2F;code&gt; 状態になったら次の処理を実行していきます．&lt;&#x2F;p&gt;
&lt;p&gt;これ踏まえて，ユーザー辞書とシノニム辞書の2つを更新する処理を直列と並列それぞれ実装してみます．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;zhi-lie-depaipurainwozu-ndachang-he&quot;&gt;直列でパイプラインを組んだ場合&lt;&#x2F;h3&gt;
&lt;p&gt;ユーザー辞書を更新した後にシノニム辞書の更新を行うパイプラインを用意します．&lt;&#x2F;p&gt;
&lt;details&gt;
&lt;summary&gt;直列パイプライン - DSL&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;全量データの同期と辞書更新のジョブ&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;StartAt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Update-Package-User-Dict&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;States&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Update-Package-User-Dict&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        &amp;quot;PackageSource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;S3BucketName&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;バケット名&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;S3Key&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;ファイル名&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::aws-sdk:opensearch:updatePackage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのアップデート&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Catch&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;ErrorEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;            &amp;quot;States.ALL&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;NotifySlackFailure&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;List-Domains-For-Package-User1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;List-Domains-For-Package-User1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::aws-sdk:opensearch:listDomainsForPackage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのステータス確認&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Choice-Package-Active-Check-User1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Choice-Package-Active-Check-User1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Choice&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Choices&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Variable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.DomainPackageDetailsList[0].DomainPackageStatus&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;StringEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;ACTIVE&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Associate-Package-User&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Default&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Wait-User1-10s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのステータスに応じた処理の分岐&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Associate-Package-User&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        &amp;quot;DomainName&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;ドメイン名&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::aws-sdk:opensearch:associatePackage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Catch&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;ErrorEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;            &amp;quot;States.ALL&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;NotifySlackFailure&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;List-Domains-For-Package-User2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージの関連付けを行う&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;List-Domains-For-Package-User2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::aws-sdk:opensearch:listDomainsForPackage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのステータス確認&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Choice-Package-Active-Check-User2&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Choice-Package-Active-Check-User2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Choice&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Choices&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Variable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.DomainPackageDetailsList[0].DomainPackageStatus&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;StringEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;ACTIVE&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Pass&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Variable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.DomainPackageDetailsList[0].DomainPackageStatus&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;StringEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;ASSOCIATION_FAILED&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;NotifySlackFailure&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Default&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Wait-User2-60s&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Pass&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Pass&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Update-Package-Synonym-Dict&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Update-Package-Synonym-Dict&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        &amp;quot;PackageSource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;S3BucketName&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;バケット名&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;S3Key&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;ファイル名&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::aws-sdk:opensearch:updatePackage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Catch&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;ErrorEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;            &amp;quot;States.ALL&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;NotifySlackFailure&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;List-Domains-For-Package-Synonym1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのアップデート&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;List-Domains-For-Package-Synonym1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::aws-sdk:opensearch:listDomainsForPackage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのステータス確認&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Choice-Package-Active-Check-Synonym1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Choice-Package-Active-Check-Synonym1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Choice&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Choices&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Variable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.DomainPackageDetailsList[0].DomainPackageStatus&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;StringEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;ACTIVE&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Associate-Package-Synonym&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Default&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Wait-Synonym1-10s&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Associate-Package-Synonym&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        &amp;quot;DomainName&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;ドメイン名&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::aws-sdk:opensearch:associatePackage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Catch&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;ErrorEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;            &amp;quot;States.ALL&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;NotifySlackFailure&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;List-Domains-For-Package-Synonym2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージの関連付けを行う&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;List-Domains-For-Package-Synonym2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::aws-sdk:opensearch:listDomainsForPackage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのステータス確認&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Choice-Package-Active-Check-Synonym2&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Choice-Package-Active-Check-Synonym2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Choice&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Choices&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Variable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.DomainPackageDetailsList[0].DomainPackageStatus&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;StringEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;ACTIVE&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Success-Associate-Package-Synonym&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Variable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.DomainPackageDetailsList[0].DomainPackageStatus&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;StringEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;ASSOCIATION_FAILED&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;NotifySlackFailure&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Default&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Wait-Synonym2-60s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのステータスに応じた処理の分岐&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Success-Associate-Package-Synonym&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Succeed&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Wait-Synonym2-60s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Wait&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Seconds&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;List-Domains-For-Package-Synonym2&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Wait-Synonym1-10s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Wait&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Seconds&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;待機&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;List-Domains-For-Package-Synonym1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Wait-User2-60s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Wait&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Seconds&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;List-Domains-For-Package-User2&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Wait-User1-10s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Wait&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Seconds&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;待機&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;List-Domains-For-Package-User1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;NotifySlackFailure&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::lambda:invoke&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;OutputPath&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.Payload&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        &amp;quot;Payload.$&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        &amp;quot;FunctionName&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;LambdaのARN&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Retry&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;ErrorEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;            &amp;quot;Lambda.ServiceException&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;            &amp;quot;Lambda.AWSLambdaException&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;            &amp;quot;Lambda.SdkClientException&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;IntervalSeconds&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;MaxAttempts&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;BackoffRate&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;処理失敗のslack通知&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;FailState&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;FailState&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Fail&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Error&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Error&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Cause&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Error&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;series_or_parallel_pipeline_for_updating_opensearch_package&#x2F;stepfunctions-series-img1.png&quot; alt=&quot;直列パイプライン&quot; title=&quot;直列パイプライン&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bing-lie-depaipurainwozu-ndachang-he&quot;&gt;並列でパイプラインを組んだ場合&lt;&#x2F;h3&gt;
&lt;p&gt;ユーザー辞書とシノニム辞書の更新を同時に実行するパイプラインを用意します．&lt;&#x2F;p&gt;
&lt;details&gt;
&lt;summary&gt;並列パイプライン - DSL&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;全量データの同期と辞書更新のジョブ&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;StartAt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Parallel&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;States&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;Parallel&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Parallel&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;Branches&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;StartAt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Update-Package-User-Dict&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;States&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;Update-Package-User-Dict&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                &amp;quot;PackageSource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;S3BucketName&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;バケット名&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;S3Key&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;ファイル名&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::aws-sdk:opensearch:updatePackage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのアップデート&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;List-Domains-For-Package-User1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Catch&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;ErrorEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;                    &amp;quot;States.ALL&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;NotifySlackFailure1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;NotifySlackFailure1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::lambda:invoke&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;OutputPath&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.Payload&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                &amp;quot;Payload.$&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                &amp;quot;FunctionName&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;LambdaのARN&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Retry&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;ErrorEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;                    &amp;quot;Lambda.ServiceException&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;                    &amp;quot;Lambda.AWSLambdaException&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;                    &amp;quot;Lambda.SdkClientException&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;IntervalSeconds&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;MaxAttempts&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;BackoffRate&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;処理失敗のslack通知&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;FailState1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;FailState1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Fail&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Error&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Error&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Cause&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Error&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;List-Domains-For-Package-User1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::aws-sdk:opensearch:listDomainsForPackage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのステータス確認&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Choice-Package-Active-Check-User1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;Choice-Package-Active-Check-User1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Choice&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Choices&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;Variable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.DomainPackageDetailsList[0].DomainPackageStatus&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;StringEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;ACTIVE&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Associate-Package-User&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Default&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Wait-User1-10s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのステータスに応じた処理の分岐&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;Associate-Package-User&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                &amp;quot;DomainName&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;ドメイン名&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::aws-sdk:opensearch:associatePackage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;List-Domains-For-Package-User2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Catch&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;ErrorEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;                    &amp;quot;States.ALL&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;NotifySlackFailure1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;List-Domains-For-Package-User2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::aws-sdk:opensearch:listDomainsForPackage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Choice-Package-Active-Check-User2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのステータス確認&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;Choice-Package-Active-Check-User2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Choice&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Choices&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;Variable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.DomainPackageDetailsList[0].DomainPackageStatus&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;StringEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;ACTIVE&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Success-Associate-Package-User&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;Variable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.DomainPackageDetailsList[0].DomainPackageStatus&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;StringEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;ASSOCIATION_FAILED&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;NotifySlackFailure1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Default&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Wait-User2-60s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのステータスに応じた処理の分岐&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;Success-Associate-Package-User&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Succeed&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;Wait-User2-60s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Wait&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Seconds&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;List-Domains-For-Package-User2&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;Wait-User1-10s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Wait&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Seconds&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;待機&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;List-Domains-For-Package-User1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;StartAt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Update-Package-Synonym-Dict&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;          &amp;quot;States&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;Update-Package-Synonym-Dict&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                &amp;quot;PackageSource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;S3BucketName&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;バケット名&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;S3Key&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;ファイル名&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::aws-sdk:opensearch:updatePackage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのアップデート&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;List-Domains-For-Package-Synonym1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Catch&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;ErrorEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;                    &amp;quot;States.ALL&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;NotifySlackFailure2&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;NotifySlackFailure2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::lambda:invoke&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;OutputPath&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.Payload&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                &amp;quot;Payload.$&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                &amp;quot;FunctionName&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;LambdaのARN&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Retry&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;ErrorEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;                    &amp;quot;Lambda.ServiceException&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;                    &amp;quot;Lambda.AWSLambdaException&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;                    &amp;quot;Lambda.SdkClientException&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;IntervalSeconds&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;MaxAttempts&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;BackoffRate&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;FailState2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;処理失敗のslack通知&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;FailState2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Fail&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Error&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Error&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Cause&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Error&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;List-Domains-For-Package-Synonym1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::aws-sdk:opensearch:listDomainsForPackage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのステータス確認&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Choice-Package-Active-Check-Synonym1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;Choice-Package-Active-Check-Synonym1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Choice&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Choices&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;Variable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.DomainPackageDetailsList[0].DomainPackageStatus&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;StringEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;ACTIVE&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Associate-Package-Synonym&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Default&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Wait-Synonym1-10s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのステータスに応じた処理の分岐&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;Associate-Package-Synonym&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                &amp;quot;DomainName&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;ドメイン名&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::aws-sdk:opensearch:associatePackage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;List-Domains-For-Package-Synonym2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Catch&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;ErrorEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;                    &amp;quot;States.ALL&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;NotifySlackFailure2&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;List-Domains-For-Package-Synonym2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                &amp;quot;PackageID&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&amp;lt;パッケージID&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;arn:aws:states:::aws-sdk:opensearch:listDomainsForPackage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Choice-Package-Active-Check-Synonym2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのステータス確認&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;Choice-Package-Active-Check-Synonym2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Choice&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Choices&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;Variable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.DomainPackageDetailsList[0].DomainPackageStatus&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;StringEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;ACTIVE&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Success-Associate-Package-Synonym&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;Variable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;$.DomainPackageDetailsList[0].DomainPackageStatus&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;StringEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;ASSOCIATION_FAILED&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                  &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;NotifySlackFailure2&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Default&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Wait-Synonym2-60s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;パッケージのステータスに応じた処理の分岐&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;Success-Associate-Package-Synonym&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Succeed&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;Wait-Synonym2-60s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Wait&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Seconds&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;List-Domains-For-Package-Synonym2&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;            &amp;quot;Wait-Synonym1-10s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;Wait&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Seconds&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;待機&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;              &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;List-Domains-For-Package-Synonym1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;End&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;series_or_parallel_pipeline_for_updating_opensearch_package&#x2F;stepfunctions-parallel-img2.png&quot; alt=&quot;並列パイプライン&quot; title=&quot;並列パイプライン&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;パイプライン内では &lt;code&gt;OpenSearch: ListDomainsForPackage&lt;&#x2F;code&gt; でパッケージの状況を確認し，ACTIVE 状態でない場合は数十秒の待機処理を入れてから再度確認する方法で更新を行っています．&lt;&#x2F;p&gt;
&lt;p&gt;辞書更新にかかる処理時間は5分以内ぐらいなので，より安全に実施できる直列で更新する方法に落ち着きました．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は OpenSearch の複数の辞書更新を Step Functions で行う場合に，直列で更新処理を組むのが良いか，並列で更新処理を組むのが良いかを考えてみました．より安全に実行するという観点で直列を選択するのが良さそうに思います．&lt;&#x2F;p&gt;
&lt;p&gt;パイプラインが長くなってしまいますが，辞書更新用の Step Functions を用意することで，この Step Functions をデータ同期のパイプラインのステップの1つとして組み込めば，処理単位でモジュール化することができるので，修正やデバッグもやりやすくなるはずです．&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>「JAWS DAYS 2022」で登壇した感想</title>
        <published>2022-10-10T00:00:00+00:00</published>
        <updated>2022-10-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/speaking-at-jawsdays-2022/"/>
        <id>https://masatakashiwagi.com/blog/speaking-at-jawsdays-2022/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/speaking-at-jawsdays-2022/">&lt;p&gt;今回初めて AWS のユーザーイベントである &quot;&lt;strong&gt;JAWS DAYS 2022&lt;&#x2F;strong&gt;&quot; で登壇させて頂いたので，その感想でも書こうと思います．&lt;&#x2F;p&gt;
&lt;p&gt;JAWS DAYS は毎年行われていて，今年は2022年10月8日（土）に開催されました．&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jawsdays2022.jaws-ug.jp&#x2F;&quot;&gt;AWS ユーザによる AWS ユーザのためのイベント JAWS DAYS 2022 - Satellite -&lt;&#x2F;a&gt; ということで，日本全国サテライト会場が用意されたり，オンラインとオフラインのハイブリッド開催のイベントです！&lt;&#x2F;p&gt;
&lt;p&gt;また，セッションは入門・初心者向けから中級・上級者向け，事例やハンズオンなど様々な種類の講演が行われていて，とても盛り上がったイベントでした！ Twitter のハッシュタグ「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;search?q=jawsdays2022&quot;&gt;#jawsdays2022&lt;&#x2F;a&gt;」などでその様子がわかると思います．&lt;&#x2F;p&gt;
&lt;p&gt;僕は事例紹介というセッションで，「&lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jawsdays2022.jaws-ug.jp&#x2F;sessions&#x2F;A11&#x2F;&quot;&gt;AWS のマネージドサービスで実現するニアリアルタイムな検索基盤&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;」というタイトルで目黒にある AWS の会場にて発表してきました．&lt;&#x2F;p&gt;
&lt;script async class=&quot;speakerdeck-embed&quot; data-id=&quot;344ccae722a1405caf2a3cfbdec08adc&quot; data-ratio=&quot;1.77725118483412&quot; src=&quot;&#x2F;&#x2F;speakerdeck.com&#x2F;assets&#x2F;embed.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;h2 id=&quot;deng-tan-sitemite&quot;&gt;登壇してみて&lt;&#x2F;h2&gt;
&lt;p&gt;今まで，今回のようなユーザーイベントで登壇した経験はなかったので，学生時代の物理学会で発表して以来の感覚でした😊&lt;&#x2F;p&gt;
&lt;p&gt;最近はコロナでオンラインでの発表が主流になっていたので，会場の雰囲気などを味わう経験はできなかったのですが，今回は AWS の会場で聴衆はスタッフや他の登壇者の方々に限られてはいたものの，&quot;&lt;strong&gt;イベントで登壇する&lt;&#x2F;strong&gt;&quot; という感覚になれたのはとても良い体験でした！&lt;&#x2F;p&gt;
&lt;p&gt;発表に関しては，35分の登壇時間があったのですが，33分ぐらいで話し切ってしまったので，ちょっと早く話し過ぎたなというのと，緊張もあり少し早口になってしまったかなーと反省しています😇&lt;&#x2F;p&gt;
&lt;p&gt;今回の登壇では，直近携わっている検索システムの話をしっかり紹介することができたので，今会社でどういった取り組みをしているのかを知って貰えたかなと思います．&lt;&#x2F;p&gt;
&lt;p&gt;オーディエンスの反応は Twitter で色々と流れていて，登壇内容に関して良い反応をして頂けてたみたいで嬉しい限りです！&lt;&#x2F;p&gt;
&lt;h3 id=&quot;shao-sidakedeng-tan-nei-rong-nituitemo&quot;&gt;少しだけ登壇内容についても&lt;&#x2F;h3&gt;
&lt;p&gt;今回の取り組みは &quot;&lt;strong&gt;検索&lt;&#x2F;strong&gt;&quot; という今まで経験がなかった領域で，検索基盤の整備をほぼ一人で構築していったので，タフな仕事でした．&lt;&#x2F;p&gt;
&lt;p&gt;Glue, OpenSearch は意外と初めて触れるサービスだったりしたので，どう扱っていくか考えたり今回のシステムの肝である「&lt;strong&gt;ニアリアルタイム&lt;&#x2F;strong&gt;」なデータ同期を AWS のマネージドサービスを組み合わせてどう実現するかを設計したり検証したりとチャレンジングでした．&lt;&#x2F;p&gt;
&lt;p&gt;結果的には，「&lt;u&gt;ワークフロー&#x2F;パイプラインの設計&lt;&#x2F;u&gt;」や「&lt;u&gt;OpenSeach のインデックスの切り替え&lt;&#x2F;u&gt;」など工夫した仕組みで，自信を持てる良い仕上がりになってるのではないかと我ながら思います．&lt;&#x2F;p&gt;
&lt;p&gt;取り組みとしてはまだまだ始まったばっかりなので，これから &quot;&lt;u&gt;検索体験の向上&lt;&#x2F;u&gt;&quot; や &quot;&lt;u&gt;より堅牢な検索基盤の構築・運用&lt;&#x2F;u&gt;&quot; に力を入れて改善サイクルを回していきたいと思います．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回のプロジェクトは育業後（育業の記事は&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masatakashiwagi.com&#x2F;blog&#x2F;first-childcare-leave&#x2F;&quot;&gt;こちら&lt;&#x2F;a&gt;）すぐに取り掛かったプロジェクトで，子育てと仕事のバランスを上手く掴めるかな？と不安な面もありましたが，リモートワークというのもあり，夕方早めに仕事を切り上げて，直ぐに子育ての方に移ることができたのは大きかったです．特に子供が小さいうちはリモートワークで引き続き仕事をしていきたいと感じました．&lt;&#x2F;p&gt;
&lt;p&gt;登壇などの外部発信については，これからも業務で得た知見や事例をどんどん外部に発信して，色々な方と交流・ディスカッションできればと思います．あとは，オーディエンスの方々がいる場所でも登壇できると楽しいだろうなと思うので，コロナとの兼ね合いはあるものの今度はそういった機会でも登壇したいと感じました！&lt;&#x2F;p&gt;
&lt;p&gt;P.S. 今回の事例に関して質問・疑問があれば，是非色々と聞いて頂ければと思うので，Twitter なりで絡んで貰えると嬉しいです😆&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Airbyte でスプレッドシートのデータを BigQuery に連携</title>
        <published>2022-09-29T00:00:00+00:00</published>
        <updated>2022-09-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/airbyte-for-data-integration/"/>
        <id>https://masatakashiwagi.com/blog/airbyte-for-data-integration/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/airbyte-for-data-integration/">&lt;p&gt;以前から気になっていた OSS の **&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;airbyte.com&#x2F;&quot;&gt;Airbyte&lt;&#x2F;a&gt; という EL に特化した Data Integration ツールを使ってみたかったので，今回はこれを使って以前 Embulk で実装していたスプレッドシートから BigQuery へのデータ同期処理と同じことができるか試してみました．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masatakashiwagi.com&#x2F;blog&#x2F;integrate-spreadsheets-to-bigquery-with-digdag&#x2F;&quot;&gt;スプレッドシートから BigQuery へ Digdag を使ったデータ連携&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Airbyte は良い感じのUIがあるので，UI をポチポチしながら設定していきます．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;airbytetoha&quot;&gt;Airbyteとは？&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;airbyte_for_data_integration&#x2F;airbyte-img1.png&quot; alt=&quot;Airbyte&quot; title=&quot;Airbyte&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;iframe class=&quot;hatenablogcard&quot; style=&quot;width:100%;height:155px;max-width:680px;&quot; title=&quot;airbytehq&#x2F;airbyte&quot; src=&quot;https:&#x2F;&#x2F;hatenablog-parts.com&#x2F;embed?url=https:&#x2F;&#x2F;github.com&#x2F;airbytehq&#x2F;airbyte&quot; width=&quot;300&quot; height=&quot;150&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;Airbyte は OSS の ETL ツールで，特に Extract と Load に注力しているツールになっています．豊富なデータソース（&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;airbyte.gitbook.io&#x2F;airbyte&#x2F;integrations&#x2F;sources&quot;&gt;Source&lt;&#x2F;a&gt;）とターゲットソース（&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;airbyte.gitbook.io&#x2F;airbyte&#x2F;integrations&#x2F;destinations&quot;&gt;Destination&lt;&#x2F;a&gt;）に対応していて，これらを設定することでデータを簡単に連携できます．Transform 部分は内部的には dbt を使ってハンドリングしているみたいです．（&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;airbyte.gitbook.io&#x2F;airbyte&#x2F;operator-guides&#x2F;transformation-and-normalization&#x2F;transformations-with-sql&quot;&gt;Transformations with SQL (Part 1&#x2F;3)&lt;&#x2F;a&gt;）&lt;&#x2F;p&gt;
&lt;p&gt;提供形態としては，OSS とマネージドサービス（クラウド版: 有料）があり，ローカルをはじめ AWS&#x2F;GCP&#x2F;Azure と各種クラウドサービスでデプロイできます（参考: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;airbyte.gitbook.io&#x2F;airbyte&#x2F;deploying-airbyte&quot;&gt;Deploying Airbyte Open Source&lt;&#x2F;a&gt;）．&lt;&#x2F;p&gt;
&lt;p&gt;Connector は既に用意されているもの（&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;airbytehq&#x2F;airbyte&#x2F;tree&#x2F;master&#x2F;airbyte-integrations&#x2F;connectors&quot;&gt;airbyte&#x2F;airbyte-integrations&#x2F;connectors&#x2F;&lt;&#x2F;a&gt;）もあれば，独自で作成することもできるようになっています．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;supuretudositokara-bigquery-nilian-xi&quot;&gt;スプレッドシートから BigQuery に連携&lt;&#x2F;h2&gt;
&lt;p&gt;基本的には，Tutorial に沿って進めていく．まずは &lt;code&gt;git clone&lt;&#x2F;code&gt; して UI を立ち上げます．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; clone https:&#x2F;&#x2F;github.com&#x2F;airbytehq&#x2F;airbyte.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; airbyte&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; compose up&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;docker compose&lt;&#x2F;code&gt; を実行したら，&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;localhost:8000&quot;&gt;http:&#x2F;&#x2F;localhost:8000&lt;&#x2F;a&gt; で UI にアクセスすることができて，ここからは UI の世界で全て完結することができます！&lt;&#x2F;p&gt;
&lt;h3 id=&quot;source&quot;&gt;Source&lt;&#x2F;h3&gt;
&lt;p&gt;案内に従って進めると，まずプルダウンから今回のデータソースである Google Sheets を Source type として選択します．右側に Setup Guide があるので，それを見ながら設定できて親切設計になっています．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;airbyte_for_data_integration&#x2F;airbyte-img2.png&quot; alt=&quot;Google Sheets&quot; title=&quot;Google Sheets&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;以下の設定を埋めていきます．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Source name&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;「Google Sheets」としている&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Authentication&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;GCP のサービスアカウントを設定する．json ファイルの中身をコピーして貼り付ける&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;cat ~&#x2F;.gcp&#x2F;hoge_service_account.json | pbcopy&lt;&#x2F;code&gt; でクリップボードにコピーするとやりやすい&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Row Batch Size&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;デフォルトの200にしている&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Spreadsheet Link&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;対象となるスプレッドシートの URL を設定する&lt;&#x2F;li&gt;
&lt;li&gt;事前にサービスアカウントでのアクセスを許可しておく必要がある&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;destination&quot;&gt;Destination&lt;&#x2F;h3&gt;
&lt;p&gt;次に，プルダウンからターゲットソースである BigQuery を Destination type として選択します．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;airbyte_for_data_integration&#x2F;airbyte-img3.png&quot; alt=&quot;BigQuery&quot; title=&quot;BigQuery&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;以下の設定を埋めていきます．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Destination name&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;「BigQuery」としている&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Project ID&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;GCP にアクセスして現在使っているプロジェクト ID を設定する&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Dataset Location&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;「US」で良さそう？&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Default Dataset ID&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;BigQuery のデータセットとして作成される ID になる&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Loading Method&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;Standard Inserts と GCS Staging の2種類ある&lt;&#x2F;li&gt;
&lt;li&gt;Standard Inserts
&lt;ul&gt;
&lt;li&gt;SQL INSERT で直接アップロードする方法で，非効率的なため GCS Staging を推奨している（今回はこちらを選択）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;GCS Staging
&lt;ul&gt;
&lt;li&gt;ファイルにレコードを書き込み，そのファイルを GCS にアップロードし，その後 COPY INTO テーブルを使用してファイルをアップロードする方法（GCS のバケットなどの情報が必要になる）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Service Account Key JSON (Required for cloud, optional for open-source)&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;GCP のサービスアカウントを設定する．json ファイルの中身をコピーして貼り付ける&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Transformation Query Run Type (Optional)&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;interactive と batch の2種類ある&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Google BigQuery Client Chunk Size (Optional)&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;デフォルトの15にしている&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;connection&quot;&gt;Connection&lt;&#x2F;h3&gt;
&lt;p&gt;最後に，Connection のセットアップを行います．設定した Source と Destination をセットし，Replication frequency（同期頻度）, Destination Namespace や Prefix などを決めていきます．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Transfer&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;Replication frequency
&lt;ul&gt;
&lt;li&gt;手動実行やスケジュール実行を選択できる&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Streams&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;Destination Namespace
&lt;ul&gt;
&lt;li&gt;Mirror source structure, Destination default, Custom format の3種類ある&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Destination Stream Prefix (Optional)
&lt;ul&gt;
&lt;li&gt;必要に応じて付与する&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Normalization &amp;amp; Transformation&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;Raw data (JSON)&lt;&#x2F;li&gt;
&lt;li&gt;Normalized tabular data&lt;&#x2F;li&gt;
&lt;li&gt;上記どちらかを選択するが，Raw data だと json のままデータが格納されるので，Normalized tabular data で良いと思う&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;個人的に同期するスプレッドシートの各シートがそれぞれ表示されて，どれを同期するか選択して決められるというのが感動しました🎉&lt;&#x2F;p&gt;
&lt;p&gt;今回は1シートだけ連携することにし，Custom Transform の処理はせずに単純にデータをそのまま連携していきます．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;airbyte_for_data_integration&#x2F;airbyte-img4.png&quot; alt=&quot;Connection&quot; title=&quot;Connection&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;実行結果のログは以下のような感じ &lt;code&gt;Sync Succeeded&lt;&#x2F;code&gt; と表示されました．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;airbyte_for_data_integration&#x2F;airbyte-img5.png&quot; alt=&quot;Execution Logs&quot; title=&quot;Execution Logs&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Airbyte 側は大丈夫そうなので，BigQuery の方も確認してみると，ちゃんと入ってるので問題なさそうです！&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;airbyte_for_data_integration&#x2F;airbyte-img6.png&quot; alt=&quot;BigQuery Logs&quot; title=&quot;BigQuery Logs&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は，OSS の Airbyte を使ってスプレッドシートから BigQuery へのデータ同期を行ってみました．Airbyte は UI が用意されていて，直感的に操作できる+設定も簡単でデータ同期の体験としてとても良かったです！データソースが豊富なのもメリットとして大きいと思います．&lt;&#x2F;p&gt;
&lt;p&gt;Extract &amp;amp; Load のみしか使えていないので，次は dbt を理解して Transform も追加して処理を実行してみたいと思います．あとは他のデータパイプラインツールとの比較とかも出来たら楽しそうかな？&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>2022年夏休みのテック備忘録日記📔</title>
        <published>2022-09-02T00:00:00+00:00</published>
        <updated>2022-09-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/summer-tech-diary-2022/"/>
        <id>https://masatakashiwagi.com/blog/summer-tech-diary-2022/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/summer-tech-diary-2022/">&lt;p&gt;きっかけは &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;kaggle_araisan&quot;&gt;@kaggle_araisan&lt;&#x2F;a&gt; さんのこちらの Tweet を見かけて，面白そうな取り組みだなーと感じましたので，この機会に僕もやってみようと思ったのが始まりでした！&lt;&#x2F;p&gt;
&lt;p&gt;こういうのは，誰かと一緒にやったり，みんなが見ているところで宣言した方が続けられるので，僕も乗っかる形で Tweet&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; しました．&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-partner=&quot;tweetdeck&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;夏休みでいい機会なのでTry something new for 30 daysを再開してみようと思いました&lt;&#x2F;p&gt;&amp;mdash; Hidehisa Arai (@kaggle_araisan) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;kaggle_araisan&#x2F;status&#x2F;1557233438503370752?ref_src=twsrc%5Etfw&quot;&gt;August 10, 2022&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt;
&lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;期間は，8月10日から31日までの22日間で，毎日違ったテック記事や書籍または論文などを読みました．実際のコンテンツは以下のリンクから眺めてください．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;right-hell-d7a.notion.site&#x2F;8-841d8ee4ed654921953ad4155d198d79&quot;&gt;8月末までのテック備忘録日記&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;今回は Notion でページを作ってそれをシェアする形で公開しました．この辺り Notion は簡単に外部公開できるのと，階層でページを増やしていけるのでコンテンツを集約しやすいなと常々思っています👏&lt;&#x2F;p&gt;
&lt;h2 id=&quot;yatutemitagan-xiang&quot;&gt;やってみた感想&lt;&#x2F;h2&gt;
&lt;p&gt;率直に言うと結構しんどかったです笑，でもインプットを集中してできた部分もあり楽しかったです！&lt;&#x2F;p&gt;
&lt;p&gt;子供がまだ小さいというのもあり，育児があったりで上手く時間を捻出するのが難しいタイミングも正直ありました😇&lt;&#x2F;p&gt;
&lt;p&gt;コンテンツとしては，最近自分が興味ある領域「MLOps, レコメンド, 検索」を中心に技術記事などを読みましたが，ストックしていて読めていなかった記事や積読していた書籍を読み始めることができたといった面でプラスだったなと感じています．忙しくて後回しになってしまいがちですが，この業界は移り変わりも激しいので，常にある程度の最新の情報をインプットしておかないとなーと思うところもあり，集中して取り組めたのは良かったです．&lt;&#x2F;p&gt;
&lt;p&gt;一方で，勢いで始めた部分もあったので，1日で読めるぐらいの程良いコンテンツを探すのに時間をくった部分もありました．あとは1日で完結するところにこだわってしまったので，論文や書籍などでページ数がそれなりにあるものをしっかり読む！といったことが上手くできず，そこは反省かなと思います．&lt;&#x2F;p&gt;
&lt;p&gt;そういった場合は，数日に分けて読んだ部分までの紹介や感想を書けば良いかなと思いますので，次回はその辺も考えて取り組みたいです．（今回の取り組みでは読めていない記事でかなりの分量のものもあったので，その辺りも読んでいけたらと）&lt;&#x2F;p&gt;
&lt;p&gt;あと，Tweet もしましたが，今回はインプットしか出来ていない状態で，手を動かしてゴニョゴニョするみたいなところはありませんでしたので，次回はコードを書く系も取り入れて見るのも良さそうかなと感じた次第です😆&lt;&#x2F;p&gt;
&lt;p&gt;最後にコンテンツの内訳は，大体以下のような感じです（タグは複数タグ付いているものもあります）．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MLOps関連: 6~8件ぐらい&lt;&#x2F;li&gt;
&lt;li&gt;レコメンド: 7件&lt;&#x2F;li&gt;
&lt;li&gt;検索: 4件&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は約20日ぐらい実施したわけですが，集中して似た記事を読んだりするとより考えが洗練されてきたり，理解が進みやすくなりますので，短期集中でインプットするのも良いなと強く感じました！&lt;&#x2F;p&gt;
&lt;p&gt;あとは，日常だと業務に追われる部分もありますが，やっぱりインプットする時間は1日の中でもしっかり確保して割いた方が引き出しが増えたりするなと思います．&lt;&#x2F;p&gt;
&lt;p&gt;次は冬休みぐらいにまた「2022年冬休みのテック備忘録日記」でやろうかなと思います笑&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;やると言った手前途中で投げ出せない力学に持っていくやり方です笑&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>初めての育児休業（休暇）を取得した感想👶</title>
        <published>2022-07-26T00:00:00+00:00</published>
        <updated>2022-07-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/first-childcare-leave/"/>
        <id>https://masatakashiwagi.com/blog/first-childcare-leave/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/first-childcare-leave/">&lt;p&gt;少し時間が空きましたが，初めての育休（今は&lt;strong&gt;育業&lt;&#x2F;strong&gt;というみたい）を2月末〜5月のゴールデンウィーク明けまで2ヶ月ちょい取得したので，その感想とオススメしたいものを紹介していきます！&lt;&#x2F;p&gt;
&lt;h2 id=&quot;yu-er-xiu-ye-toha&quot;&gt;育児休業とは？&lt;&#x2F;h2&gt;
&lt;p&gt;そもそも育児休業とは何かというと，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ikumen-project.mhlw.go.jp&#x2F;employee&#x2F;system&#x2F;&quot;&gt;厚生労働省のページ&lt;&#x2F;a&gt;を確認すると以下のように書かれています．&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;育児休業制度&lt;br&gt;
子が１歳（一定の場合は、最長で２歳）に達するまで（父母ともに育児休業を取得する場合は、子が１歳２か月に達するまでの間の１年間＜パパ・ママ育休プラス＞）、申出により育児休業の取得が可能
また、産後８週間以内の期間に育児休業を取得した場合は、特別な事情がなくても申出により再度の育児休業取得が可能＜パパ休暇＞&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;基本的には子供が1歳になるまでに取得することが可能で，この期間中は育児休業給付金が支給され，休業開始時のお給料の67％（休業開始から6か月経過後は50％）が支給されます．また，社会保険料も免除されます．社会保険料はその月に1日でも育業期間が被っていれば，その月の社会保険料が免除されるので，月またぎで取得するのがオススメです！&lt;&#x2F;p&gt;
&lt;p&gt;あとは育業期間後も育児と仕事の両立支援制度が用意されていて，特に子の看護休暇が時間単位で取得できるようになった（令和3年1月1日から）ので，病院とかで抜ける場合に半日や1日全部休む必要がなくなったのは良いです．ただし看護休暇中の給料は法律上規定がないので，無給または有給の扱いは会社によって異なります．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;nazeyu-xiu-woqu-de-siyoutosi-tutanoka&quot;&gt;なぜ育休を取得しようと思ったのか&lt;&#x2F;h2&gt;
&lt;p&gt;そもそもなぜ育休を取得しようと思ったのか書いておくと，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;赤ちゃんの成長はすごく早いので，小さい頃の姿をしっかり記憶に残したかった
&lt;ul&gt;
&lt;li&gt;既に忘れつつある...😇&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;初めての経験でもあるので，わからないことだらけの中，それを妻一人に任せっきりにするのは違うなという気持ち（もちろん全て一人でして貰うとかではないが，日中は全てお願いになってしまう）&lt;&#x2F;li&gt;
&lt;li&gt;妻自身がメンタル的に強い方ではないので，産後うつとかそういった話を聞くとメンタル面をしっかりサポートしてあげたいという気持ちがあった&lt;&#x2F;li&gt;
&lt;li&gt;自分が携わっているサービス柄，ママの気持ちだったりを少しでも理解することで今までとは違う視点で物事を見ることができるだろうし，サービス開発などにそういった部分を活かせたら良いなという漠然とした想いもあった&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;上記のような思いと，次の子供が奇跡的に産まれて来てくれるか分からないというのもあり，人生の中で一度は経験できると良いなと思い，今回のタイミングで取得しました．この辺りは実は流産を2度経験していて，妊娠してから出産するまで容易なことではないというのを体感していたというのもあります．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;yu-xiu-woqu-de-sitemite&quot;&gt;育休を取得してみて&lt;&#x2F;h2&gt;
&lt;p&gt;育休期間中は Twitter で毎日一言日記を付けていたので，その当時の感想を知りたい方はそちらをどうぞ！&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet tw-align-center&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;育休1日目&lt;br&gt;今日から育休がスタート！&lt;br&gt;昨日までは妻実家で義父母も居たので、比較的余裕があったけど、今日からは2人だけで余裕が無くなってる。&lt;br&gt;娘だけでなく、妻のケアもしていきたい。&lt;&#x2F;p&gt;&amp;mdash; asteriam (@asteriam_fp) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asteriam_fp&#x2F;status&#x2F;1498279424512622597?ref_src=twsrc%5Etfw&quot;&gt;February 28, 2022&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;Podcast の方でも育休時の感想を話しているので，良ければこちらも聴いてみて下さい（宣伝です笑）！&lt;&#x2F;p&gt;
&lt;iframe style=&quot;width:100%;height:auto;&quot; src=&quot;https:&#x2F;&#x2F;podcasters.spotify.com&#x2F;pod&#x2F;show&#x2F;double-m2&#x2F;embed&#x2F;episodes&#x2F;31-2-e1gtj4c&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;育休を取得して思ったのは，取れる人は是非取って欲しいなという気持ちです．特に最初の1~2ヶ月は3時間おきにミルクを上げる必要があり，夜中でも関係なくそれが毎日続くので体力的にもしんどいのと，初めてというのもあり，十二分に赤ちゃんの動きに対して反応してしまうので精神的にも疲れてしまうことがあり，これを1人でやり切るのは本当に大変です．なので，夫婦で交代しながらミルクを上げたり，寝かしつけることができるとお互い少しは休める時間を取れるかなという思いです．&lt;&#x2F;p&gt;
&lt;p&gt;自分で子供を育ててみて（まだ数ヶ月ですが笑），改めて自分の親の偉大さを感じています．育休中に上達したことといえば，育休期間を通してミルクを適温で調整する能力をかなり高めることはできました笑．湯冷しのお水と沸騰したお湯をいい感じに配合して，適温で100mlとか150mlのミルクを作ることができます😆&lt;&#x2F;p&gt;
&lt;p&gt;あとは Twitter でも書いたりしていましたが，新しい発見も多く赤ちゃんの足の温度で眠たいかどうかを理解出来たりもします（足があったかくなるとそろそろ眠たくなるという合図）．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;osusumenomonoshao-jie-shun-bu-tong&quot;&gt;オススメのもの紹介（順不同）&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;スワドル&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;生後数ヶ月の時に一番役に立ったのは，スワドルかなと思います．これは&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;shunyaueta.com&#x2F;posts&#x2F;2021-07-23&#x2F;&quot;&gt;Ueta さんのブログ記事&lt;&#x2F;a&gt;で知りましたが，買って最高に良かったです！赤ちゃんはモロー反射で抱っこした状態からベッドなりお布団に置いた時や寝ている時に起きてしまうことが多々あるので，これを着せて寝かすと腕が動かしづらくなり，モロー反射で起きないようになるのでオススメです！&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lovetree.jp&#x2F;&quot;&gt;LOVE TREE - スワドルアップ&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;ぴよログ&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;赤ちゃんの生活記録を付けるならぴよログがオススメです．これはミルクの量や睡眠時間，おしっこやうんちなどの赤ちゃんに関するログを取ることができます．最初はミルクの量や回数など成長の目安になる部分もあるので，これを履歴として確認できるのは良きです！&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.piyolog.com&#x2F;&quot;&gt;ぴよログ&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;BabyBoon&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;iOS でしか使えないみたいですが，BabyBoon はホワイトノイズを始め，30種類以上の環境音などの赤ちゃんにとって穏やかで快適な音があるので寝かしつけの際に重宝します！&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;apps.apple.com&#x2F;jp&#x2F;app&#x2F;babyboon-%E3%83%99%E3%83%93%E3%83%BC%E3%83%9B%E3%83%AF%E3%82%A4%E3%83%88%E3%83%8E%E3%82%A4%E3%82%BA&#x2F;id1453295296&quot;&gt;BabyBoon&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;バウンサー&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;買ってはなく，知り合いから譲り受けたバウンサーもとても良かったです！常に抱っこしておくことは難しいこともあるので，バウンサーに置くと自動的に揺らしてくれるので新生児の時はとても助かりました．ただ，寝返りを打つようになってからは危ない場面もあり使わないようになりました．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;ニオイポイ&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;オムツを処理したい場合に，そのままゴミ箱に入れると匂いが気になったり，普段のゴミと赤ちゃんのオムツゴミを分けたい時にニオイポイはとても使えます！カートリッジを買い足すことでゴミ袋は補充することができます．&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.aprica.jp&#x2F;products&#x2F;nappy&#x2F;detail&#x2F;pail&#x2F;nioi-poi&#x2F;&quot;&gt;Aprica - ニオイポイ&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;CuboAi&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;ベビーモニターは最近まで少し高価なので買うか悩んでいましたが，結局買いました！買った感想としてはもっと早く買っても良かったなーという感想です．子供が1人で先に別の部屋で寝かす時に（親はまだ寝る時間じゃない時），例えば仰向けで寝ていると顔が布団で覆われていたり，心配な場面が出ると思いますが，ベビーベッドに取り付けることで寝ている様子がハッキリとわかるので安心して他のことができるようになりました！&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jp.getcubo.com&#x2F;&quot;&gt;CuboAi&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;今5ヶ月ほど経過しましたが，毎日ハイハイでマットの上を歩き回っていて少しの間も目を離せない感じに成長してくれています😅 まだ，自分で座ることはできないので，コテンとバランスを崩して倒れてしまって頭を打ったりするのをヒヤヒヤしながら見守ってます笑．あとは手足を活発に動かすので，たまに踵落としを食らわされたりもしてます😇&lt;&#x2F;p&gt;
&lt;p&gt;なにはともあれ健康にすくすくと成長してくれることを願ってます！&lt;&#x2F;p&gt;
&lt;p&gt;P.S. 勤めている会社の関係もあり，今回育休を取得したことでテレビ朝日の取材を受ける機会がありました．オンラインでの取材だったのですが，ABEMA Morning の方でインタビューの様子が放送されたみたいで，探せば YouTube にアップされた映像を見れます笑．あとは記事でも一部取り上げて頂いたみたいです．&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Github Actions と CodePipeline を使って Step Functions を動かす CI&#x2F;CD を構築</title>
        <published>2022-07-18T00:00:00+00:00</published>
        <updated>2022-07-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/implement-cicd-github-actions-codepipeline-for-stepfunctions/"/>
        <id>https://masatakashiwagi.com/blog/implement-cicd-github-actions-codepipeline-for-stepfunctions/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/implement-cicd-github-actions-codepipeline-for-stepfunctions/">&lt;p&gt;2ヶ月以上ご無沙汰になってしまいましたが，久しぶりのテックブログです．今回はタイトルにもあるように，Github Actions と CodePipeline を使ってマージトリガーで Step Functions のパイプラインを動かす CI&#x2F;CD を構築したお話になります．&lt;&#x2F;p&gt;
&lt;p&gt;今回のモチベーションは，3つほどあります．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;ML 系のモデル学習パイプラインの構築と DryRun 的なものを毎回手動で実行するのがいいかげんめんどくさくなってきた&lt;&#x2F;li&gt;
&lt;li&gt;人数が少ない ML チームだと担当者が対応できない場合に，属人化したものを代わりにオペレーションするのが大変でオペミスが発生する可能性がある
&lt;ul&gt;
&lt;li&gt;この辺りはドキュメント整備やチーム内での共有といった部分を整理しておく必要があるのは理解しつつ...&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;CI&#x2F;CD 周りの設定含めてもう少し知識を付けて MLOps のレベルを上げたかった&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;ML 系プロジェクトにおいて，CI&#x2F;CD 整備の優先度が低かったり，そもそもソフトウェアエンジニアに比べてこの辺りの経験や知識が豊富でないということで後回しにされがちですが，MLOps を考える上で CI&#x2F;CD は大事なファクターの1つなのでしっかり取り組むべきです（CI&#x2F;CD の自動化は Google が定義している MLOps level 2: CI&#x2F;CD pipeline automation に相当する部分）．また，少人数チームの場合は尚のこと，人手をかけられない + 属人化を排除する意味でも取り入れたいです．&lt;&#x2F;p&gt;
&lt;!-- 継続的な取り組みとしてのContinuous IntegrationとContinuous Delivery &amp; Deployは品質・運用・スピードを高めるためにも大事にすべき要素だと思います． --&gt;
&lt;p&gt;以下のリポジトリにソースコードを置いておきます．&lt;&#x2F;p&gt;
&lt;iframe class=&quot;hatenablogcard&quot; style=&quot;width:100%;height:155px;max-width:680px;&quot; title=&quot;teamaya&#x2F;cicd-pipeline at main · masatakashiwagi&#x2F;teamaya&quot; src=&quot;https:&#x2F;&#x2F;hatenablog-parts.com&#x2F;embed?url=https:&#x2F;&#x2F;github.com&#x2F;masatakashiwagi&#x2F;teamaya&#x2F;tree&#x2F;main&#x2F;cicd-pipeline&quot; width=&quot;300&quot; height=&quot;150&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;&#x2F;iframe&gt;
&lt;h2 id=&quot;ci-cd-paipurainnogou-cheng&quot;&gt;CI&#x2F;CD パイプラインの構成&lt;&#x2F;h2&gt;
&lt;p&gt;※ はじめに，CodePipeline の設定や IAM ロールの必要な権限は詳細に説明しないのでご了承くださいませ．公式ドキュメントや巷にある詳細な説明がされているブログをご覧下さい．&lt;&#x2F;p&gt;
&lt;p&gt;今回のゴールは &lt;strong&gt;Github のブランチマージから最終的に Step Functions のパイプラインを動かす&lt;&#x2F;strong&gt;ところまでになります．本来は Step Functions 内で ML のモデル学習を行うパイプラインを構築しますが，今回はサンプルとして SageMaker ProcessingJob を単発で動かすだけです．&lt;&#x2F;p&gt;
&lt;p&gt;今回構築した CI&#x2F;CD パイプラインは以下のような感じで，&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;implement_cicd_github_actions_codepipeline_for_stepfunctions&#x2F;cicd-img1.png&quot; alt=&quot;CI&#x2F;CD パイプライン&quot; title=&quot;CI&#x2F;CD パイプライン&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;ディレクトリ構成は以下になります．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── .github&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   └── workflows&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│       └── sam-codepipeline.yaml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── .gitignore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── README.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── async-processing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── cicd-pipeline&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── README.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── config&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   ├── buildspec.yml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   └── dev-codepipeline-ver1.json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── container&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   ├── Dockerfile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   ├── app&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   │   └── src&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   │       ├── hello.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   │       └── logger.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   ├── docker-compose.yml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   ├── requirements.lock&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   └── requirements.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   └── sam&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│       ├── env&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│       │   ├── dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│       │   │   ├── samconfig.toml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│       │   │   └── template.yaml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│       │   └── prod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│       │       ├── samconfig.toml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│       │       └── template.yaml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│       └── statemachine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│           └── sample-ml-pipelines-ver1.asl.json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└── teamaya&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;流れを説明していくと，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Github Actions パート&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
  &lt;details&gt;
  &lt;summary&gt;sam-codepipeline.yaml&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; sam-stepfunctions-codepipeline&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;on&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  pull_request&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    branches&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    types&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;opened&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;    # paths:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;    #   - &amp;#39;cicd-pipeline&#x2F;config&#x2F;dev-codepipeline-ver1.json&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;    #   - &amp;#39;.&#x2F;github&#x2F;workflows&#x2F;sam-codepipeline.yaml&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  workflow_dispatch&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;jobs&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  Build-Deploy-SAM&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; Build &amp;amp; Deploy SAM for Pipeline&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    runs-on&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ubuntu-latest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    timeout-minutes&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    steps&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; Checkout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; actions&#x2F;checkout@v2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; Configure AWS credentials&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; aws-actions&#x2F;configure-aws-credentials@v1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        with&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;          aws-access-key-id&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ${{ secrets.AWS_ACCESS_KEY_ID }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;          aws-secret-access-key&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ${{ secrets.AWS_SECRET_ACCESS_KEY }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;          aws-region&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ap-northeast-1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;      # samによるdev&#x2F;prod環境のAWSリソース更新&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; Build SAM &amp;amp; Deploy SAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        run&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          if ${{ github.base_ref == &amp;#39;dev&amp;#39; }}; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            cd sam&#x2F;env&#x2F;dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            sam build&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            sam deploy --fail-on-empty-changeset --no-confirm-changeset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          elif ${{ github.base_ref == &amp;#39;main&amp;#39; }}; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            cd sam&#x2F;env&#x2F;prod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            sam build&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            sam deploy --fail-on-empty-changeset --no-confirm-changeset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            echo &amp;quot;Invalid branch name.&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            exit 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  Update-CodePipeline&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; Update Codepipeline for Step Functions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    runs-on&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ubuntu-latest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    timeout-minutes&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    needs&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; Build-Deploy-SAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    steps&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; Checkout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; actions&#x2F;checkout@v2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; Configure AWS credentials&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; aws-actions&#x2F;configure-aws-credentials@v1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        with&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;          aws-access-key-id&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ${{ secrets.AWS_ACCESS_KEY_ID }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;          aws-secret-access-key&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ${{ secrets.AWS_SECRET_ACCESS_KEY }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;          aws-region&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ap-northeast-1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; Update Codepipeline&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        run&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; aws codepipeline update-pipeline --pipeline file:&#x2F;&#x2F;config&#x2F;codepipeline-ver1.json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;  &lt;&#x2F;details&gt;
&lt;ol&gt;
&lt;li&gt;Pull Reqest が Open したタイミングで Github Actions が走る&lt;&#x2F;li&gt;
&lt;li&gt;AWS Serverless Application Model (SAM) の Build と Deploy を行う
&lt;ul&gt;
&lt;li&gt;マージ先のブランチに応じて，切り替わるようにしています．dev マージでは dev 用のリソースを作成し，main マージでは prod 用のリソースを作成する．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;AWS CLI を使って CodePipeline の action configuration を更新する
&lt;ul&gt;
&lt;li&gt;Step Functions の StateMachineArn が ML のモデル学習のバージョンによって変更されることがあるので，後続の CodePipeline で動かす対象の Step Functions を更新する．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CodePipeline パート&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
  &lt;details&gt;
  &lt;summary&gt;buildspec.yml&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;version&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0.2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;env&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  variables&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    ENV&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;dev&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    REPOSITORY_NAME&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;lt;ECRのリポジトリ名&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    IMAGE_TAG&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;latest&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    REGION&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;ap-northeast-1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  parameter-store&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    AWS_ACCOUNT_ID&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&#x2F;CodeBuild&#x2F;common&#x2F;AWS_ACCOUNT_ID&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    AWS_ACCESS_KEY_ID&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&#x2F;CodeBuild&#x2F;common&#x2F;AWS_ACCESS_KEY_ID&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    AWS_SECRET_ACCESS_KEY&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&#x2F;CodeBuild&#x2F;common&#x2F;AWS_SECRET_ACCESS_KEY&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;phases&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  pre_build&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    commands&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;      #  - echo Login to Docker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;      #  - docker login --username $AWS_ACCESS_KEY_ID --password $AWS_SECRET_ACCESS_KEY&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; echo Set ECR repository URI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin $REPOSITORY_URI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  build&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    commands&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; echo Build started&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; echo Building the Docker Image&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; docker build -t $REPOSITORY_URI&#x2F;$REPOSITORY_NAME:$IMAGE_TAG container&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  post_build&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    commands&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; echo Login to Amazon ECR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin $REPOSITORY_URI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; echo Pushing the Docker Image to ECR started&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; docker push $REPOSITORY_URI&#x2F;$REPOSITORY_NAME:$IMAGE_TAG&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;  &lt;&#x2F;details&gt;
&lt;ol&gt;
&lt;li&gt;PR が dev&#x2F;main にマージされたタイミングで AWS で事前に設定している CodePipeline が走る
&lt;ul&gt;
&lt;li&gt;事前に CodePipeline 上で組んでいるフローが動く&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;CodeBuild が起動し，Docker Image の Build が行われ，Image を ECR に push する&lt;&#x2F;li&gt;
&lt;li&gt;Step Functions が起動し，パイプラインが走る
&lt;ul&gt;
&lt;li&gt;ECR に登録している Image を使って，SageMaker ProcessingJob が動く&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;細かい部分で言うと，&lt;code&gt;AWS_ACCOUNT_ID&lt;&#x2F;code&gt;, &lt;code&gt;AWS_ACCESS_KEY_ID&lt;&#x2F;code&gt;, &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;&#x2F;code&gt; などの機密情報は，パラメータストア（&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;ja_jp&#x2F;systems-manager&#x2F;latest&#x2F;userguide&#x2F;systems-manager-parameter-store.html&quot;&gt;AWS Systems Manager Parameter Store&lt;&#x2F;a&gt;）へ登録しておき，それを参照する形で使うようにしています．&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;aws-serverless-application-model&quot;&gt;AWS Serverless Application Model&lt;&#x2F;h3&gt;
&lt;p&gt;AWS Serverless Application Model (SAM) とは AWS でサーバーレスアプリケーションを簡単に構築することがフレームワークです．CloudFormation の拡張で CloudFormation で利用できるリソースは SAM でも使用することができます．YAML もしくは JSON 形式のテンプレートを使って簡単に環境構築ができるし，CLI も提供されています．詳しくは公式の「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;ja_jp&#x2F;serverless-application-model&#x2F;latest&#x2F;developerguide&#x2F;what-is-sam.html&quot;&gt;AWS Serverless Application Model (AWS SAM) とは&lt;&#x2F;a&gt;」を見ると良いです．&lt;&#x2F;p&gt;
&lt;p&gt;設定するファイルは2つあります．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;samconfig.toml&lt;&#x2F;li&gt;
&lt;li&gt;template.yaml&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;dev 環境の設定ファイルを見ていくと，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;samconfig.toml&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
  &lt;details&gt;
  &lt;summary&gt;samconfig.toml&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;version = 0.1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;default&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;default.deploy.parameters&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;stack_name = &amp;quot;dev-sample-codepipeline&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;s3_bucket = &amp;quot;aws-sam-cli-managed-samclisourcebucket-dev-sample-codepipeline&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;s3_prefix = &amp;quot;dev-sample-codepipeline&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;region = &amp;quot;ap-northeast-1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;confirm_changeset = true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;capabilities = &amp;quot;CAPABILITY_IAM&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;disable_rollback = true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;  &lt;&#x2F;details&gt;
&lt;ul&gt;
&lt;li&gt;こちらのファイルは1つのファイルに dev と prod の両方の設定を実装することもできるが，今回は環境毎にファイルを分けた（後述するテンプレートと一緒に管理する必要があるが，微妙に環境毎で変数が違う部分もあるのでこのファイルも分けて管理した方が良いかなと思い分けている）．&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;[default.deploy.parameters]&lt;&#x2F;code&gt; は &lt;code&gt;sam deploy&lt;&#x2F;code&gt; コマンドが実行された時に渡される引数になる．&lt;&#x2F;li&gt;
&lt;li&gt;注意としては，&lt;code&gt;s3_bucket&lt;&#x2F;code&gt; は事前に作成しておかないとデプロイした際に &lt;code&gt;S3 Bucket does not exist.&lt;&#x2F;code&gt; といったエラーが発生する．
&lt;ul&gt;
&lt;li&gt;S3 には，ビルドしたテンプレートファイルとリソースファイルが保存される．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;template.yaml&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
  &lt;details&gt;
  &lt;summary&gt;template.yaml&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;AWSTemplateFormatVersion&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;2010-09-09&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;Transform&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; AWS::Serverless-2016-10-31&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;Description&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  Create Resource&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  - StepFunctions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  - EventBridge&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;Parameters&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  EnvironmentVariable&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    Description&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; 環境変数&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    Type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; String&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    Default&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  VersionVariable&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    Description&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; バージョン番号&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    Type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; String&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    Default&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ver1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  StepFunctionsExecutionRole&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    Description&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; Step Functionsの実行ロール&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    Type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; String&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    Default&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; arn:aws:iam::&amp;lt;AWSアカウントID&amp;gt;:role&#x2F;StepFunctionsExecutionRole&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  SageMakerProcessingImage&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    Description&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; SageMakerのProcessingJobを動かすImage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    Type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; String&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    Default&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;lt;AWSアカウントID&amp;gt;.dkr.ecr.ap-northeast-1.amazonaws.com&#x2F;&amp;lt;ECRのリポジトリ名&amp;gt;:latest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;Resources&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;  # =======Step Functions for ProcessingJob======== #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  DevMLPipelinesStateMachine&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    Type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; AWS::Serverless::StateMachine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    Properties&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;      Name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; !Sub&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ${EnvironmentVariable}-sample-ml-pipelines-${VersionVariable}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;      DefinitionUri&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ..&#x2F;..&#x2F;statemachine&#x2F;sample-ml-pipelines-ver1.asl.json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;      DefinitionSubstitutions&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        ProcessingJobRole&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; !Ref&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; StepFunctionsExecutionRole&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        ProcessingImage&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; !Ref&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; SageMakerProcessingImage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        ProcessingEnvironment&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; !Ref&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; EnvironmentVariable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;      Role&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; !Ref&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; StepFunctionsExecutionRole&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;      Events&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        Schedule&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;          Type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; Schedule&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;          Properties&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;            Description&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; パイプライン用のスケジューラー&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;            Enabled&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; False&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;            Name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; !Sub&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ${EnvironmentVariable}-sample-ml-pipelines-${VersionVariable}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;            Schedule&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;cron(0 16 * * ? *)&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;  &lt;&#x2F;details&gt;
&lt;ul&gt;
&lt;li&gt;JSON ではなく，YAML 形式で書けるので良い．&lt;&#x2F;li&gt;
&lt;li&gt;Parameters ブロックでは，値を変数化できるので，共通設定や dev&#x2F;prod で動的に変わる部分だったりを書いておくと使い回しやすい．&lt;&#x2F;li&gt;
&lt;li&gt;Resources ブロックでは，Parameters ブロックで定義した変数を &lt;code&gt;!Ref&lt;&#x2F;code&gt; や &lt;code&gt;!Sub&lt;&#x2F;code&gt; で使うことができる．
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;!Sub&lt;&#x2F;code&gt; は値の一部に変数を使用したい時に使うことができる．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Role の設定もできるが，今回は事前に設定しておいた IAM ロールを使用している．&lt;&#x2F;li&gt;
&lt;li&gt;今回は Step Functions だけを定義したので，定義ファイル &lt;code&gt;sample-ml-pipelines-ver1.asl.json&lt;&#x2F;code&gt; を次に見ていく．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;sample-ml-pipelines-ver1.asl.json&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
  &lt;details&gt;
  &lt;summary&gt;sample-ml-pipelines-ver1.asl.json&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Sample ML pipelines&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  &amp;quot;StartAt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;SageMaker-Hello-World&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  &amp;quot;States&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;SageMaker-Hello-World&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Hello Worldを出力する&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;arn:aws:states:::sagemaker:createProcessingJob.sync&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;RoleArn&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;${ProcessingJobRole}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;ProcessingJobName.$&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;States.Format(&amp;#39;{}&amp;#39;, $$.Execution.Name)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;AppSpecification&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;ImageUri&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;${ProcessingImage}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;ContainerEntrypoint&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;python3&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;&#x2F;opt&#x2F;program&#x2F;src&#x2F;hello.py&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;ProcessingResources&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;ClusterConfig&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;InstanceCount&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;InstanceType&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;ml.t3.medium&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;VolumeSizeInGB&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;Environment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;PYTHON_ENV&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;${ProcessingEnvironment}&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;StoppingCondition&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;MaxRuntimeInSeconds&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 86400&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;Catch&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;ErrorEquals&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;States.ALL&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;Next&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;FailState&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;End&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;FailState&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Fail&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;Cause&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Error&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;Error&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Error&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;  &lt;&#x2F;details&gt;
&lt;ul&gt;
&lt;li&gt;JSON 形式で書かれた Step Functions の定義ファイルになる．&lt;&#x2F;li&gt;
&lt;li&gt;Hello World を出力するだけの内容になっているが，それを SageMaker ProcessingJob で動かしている．今回は単純な処理だが，ML モデルを構築するためのパイプラインをここに実装すれば，その内容が SAM で構築される．&lt;&#x2F;li&gt;
&lt;li&gt;パイプラインを構築する際は，Step Functions の Workflow studio で直感的な GUI で簡単に作成できるので，それで作成した後に JSON の定義ファイルをDLすれば同じものを本番環境用にサクッと構築することができる．&lt;&#x2F;li&gt;
&lt;li&gt;ProcessingJob を動かす Image は CodeBuild 時に ECR に push したものを使っている．&lt;&#x2F;li&gt;
&lt;li&gt;また，&lt;code&gt;ProcessingJobName&lt;&#x2F;code&gt; は一意でないとエラーになるので，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;ja_jp&#x2F;step-functions&#x2F;latest&#x2F;dg&#x2F;input-output-contextobject.html&quot;&gt;Context オブジェクト&lt;&#x2F;a&gt;の &lt;code&gt;$$.Execution.Name&lt;&#x2F;code&gt; を使用している．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;aws-codepipeline&quot;&gt;AWS CodePipeline&lt;&#x2F;h3&gt;
&lt;p&gt;CodePipeline は複数のステージというものが用意されていて，それを繋ぎ合わせて一連のパイプラインを構築し CI&#x2F;CD を自動化します．詳しくは公式の「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;ja_jp&#x2F;codepipeline&#x2F;latest&#x2F;userguide&#x2F;welcome.html&quot;&gt;AWS CodePipeline とは&lt;&#x2F;a&gt;」を見ると良いです．&lt;&#x2F;p&gt;
&lt;p&gt;今回の場合，Source → Build → Execute (Invoke) のような流れになっています．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Source: Github のブランチマージトリガーで起動する&lt;&#x2F;li&gt;
&lt;li&gt;Build: Docker ImageのBuild と ECR への push を行う&lt;&#x2F;li&gt;
&lt;li&gt;Execute (Invoke): Step Functions を起動する&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;implement_cicd_github_actions_codepipeline_for_stepfunctions&#x2F;cp-img1.png&quot; alt=&quot;CodePipeline&quot; title=&quot;CodePipeline&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;処理が正常に終了すると，Step Functions の実行結果と CloudWatch Logs のログは以下のようになります．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;implement_cicd_github_actions_codepipeline_for_stepfunctions&#x2F;sf-img1.png&quot; alt=&quot;Step Functions の結果&quot; title=&quot;Step Functions の結果&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;implement_cicd_github_actions_codepipeline_for_stepfunctions&#x2F;cwl-img1.png&quot; alt=&quot;CloudWatch Logs の結果&quot; title=&quot;CloudWatch Logs の結果&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;CodePipeline を動かす時の注意としては，権限周りのエラーがよく発生するので CodePipeline から何を動かす必要があるかをチェックして動かすアクションの権限を与えてやる必要があります．
&lt;ul&gt;
&lt;li&gt;今回の場合:
&lt;ul&gt;
&lt;li&gt;CodePipeline では，CodeBuild と Step Functions を動かすためのポリシーが必要&lt;&#x2F;li&gt;
&lt;li&gt;CodeBuild では，ECR と SystemsManager を操作するためのポリシーが必要&lt;&#x2F;li&gt;
&lt;li&gt;Step Functions では，SageMaker の操作と ECR へのアクセスを行うポリシーが必要&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;エラー周りは参考に挙げたブログが役に立ちます．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は Github Actions と CodePipeline を使って Step Functions を動かす CI&#x2F;CD パイプラインを構築したお話でした．&lt;&#x2F;p&gt;
&lt;p&gt;Step Functions の中身をMLモデル学習のパイプラインとすれば，Github Actions の PR が Open とブランチマージをトリガーとして，CodePipeline が走ることで，一連の流れを CI&#x2F;CD で実現できることになります．&lt;&#x2F;p&gt;
&lt;p&gt;ここにテストを追加したり，例えば，ECS で ML-API が動いている場合には，Step Functions のパイプラインが正常終了した後に，承認プロセスを入れて ECS のタスク定義とサービスの更新を入れることで，デプロイまで持っていくことができるかなと！&lt;&#x2F;p&gt;
&lt;p&gt;もう少し発展させることでより良い開発体験が生み出すことができるのと，MLOps の成熟度も上がって運用の自動化も一歩前進すると考えています．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rinoguchi.net&#x2F;2021&#x2F;08&#x2F;aws-fullstack-sample-application-part3.html&quot;&gt;CodeBuild・CodePipelineを使ってデリバリーパイプラインを導入（AWSでWebアプリ構築 part3）&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bobbyhadz.com&#x2F;blog&#x2F;aws-policy-has-prohibited-field-principal&quot;&gt;Solve - Policy has Prohibited field Principal AWS Error&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;codebuild&#x2F;latest&#x2F;userguide&#x2F;troubleshooting.html&quot;&gt;Troubleshooting AWS CodeBuild&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;codepipeline&#x2F;latest&#x2F;userguide&#x2F;troubleshooting.html&quot;&gt;Troubleshooting CodePipeline&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>検索に対する感想 - 検索基盤から検索エンジンの改善を始めて半年経て</title>
        <published>2022-05-04T00:00:00+00:00</published>
        <updated>2022-05-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/search-experienced-in-the-first-six-months/"/>
        <id>https://masatakashiwagi.com/blog/search-experienced-in-the-first-six-months/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/search-experienced-in-the-first-six-months/">&lt;p&gt;最近，スタバで期間限定で販売しているの冬の新作「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;menu.starbucks.co.jp&#x2F;4524785522695&quot;&gt;バターキャラメルミルフィーユ ラテ&lt;&#x2F;a&gt;」のミルクをアーモンドミルクに変更して飲んだら激ウマでハマってしまいました笑．皆さんも是非飲んでみて下さい！（ちなみに寒いので，ホットで注文しました😋）&lt;&#x2F;p&gt;
&lt;p&gt;今回のポストは &lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;adventar.org&#x2F;calendars&#x2F;7389&quot;&gt;情報検索・検索技術 Advent Calendar 2022&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; の20日目の記事になります．&lt;&#x2F;p&gt;
&lt;p&gt;どんな内容の記事を書こうか悩みましたが，今回は技術的なものではなく，僕が今年の5月半ばぐらいから関わり出した「&lt;strong&gt;検索&lt;&#x2F;strong&gt;」に関しての取り組みやその感想を書こうと思います．具体的には検索基盤の整備〜検索エンジンのチューニング〜輪読会などを通して感じたことを書いていきます．&lt;&#x2F;p&gt;
&lt;p&gt;モチベーション的には，後から見返した時に当時の検索に対する初々しい気持ちはどんなものだったのかを残しておきたい気持ちです．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;jian-suo-surushang-deqian-kasenaijian-suo-ji-pan&quot;&gt;検索する上で欠かせない検索基盤&lt;&#x2F;h2&gt;
&lt;p&gt;何と言っても検索エンジンにデータを連携し供給しないと検索は何もできないので，まずは検索基盤を整備するのが必要になってきます．検索という行為は普段から Google 先生に聞いたり，各種 Web サイト内で検索をしたりと何気なしに使っていますが，新しいデータを追加して検索できるようにするためには，検索エンジンのインデックスにデータを追加する必要があるというのを正直この時初めて知りました笑（最初はインデックスという単語をよく理解していませんでした）．&lt;&#x2F;p&gt;
&lt;p&gt;※ 検索エンジンを使わずに，データベースに検索クエリを投げているケースもありますが，ここでは検索エンジンを使っているとします．&lt;&#x2F;p&gt;
&lt;p&gt;検索エンジンにデータを定常的に連携するために検索基盤を用意するわけですが，検索基盤の具体的な構成とかの話は，僕が以前登壇したこちらの資料「&lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;speakerdeck.com&#x2F;masatakashiwagi&#x2F;jaws-days-2022-awsnomanezidosabisudeshi-xian-suruniariarutaimunajian-suo-ji-pan&quot;&gt;JAWS DAYS 2022 - AWS のマネージドサービスで実現するニアリアルタイムな検索基盤&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;」を見ていただけるとありがたいです．&lt;&#x2F;p&gt;
&lt;p&gt;構築段階よりはどう日々の運用と上手く付き合っていくか，「日々運用をしていく上で，何に気をつけるべきなのか？どういったことを意識すると良いのか？」を考えると，そういった話は調べてもなかなか出てこないし，環境によって違うしという感じで悩ましいなという気持ちでしたが，僕は以下の2つを意識しながら，設計して作るようにしました．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ユーザーへの影響を考える&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;ユーザー視点で見ると，検索機能が使えなくなることは，そのサービスへの期待値を下げてしまうことになるし，欲しい・知りたい情報を見つけられなくなるため，影響が大きい．そのためアラートの粒度やエラー時のリカバリーをどうするか，今回の検索基盤だと2つのインデックスを運用していたので，切り替え時にエラーが出てもそのまま動き続けれるように，削除タイミングやどのタイミングで切り替えるのが良いのか，などは考慮しながら作るようにしていた．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;システムを運用していくチームメンバーのことも考える&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;基盤を作った僕以外の人が触る時に，簡単に処理を修正できるか？エラーが起きた場合のリカバリーが簡単にできるか？といった部分は，構築後の運用において属人化を避けるためにも意識したいところ．&lt;&#x2F;li&gt;
&lt;li&gt;ドキュメントをきちんと用意することもそうだし，処理をモジュール単位で作る（Step Functions だとこの辺りは整理しやすい）とかは意識していた．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;より大きなシステムを運用するとなると，また違った要素も必要なのかもしれません．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;システムは作った後の日々の運用をどうしやすくするかが大事&lt;&#x2F;strong&gt;だと思うので，この点は今後も意識したいと思っています（なんか，検索システムに限った話ではない感じになってしまいましたが😅）．&lt;&#x2F;p&gt;
&lt;p&gt;検索基盤の構築で個人的にこれは良かったなと思った取り組みは，インデックスの切り替えで，Blue&#x2F;Green deployment をパイプライン（AWS Step Functions）の中で行うようにすることで，安全に切り替わる方式を作れたのは，ユーザーへの影響を考えると良い取り組みだったかなと思います．他の会社さんはどういった感じで運用されているのかとても気になっているので，是非教えてください！&lt;&#x2F;p&gt;
&lt;p&gt;なので，検索基盤が安定 &amp;amp; 信頼できるものでないと，ユーザー影響もそうですし，検索エンジンの精度改善だったりもおぼつかなくなるので，検索基盤大事です！&lt;&#x2F;p&gt;
&lt;h2 id=&quot;minnadejian-suo-noshu-ji-wodu-ndewaiwaihua-su&quot;&gt;みんなで検索の書籍を読んでワイワイ話す&lt;&#x2F;h2&gt;
&lt;p&gt;チーム内の検索システムに対する共通認識や目線を合わせるために，「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.lambdanote.com&#x2F;products&#x2F;ir-system&quot;&gt;検索システム - 実務者のための開発改善ガイドブック（通称ペンギン本）&lt;&#x2F;a&gt;」の輪読会を主催しました（チーム内でも個々人で検索システムに対しての理解のバラツキがあったので，理解を深めて議論が活発になると良いなと思い始めました．あとは，単純にこの書籍がとても面白そうだったので，みんなで読みたいと思い始めた感じです笑）．&lt;&#x2F;p&gt;
&lt;p&gt;この書籍は名の通りで，実務向けに書かれていてとても参考になることが多かったです．特に後半の第II部にその要素が詰め込まれていて，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;検索システムの運用の話
&lt;ul&gt;
&lt;li&gt;上で話した Blue&#x2F;Green deployment の話やオフライン評価，障害検知など実務的に考えていく必要があることが載っていて，どういったことを運用時には考えて用意しておく必要があるのかなど参考になります&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;分析の観点の話
&lt;ul&gt;
&lt;li&gt;検索クエリだけでなく，その結果がどうだったかなどを考えるべきといったことが書かれています&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;改善箇所の発見プロセス
&lt;ul&gt;
&lt;li&gt;Why-What-Who を定めないと意味のない改善になってしまうといった心に刺さることが書かれています&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;機械学習を使ったランキングの話
&lt;ul&gt;
&lt;li&gt;あまり体系的に整理されたものはないと思うので，非常にありがたいことが書かれています&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;etc...&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;これ以外にも色々とありすぎて全部はここに書けませんが，検索をする人は一度は目を通しておくべき内容だなと思います！（定期的に読み直したいです）&lt;&#x2F;p&gt;
&lt;p&gt;輪読会を通して，検索システムに対する理解やそれが及ぶ範囲などを知ることができたのと，それをチームメンバーでうちのサービスだとどうか？など自分達の状況に置き換えながら議論して，内容を共有しながら進めることができたので，とても学びがある会になったと思います．&lt;&#x2F;p&gt;
&lt;p&gt;ただ，準備に時間がかかったり，読み込みの時間が十分でなく議論がそこまで活発化しなかった会もあったので，そういった場合は会の最初に黙々と読む時間を用意しても良かったのかもと思ったりしました...&lt;&#x2F;p&gt;
&lt;p&gt;検索システムは奥が深くて知れば知るほど関わる人も多く一筋縄ではいかないなと思う一方で，取り組み甲斐のある面白い領域だなと感じています😊&lt;&#x2F;p&gt;
&lt;h2 id=&quot;jian-suo-enzinnotiyuningututenan-siina&quot;&gt;検索エンジンのチューニングって難しいな&lt;&#x2F;h2&gt;
&lt;p&gt;メインは検索基盤周りを扱っていて，今の所チューニング部分は少しだけ関わっていますが，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Analyzer の定義&lt;&#x2F;li&gt;
&lt;li&gt;Query DSL の定義&lt;&#x2F;li&gt;
&lt;li&gt;辞書整備&lt;&#x2F;li&gt;
&lt;li&gt;etc...&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;上に挙げたあたりで難しいなと日々感じている...&lt;&#x2F;p&gt;
&lt;p&gt;最初の方はゼロ件ヒットの結果や検索ログに基づいたユーザー辞書・同義語辞書の整備は色々とやっていて，特に同義語辞書は何を同義語と設定するか，双方向なのか一方向の辞書展開なのかは答えがないので，言葉の意味や定義を調べたり，ユーザーの一人である妻に聞いたりしながら設定していたりしました（同義語の収集自動化したい...）．&lt;&#x2F;p&gt;
&lt;p&gt;また，検索ログを眺めていると，ユーザーが何を調べているか，ワードもそうですし全体でのそのワード回数などを感覚的に掴めるので，一度やったのは正解でした！&lt;&#x2F;p&gt;
&lt;p&gt;他には，こんな感じで検索ワード入れると検索にヒットするのになーと思ったりして，ユーザー全員が検索の仕方が上手いわけではないので，サジェストで「これのことですか？」とか，意味は同じで「こちらの方がヒット数が多いですよ」とか，もう少しガイドがあったりすると改善できるのかな？と感じたり．&lt;&#x2F;p&gt;
&lt;p&gt;あとは内部的に表記揺れを吸収して直したりはありだと思っています．すぐに技術的に解決が難しくても，UI でもそういったガイドはできると思っていて，この辺りはエンジニアリングとデザインが上手く混ざり合うと良い体験をユーザーに提供できるのかなと感じています．&lt;&#x2F;p&gt;
&lt;p&gt;機械学習の導入に関しては，検索結果のパーソナライズ化ができる利点もありますが，それを動かす環境だったりレイテンシーを抑えて計算して結果を表示する工夫が必要だと思うので，そんなに簡単には導入でき無さそうかなと思ったりしてます🤔&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;半年程度検索という領域に携わって，手探りながら進めて感じたのは，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;検索ログを泥臭く見て改善ポイントを見つけたり，ユーザーの行動に思いを馳せる&lt;&#x2F;li&gt;
&lt;li&gt;ゼロ件ヒットワードや検索利用率などの各種メトリクスを取って可視化できるようにする&lt;&#x2F;li&gt;
&lt;li&gt;ロジック変更したら，定性チェックして検索結果に違和感がないか見る&lt;&#x2F;li&gt;
&lt;li&gt;エラー検知はもちろんだけど，エラー時の Runbook を用意する&lt;&#x2F;li&gt;
&lt;li&gt;リカバリーする手順はなるべく自動化して手動によるオペミスを減らす（インデックスの再作成）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;などが大事だなと思ったり，あとは検索で良い体験を提供するためには，単純にアルゴリズムの話だけでなく，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;UI&#x2F;UX&lt;&#x2F;li&gt;
&lt;li&gt;信頼できる検索基盤&lt;&#x2F;li&gt;
&lt;li&gt;検索エンジンのチューニング&lt;&#x2F;li&gt;
&lt;li&gt;辞書の整備&lt;&#x2F;li&gt;
&lt;li&gt;検索のパフォーマンス&lt;&#x2F;li&gt;
&lt;li&gt;etc...&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;本当に総合格闘技で取り組まないと成功しないなというの実感しているのと，そもそもユーザーにどういった検索体験を提供したいかを考えないと目指す方向性がブレるので，言語化が必要だなというお気持ち😅&lt;&#x2F;p&gt;
&lt;p&gt;これからもいっぱい悩んでいこうと思います！&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>MLOps 勉強会で登壇した感想</title>
        <published>2022-05-04T00:00:00+00:00</published>
        <updated>2022-05-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/speaking-at-the-mlops-study/"/>
        <id>https://masatakashiwagi.com/blog/speaking-at-the-mlops-study/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/speaking-at-the-mlops-study/">&lt;p&gt;2週間ぐらい間が空いてしまいましたが，先月の4月19日に&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mlops.connpass.com&#x2F;event&#x2F;242652&#x2F;&quot;&gt;こちらの MLOps 勉強会&lt;&#x2F;a&gt;で登壇した時の感想ポエムを書きました．&lt;&#x2F;p&gt;
&lt;p&gt;ところで MLOps 勉強会とは？ コミュニティーの説明を引用すると...&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;AI&#x2F;機械学習技術をビジネス適用した後に必要となる多くのチャレンジについて理解を深めていく事、また業界横断の技術コミュニティを作ることを目的としています。&lt;br &#x2F;&gt;
また、先駆けてMLOpsに取り組まれている事例の講演など、MLOpsに関する最先端の情報を共有する会を開催していきます。&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;日本での MLOps に関する事例などをそれらに取り組んでいる方々と共有する会で，今回僕は&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masatakashiwagi.github.io&#x2F;portfolio&#x2F;post&#x2F;start-mlops-practices-project&#x2F;&quot;&gt;以前のブログポスト&lt;&#x2F;a&gt;で紹介した「&lt;strong&gt;MLOps Practices&lt;&#x2F;strong&gt;」という日本での MLOps の事例を収集して整理したWebサイトを公開したという内容で登壇させて頂きました．&lt;&#x2F;p&gt;
&lt;p&gt;このブログを書いて Twitter で発信したところ想定以上の反応を頂いて，その中で運営の方からお声がけ适いて登壇する流れになりました．&lt;&#x2F;p&gt;
&lt;script async class=&quot;speakerdeck-embed&quot; data-id=&quot;5a65c335b5a445a6987c3d599c87826f&quot; data-ratio=&quot;1.77725118483412&quot; src=&quot;&#x2F;&#x2F;speakerdeck.com&#x2F;assets&#x2F;embed.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;h2 id=&quot;deng-tan-qian-made&quot;&gt;登壇前まで&lt;&#x2F;h2&gt;
&lt;p&gt;まず登壇までの話をしておきますと，お話を頂いてから登壇日までは十分時間があったのですが，丁度育休中だったこともあり，育児や家事で思ったよりもあっという間に1日が過ぎて行って，資料の構成やスライドの作成の時間を確保するのが難しく，気づけば登壇日まであと1週間になっていた時は少し焦りました😅&lt;&#x2F;p&gt;
&lt;p&gt;この辺は毎日少しづつ時間を確保すれば良かったなーと計画性の無さを実感しました...（余談ですが，実は個人プロジェクトのコードを書くことに夢中になっててスライド作成に取り掛かれてなかったですw）&lt;&#x2F;p&gt;
&lt;p&gt;でも，我ながら生後1~2ヶ月の子供が居る中で妻と交代しながらの育児とはいえ，登壇承諾して資料作成とかして頑張ったなーと思います笑&lt;&#x2F;p&gt;
&lt;h2 id=&quot;deng-tan-sitemite&quot;&gt;登壇してみて&lt;&#x2F;h2&gt;
&lt;p&gt;当日はオフラインで18時開催だったので，それまでに子供をお風呂に入れて事前準備を終えたり，登壇中の育児は妻にお願いしたりして対応してました．小さいお子さんが居る家庭は似たような感じなのか気になったので，誰かまたお話し聞かせて下さいー！&lt;&#x2F;p&gt;
&lt;p&gt;さてさて実際に登壇した感想としては，オンライン発表はこちらが一方的に喋る感じになるので，聴いてくれている人の顔や反応を見ることができないのが残念だし難しいなと感じました．自己紹介の一発目にボケをかましたので，皆さんの失笑具合を見れなかったのは残念です🤣&lt;&#x2F;p&gt;
&lt;p&gt;あとどうしても淡々と話す感じになるので，話すスピードが速かったりとかに気づきにくいとも思いました．発表はオフラインでしたいけど，小さい子供が居ると今回のようなオンラインで助かるなとも思い難しいです...&lt;&#x2F;p&gt;
&lt;p&gt;内容に関しては，実務での取り組みとは少し違う部分がメインになるので，聴いている人の興味としてどうなのかな？と思い，おまけとして実務で取り組んでいる事例も軽く紹介する形にしました．メインパートは継続的な取り組みが必要とされる MLOps において，それらに興味がある人にとってどういうのを参考にすればいいかをサポートする形で海外の事例集を紹介しつつ，日本版でそういった事例集がないので，それを作りたい気持ちで Website を作成して公開した話をする流れにしました．備忘録がてらに用意したもので，色々と反響頂けたのは嬉しかったです！&lt;&#x2F;p&gt;
&lt;p&gt;また，発表後の質問やアンケート結果を見る限り，実際に皆さんからも好意的な内容が多く嬉しい気持ちになりました！😆（受けた質問をメモしておけば良かったのですが，していなかったのでもし録画が公開されたらこのブログに回答する形で追記したいと思います）&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;自分自身まだまだ満足した MLOps の取り組みが出来ているわけではないのですが，知らない部分も多いので，他社さんの事例を参考にしながら，個人的に関心が強い「&lt;strong&gt;機械学習の社会実装と継続的な仕組み作り&lt;&#x2F;strong&gt;」にチャレンジして行ければと思います．&lt;&#x2F;p&gt;
&lt;p&gt;そして，日本の MLOps コミュニティー界隈を少しでも盛り上げたい気持ちから，この度 MLOps 勉強会の運営に参加させて頂くことになりました！情報発信や企画など進めて行ければと思いますので，今後ともよろしくお願いします🙏&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>CML を使った ML モデルの CI&#x2F;CD</title>
        <published>2022-05-01T00:00:00+00:00</published>
        <updated>2022-05-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/build-continuous-machine-learning/"/>
        <id>https://masatakashiwagi.com/blog/build-continuous-machine-learning/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/build-continuous-machine-learning/">&lt;p&gt;&lt;strong&gt;Continuous Machine Learning (CML)&lt;&#x2F;strong&gt; という機械学習モデルの CI ツールを個人プロジェクトで導入したので，その紹介をしようと思います．&lt;&#x2F;p&gt;
&lt;p&gt;機械学習プロジェクトでテストを考える時に，大きく3つあると考えています．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ソフトウェアのテスト&lt;&#x2F;strong&gt;: 単体テストや結合テストなどコードが意図通りの挙動を示すかどうかを確認するテスト
&lt;ul&gt;
&lt;li&gt;ツール: pytest, unittest ...など&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;機械学習モデルのテスト&lt;&#x2F;strong&gt;: 機械学習モデルが正常に動作するか，評価指標でスコアを得ることができるかなどを確認するテスト
&lt;ul&gt;
&lt;li&gt;ツール: CML (with DVC) ...など&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;データのテスト&lt;&#x2F;strong&gt;: データが想定しているスキーマに従っているか，データの分布や範囲が意図したデータかなどを確認するテスト
&lt;ul&gt;
&lt;li&gt;ツール: dbt, Dataform ...など&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;このうち今回は，&lt;strong&gt;機械学習モデルのテスト&lt;&#x2F;strong&gt;に着目してこれをどのように実施するかを紹介します．&lt;&#x2F;p&gt;
&lt;p&gt;※ 尚今回，&lt;strong&gt;DVC&lt;&#x2F;strong&gt; は使っていないです．機械学習モデルは使用するデータに依存する部分がかなり大きいので，DVC と組み合わせて実施するのが望ましいですが，今回は簡易的なテストデータを用意して，CML を実施することにしています．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;continuous-machine-learning-cml-toha&quot;&gt;Continuous Machine Learning (CML) とは？&lt;&#x2F;h2&gt;
&lt;p&gt;Continuous Machine Learning (CML) は，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;iterative.ai&#x2F;&quot;&gt;Iterative.ai&lt;&#x2F;a&gt; が開発している機械学習プロジェクトの CI&#x2F;CD を実現する OSS であり，特徴としては以下のような点があります．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;モデルの学習と評価の結果をレポート（markdown 形式）にして自動生成できる（メトリクスや図など）&lt;&#x2F;li&gt;
&lt;li&gt;Github Actions と連携して，Pull Requests 時に自動的に実行する仕組み&lt;&#x2F;li&gt;
&lt;li&gt;任意のクラウド環境で実験を実行することが可能&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;これは例えば，次のような課題を解決するためのサポートになると考えています．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;PoC でデータサイエンティストが作成したコードをプロダクション環境に載せた際に，モデルの学習と評価が適切に行われているかをどのように確認するか？&lt;&#x2F;li&gt;
&lt;li&gt;モデルが前回から向上していることをどのように確認するか？（これについては DVC との連携も必要）&lt;&#x2F;li&gt;
&lt;li&gt;モデルの再学習の際にも同じようなチェックが行われるのか？&lt;&#x2F;li&gt;
&lt;li&gt;etc...&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;CML は PR ベースでモデルの学習と評価を行い，適切な意思決定に繋げるのに役立つツールです．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ge-ren-puroziekutohenodao-ru&quot;&gt;個人プロジェクトへの導入&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masatakashiwagi.com&#x2F;blog&#x2F;async-ml-processing-fastapi-rabbitmq&#x2F;&quot;&gt;前回のブログポスト&lt;&#x2F;a&gt;の「#consumerの実装」で少し触れた部分になります．&lt;&#x2F;p&gt;
&lt;p&gt;機械学習によるモデル作成を行っている &lt;code&gt;tasks.py&lt;&#x2F;code&gt; の &lt;code&gt;if __name__ == &quot;__main__&quot;:&lt;&#x2F;code&gt; 以下が CML 用に用意したコードになります．&lt;&#x2F;p&gt;
&lt;details&gt;
&lt;summary&gt;if __name__ == &quot;__main__&quot;:以下のコードを抜粋&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; __name__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; plot_yy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;y_valid&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; y_pred&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; metrics&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; savepath&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;Vizualize the results using yy-plot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        y_max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np.max(y_valid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        y_min&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np.min(y_valid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;        # calculate max and min of y_pred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        predict_y_max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np.max(y_pred)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        predict_y_min&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np.min(y_pred)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;        # use the smallest and largest value of either of both y_valid and y_pred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;        # as the range of the vertical axis horizontal axis&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        axis_max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; max&lt;&#x2F;span&gt;&lt;span&gt;(y_max, predict_y_max)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        axis_min&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; min&lt;&#x2F;span&gt;&lt;span&gt;(y_min, predict_y_min)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;        # margin of 5% of the length&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        axis_max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; axis_max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; (axis_max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; axis_min)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0.05&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        axis_min&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; axis_min&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; (axis_max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; axis_min)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0.05&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.figure(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;figsize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.subplots_adjust(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;wspace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0.2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; hspace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0.3&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.scatter(y_pred, y_valid,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;r&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; zorder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; edgecolors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; alpha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0.6&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.plot([axis_min, axis_max], [axis_min, axis_max],&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;#1560bd&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.xlabel(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;Predict Values&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; fontsize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.ylabel(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;True Values&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; fontsize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.title(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;RMSE=%.2f&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span&gt; (metrics),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; fontsize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.tick_params(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;labelsize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.tight_layout()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.grid(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.savefig(savepath,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; dpi&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;100&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; bbox_inches&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;tight&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; pad_inches&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0.1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.close()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; plot_residual&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;y_valid&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; y_pred&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; savepath&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        residual&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; y_pred&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; y_valid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        xmax&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np.max(y_pred)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; (np.max(y_pred)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; np.min(y_pred))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0.05&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        xmin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np.min(y_pred)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; (np.max(y_pred)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; np.min(y_pred))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0.05&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.figure(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;figsize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.subplots_adjust(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;wspace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0.2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; hspace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0.3&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.scatter(y_pred, residual,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;r&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;50&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; zorder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; edgecolors&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; alpha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0.6&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.hlines(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;y&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; xmin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;xmin,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; xmax&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;xmax,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; color&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;#1560bd&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.title(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;Residual Plot&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; fontsize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.xlabel(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;Predict Values&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; fontsize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.ylabel(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;Residuals&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; fontsize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.tick_params(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;labelsize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.tight_layout()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.grid(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.savefig(savepath,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; dpi&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;100&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; bbox_inches&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;tight&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; pad_inches&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0.1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        plt.close()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    params&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;model_id&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;sample_test&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;dataset_id&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;test_diabetes&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;features&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;age&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;bmi&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;bp&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;s1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;s2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;s3&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;s4&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;s5&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;s6&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;target&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;target&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    dataset_path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;test&#x2F;data&#x2F;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; params[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;dataset_id&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;.csv&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    df&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd.read_csv(dataset_path)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    result&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; train(df, params)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rmse&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; result[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;metrics&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;rmse&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;    # Record the metrics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    outfile&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;data&#x2F;metrics.txt&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    if not&lt;&#x2F;span&gt;&lt;span&gt; os.path.isdir(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;data&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        os.mkdir(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;data&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    with&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; open&lt;&#x2F;span&gt;&lt;span&gt;(outfile,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;w&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; f:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        f.write(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;RMSE: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;rmse&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;:.2f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;    # Plot results&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    y_valid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; result[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;y_true&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    y_pred&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; result[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;y_pred&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    savepath_yy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;data&#x2F;yy_plot.png&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    plot_yy(y_valid, y_pred,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; metrics&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;rmse,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; savepath&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;savepath_yy)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    savepath_residual&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;data&#x2F;residual_plot.png&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    plot_residual(y_valid, y_pred,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; savepath&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;savepath_residual)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;p&gt;こちらのコードがレポートを作る処理になります．&lt;code&gt;metrics.txt&lt;&#x2F;code&gt; というテキストファイルを一時的に作成し，そこにメトリクスの結果を書き込みます．また，作成した回帰モデルによる実測-予測プロットの図（Y-Y プロット）や残差プロットの図を png ファイルでこちらも一時的に保存し，レポートに出力する形式です．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Record the metrics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;outfile&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;data&#x2F;metrics.txt&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;if not&lt;&#x2F;span&gt;&lt;span&gt; os.path.isdir(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;data&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    os.mkdir(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;data&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;with&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; open&lt;&#x2F;span&gt;&lt;span&gt;(outfile,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;w&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; f:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    f.write(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;RMSE: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;rmse&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;:.2f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Plot results&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;y_valid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; result[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;y_true&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;y_pred&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; result[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;y_pred&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;savepath_yy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;data&#x2F;yy_plot.png&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;plot_yy(y_valid, y_pred,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; metrics&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;rmse,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; savepath&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;savepath_yy)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;savepath_residual&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;data&#x2F;residual_plot.png&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;plot_residual(y_valid, y_pred,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; savepath&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;savepath_residual)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;レポートに出力したいファイルを用意できたら，CML を使うために &lt;code&gt;cml.yaml&lt;&#x2F;code&gt; ファイルを &lt;code&gt;.github&#x2F;workflows&lt;&#x2F;code&gt; 以下に作成します．&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;iterative&#x2F;cml_base_case&quot;&gt;公式のユースケース&lt;&#x2F;a&gt;を参考にしても良いと思います．&lt;&#x2F;p&gt;
&lt;p&gt;以下は，今回のプロジェクトで実行した CML になります．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; train-my-model&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;on&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  push&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    paths&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;async-processing&#x2F;app&#x2F;consumer&#x2F;tasks.py&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  pull_request&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    branches&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;jobs&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  train-model&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    runs-on&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ubuntu-latest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    steps&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; actions&#x2F;checkout@v2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; iterative&#x2F;setup-cml@v1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; Set up Python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; actions&#x2F;setup-python@v2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        with&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;          python-version&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;3.8&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; Train model&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        env&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;          repo_token&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ${{ secrets.GITHUB_TOKEN }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;          S3_BUCKET_NAME&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ${{ secrets.S3_BUCKET_NAME }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;          S3_PATH_NAME&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ${{ secrets.S3_PATH_NAME }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;          S3_MODEL_PATH_NAME&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ${{ secrets.S3_MODEL_PATH_NAME }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        run&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          cd async-processing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          docker compose up -d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          docker compose exec -T consumer python3 consumer&#x2F;tasks.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          # Create CML report&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          echo &amp;quot;## Metrics&amp;quot; &amp;gt;&amp;gt; report.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          cat app&#x2F;data&#x2F;metrics.txt &amp;gt;&amp;gt; report.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          echo &amp;quot;## Plots&amp;quot; &amp;gt;&amp;gt; report.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          echo &amp;quot;### YY-plot&amp;quot; &amp;gt;&amp;gt; report.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          cml-publish app&#x2F;data&#x2F;yy_plot.png --md --title &amp;#39;YY Plot&amp;#39; &amp;gt;&amp;gt; report.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          echo &amp;quot;### Residual-plot&amp;quot; &amp;gt;&amp;gt; report.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          cml-publish app&#x2F;data&#x2F;residual_plot.png --md --title &amp;#39;Residual Plot&amp;#39; &amp;gt;&amp;gt; report.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          cml-send-comment report.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;CML が実行されるタイミングとして，&lt;code&gt;tasks.py&lt;&#x2F;code&gt; が変更された時と &lt;code&gt;dev&lt;&#x2F;code&gt; ブランチに PR が作成された時の2つを設定していますが，こちらは適宜状況に合わせるで良いかと思います．今回は単純な RandomForest のモデルなので簡単に短時間で回すことができますが，画像系のモデル学習など学習に時間もリソースもかかる場合（特にクラウド環境で CML を動かす場合），コード修正の度に実行されるのは適切でないかもしれないです．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;run&lt;&#x2F;code&gt; パートは，&lt;code&gt;docker compose up&lt;&#x2F;code&gt; で立ち上げたコンテナ環境内で &lt;code&gt;tasks.py&lt;&#x2F;code&gt; を実行して，出力されたテキストファイルと図を markdown 形式のファイルに出力しています．ここで，&lt;code&gt;echo&lt;&#x2F;code&gt; を挟むことで header を付けたりもできます．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cml-publish&lt;&#x2F;code&gt;: レポートに画像を表示させるコマンド&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;cml-send-comment&lt;&#x2F;code&gt;: github の PR にコメントととして markdown レポートを作成するコマンド&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;参考: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cml.dev&#x2F;doc&#x2F;ref&quot;&gt;CML - Command Reference&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;結果はこのような形のレポートになります．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;build_continuous_machine_learning&#x2F;cml-img1.png&quot; alt=&quot;CML実行結果の画像&quot; title=&quot;CMLサンプル画像&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;shi-ji-shi-tutemitagan-xiang&quot;&gt;実際使ってみた感想&lt;&#x2F;h2&gt;
&lt;p&gt;個人的に良いと思う部分と微妙だなと思う部分を挙げておくと...&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;良い点
&lt;ul&gt;
&lt;li&gt;作成した学習の結果や評価を PR 上で議論できる点
&lt;ul&gt;
&lt;li&gt;認識のズレなどを議論できそう&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;モデルの結果を見て，デプロイするかどうかなど意思決定に繋げることができる点&lt;&#x2F;li&gt;
&lt;li&gt;再現性を一定担保することができる点&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;微妙な点
&lt;ul&gt;
&lt;li&gt;必要なものを出力してからレポート作成する必要がある点
&lt;ul&gt;
&lt;li&gt;結果のテキストファイルや図を出力しておく必要があるので，そこが面倒だったり，何を出すかの検討も必要&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;どういった基準で CML を実行するか
&lt;ul&gt;
&lt;li&gt;どのタイミングで CML を実行するか？（push 時？ merge 時？）&lt;&#x2F;li&gt;
&lt;li&gt;重たいモデルを実行する場合，全てのデータで学習させてテストすべきか？&lt;&#x2F;li&gt;
&lt;li&gt;etc...&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;微妙な点として挙げた内容も一部は，利用する側で決めるべきルールやポリシーだったりするので，ここはどういった情報があれば「&lt;strong&gt;意思決定&lt;&#x2F;strong&gt;」をする上で判断材料となるのかを整理することでクリアになる部分かもしれない．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は，機械学習モデルのためのテストとして，CML という機械学習プロジェクトで CI&#x2F;CD を行うツールを使ってみました．&lt;&#x2F;p&gt;
&lt;p&gt;また，今回は使っていないですが，DVC という同じ Iterative.ai が開発しているデータのバージョン管理を行うツールを CML と組み合わせて使う方法もあるので，ここも次回実験して使ってみたいです．これを使うことで前回の結果との差分なども見ることができるので，より良い &lt;strong&gt;CI&#x2F;CD for ML&lt;&#x2F;strong&gt; の実現が捗ります．&lt;&#x2F;p&gt;
&lt;p&gt;P.S. Twitter でコメント頂いたので，追記しておきます．&lt;&#x2F;p&gt;
&lt;p&gt;確かに，モデルの学習を Push 時や PR 時に毎回回すのは大変なので，学習時に適用するのではなく，学習済みのモデルに対して適当なサブセットのデータを用意してそれに対する推論結果をレポート出力するのが軽量で試しやすそうだなと．&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-partner=&quot;tweetdeck&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;プルリクコメントでモデルの評価結果を出力してくれる GitHub Action。学習まで回すのは大変そうなので、サブセットの推論結果くらいに留めた方が良さそう？ &lt;a href=&quot;https:&#x2F;&#x2F;t.co&#x2F;5QkaHvQYxt&quot;&gt;https:&#x2F;&#x2F;t.co&#x2F;5QkaHvQYxt&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; ken_jimmy (@ken_jimmy) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;ken_jimmy&#x2F;status&#x2F;1520939687275540480?ref_src=twsrc%5Etfw&quot;&gt;May 2, 2022&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cml.dev&#x2F;&quot;&gt;Continuous Machine Learning (CML)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dvc.org&#x2F;&quot;&gt;Data Version Control (DVC)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>FastAPI と RabbitMQ を用いた機械学習タスクの非同期処理</title>
        <published>2022-04-24T00:00:00+00:00</published>
        <updated>2022-04-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/async-ml-processing-fastapi-rabbitmq/"/>
        <id>https://masatakashiwagi.com/blog/async-ml-processing-fastapi-rabbitmq/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/async-ml-processing-fastapi-rabbitmq/">&lt;p&gt;最近，機械学習を使ったアプリケーションのバックエンドでどういった処理を行ってモデル作成などをするのか気になったので，モデル作成時によく行われる非同期処理を FastAPI と RabbitMQ を用いて検証しました．&lt;&#x2F;p&gt;
&lt;p&gt;機械学習のようなモデル作成に時間がかかる場合，モデル作成を行うリクエストに対して，その情報を受け取ったというレスポンスだけを先に返し，実際の処理は非同期で行われることが多い．この処理を RabbitMQ という OSS の message queuing service を用いて実装してみました．あと個人的に RPC (Remote Procedure Call) や Publish&#x2F;Subscribe の仕組みを理解したいという気持ちもあありました．&lt;&#x2F;p&gt;
&lt;p&gt;下記リポジトリにソースコードなどを置いておきます．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;masatakashiwagi&#x2F;teamaya&#x2F;tree&#x2F;main&#x2F;async-processing&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;masatakashiwagi&#x2F;teamaya&#x2F;tree&#x2F;main&#x2F;async-processing&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;概要として，以下のような流れで処理を見ていきました．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;FastAPI に JSON 形式でリクエストを POST する（モデル作成するためのメッセージ情報）&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;&#x2F;train&lt;&#x2F;code&gt; というエンドポイントにまずはデータを POST する&lt;&#x2F;li&gt;
&lt;li&gt;モデルの学習が行われ，モデルを S3 に保存する&lt;&#x2F;li&gt;
&lt;li&gt;モデルの作成が完了したら，次に &lt;code&gt;&#x2F;predict&lt;&#x2F;code&gt; というエンドポイントにデータを POST する&lt;&#x2F;li&gt;
&lt;li&gt;学習済みのモデルを S3 からロードし，POST されたデータに対して予測確率を返す&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;message-queuing-servicetoha&quot;&gt;Message Queuing Serviceとは？&lt;&#x2F;h2&gt;
&lt;p&gt;メッセージキューは Producer と呼ばれるクライアントアプリケーションが作成したメッセージを受け取り，メッセージが溜まっていく仕組みになっています．Producer 側から見ると，メッセージキューにメッセージを配信します．このメッセージを処理する役割として，Consumer (Worker) と呼ばれる別のアプリケーションがあり，Consumer は Queue に接続し，処理するメッセージを受信します．処理し終わったら，返信用のメッセージをクライアント側に送信することもできます．（Queue に入れられたメッセージは，Consumer が取り出すまで保存される）&lt;&#x2F;p&gt;
&lt;p&gt;また，メッセージキューには Exchange と呼ばれる機能があり，どのメッセージをどのように送るかを設定する機能もあります．（厳密には Producer は直接 Queue に送信するのではなく，Exchange に送信することになる）&lt;&#x2F;p&gt;
&lt;p&gt;実際にこのメッセージキューの役割を担うものを Broker と呼んだりもします．サービスとして &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rabbitmq.com&#x2F;&quot;&gt;RabbitMQ&lt;&#x2F;a&gt; や &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;redis.io&#x2F;&quot;&gt;Redis&lt;&#x2F;a&gt; などがあり，マネージドサービスでは &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;sqs&#x2F;&quot;&gt;Amazon Simple Queue Service (SQS)&lt;&#x2F;a&gt; などがあります．&lt;&#x2F;p&gt;
&lt;p&gt;参考: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cloudamqp.com&#x2F;blog&#x2F;what-is-message-queuing.html&quot;&gt;What is message queuing?&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rabbitmqwoshi-tutashi-zhuang&quot;&gt;RabbitMQを使った実装&lt;&#x2F;h3&gt;
&lt;p&gt;今回は RabbitMQ を使って実装してみました．RabbitMQ は OSS の Message Broker で動作が速く軽量で，複数のメッセージングプロトコルをサポートしています．いくつかの言語で実装可能ですが，Python で扱う場合には，&lt;code&gt;pika&lt;&#x2F;code&gt; というライブラリを使うことになります．&lt;&#x2F;p&gt;
&lt;p&gt;例えば，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.celeryq.dev&#x2F;en&#x2F;stable&#x2F;&quot;&gt;Celery&lt;&#x2F;a&gt; のような分散タスクキューツールを使うことで非同期処理をより簡単に実装できますが，Celery 自体はメッセージキューを構築することはできないため，RabbitMQ や Redis のような Broker が必要になります．今回はこのあたりの pub&#x2F;sub の仕組みを理解するために Celery は使わずに RabbitMQ の Python ライブラリである pika を使って実装することにしました．&lt;&#x2F;p&gt;
&lt;p&gt;RabbitMQ は docker コンテナで立ち上げていて，&lt;code&gt;definitions.json&lt;&#x2F;code&gt; という定義ファイルを事前に用意することで，そのスキーマに基づいて RabbitMQ を立ち上げることができます．このファイルはコンテナ起動時に読み込まれます．&lt;&#x2F;p&gt;
&lt;details&gt;
&lt;summary&gt;sample: definitions.json&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;rabbit_version&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;3.9.14&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;rabbitmq_version&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;3.9.14&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;product_name&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;RabbitMQ&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;product_version&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;3.9.14&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;users&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;name&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;guest&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;password&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;guest&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;hashing_algorithm&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;rabbit_password_hashing_sha256&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;tags&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;administrator&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;limits&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;vhosts&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; &amp;quot;name&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; }],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;permissions&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;user&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;guest&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;vhost&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;configure&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;.*&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;write&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;.*&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;read&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;.*&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;topic_permissions&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;global_parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;policies&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;queues&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;name&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;queue.model.train&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;vhost&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;durable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;auto_delete&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;arguments&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; &amp;quot;x-queue-type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;classic&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;name&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;queue.model.predict&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;vhost&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;durable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;auto_delete&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;      &amp;quot;arguments&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; &amp;quot;x-queue-type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;classic&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;exchanges&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;bindings&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;p&gt;RabbitMQ には丁寧な Tutorials があるので，それを読むと理解が進むと思います！&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sisutemugou-cheng&quot;&gt;システム構成&lt;&#x2F;h2&gt;
&lt;p&gt;非同期処理を行うシステムの構成は図のようになり，Producer&#x2F;Broker&#x2F;Consumer とコンテナを3つ用意しています．&lt;&#x2F;p&gt;
&lt;p&gt;図の右下にある Result Stores はタスクの処理結果を保存するためのものになります．Result Stores には PostgreSQL や MySQL などの DB を使用することもできるし，Redis を使用することもできます．Redis は Broker としても使用することができるので，両方を1つで担うことが可能です．今回はモデルを S3 に保存するだけとして，処理結果を DB に保存したりはしていないです．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Producer: 機械学習タスクを行うためにメッセージをポストするコンテナ（&lt;code&gt;=FastAPI&lt;&#x2F;code&gt;）&lt;&#x2F;li&gt;
&lt;li&gt;Broker: メッセージキューの役割を担うコンテナ（&lt;code&gt;=RabbitMQ&lt;&#x2F;code&gt;）&lt;&#x2F;li&gt;
&lt;li&gt;Consumer: タスクを実際に実行するコンテナ&lt;&#x2F;li&gt;
&lt;li&gt;Storage: モデルを保存するストレージ（&lt;code&gt;=S3&lt;&#x2F;code&gt;）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;async_ml_processing_fastapi_rabbitmq&#x2F;teamaya-async-img1.png&quot; alt=&quot;アーキテクチャー&quot; title=&quot;アーキテクチャー&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;docker-compose.yml は以下のような構成としています．&lt;&#x2F;p&gt;
&lt;details&gt;
&lt;summary&gt;sample: docker-compose.yml&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;version: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;3.8&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Common definition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;x-template: &amp;amp;template&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  volumes:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - ~&#x2F;.gcp:&#x2F;root&#x2F;.gcp:cached&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - ~&#x2F;.aws:&#x2F;root&#x2F;.aws:cached&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - .&#x2F;app:&#x2F;opt&#x2F;program:cached&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  env_file:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - .env&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  environment:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      TZ: Asia&#x2F;Tokyo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      LANG: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;ja_JP.UTF-8&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  restart: always&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  tty: true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;services:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  producer:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;    # FastAPI for producer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    container_name: producer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    build:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      context: .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ports:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - 5000:5000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    command: [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;uvicorn&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;main:app&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;--reload&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;--host&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;0.0.0.0&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;--port&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;5000&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;--access-log&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    depends_on:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - rabbitmq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&amp;lt;: *template&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  consumer:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    container_name: consumer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    hostname: consumer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    build:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      context: .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    command: [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;python3&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;consumer&#x2F;consumer.py&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;--num_threads&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    depends_on:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - rabbitmq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&amp;lt;: *template&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  rabbitmq:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    image: rabbitmq:3.9-management&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    container_name: rabbitmq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    hostname: rabbitmq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    restart: always&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    volumes:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;      # - .&#x2F;app&#x2F;rabbitmq&#x2F;etc:&#x2F;etc&#x2F;rabbitmq&#x2F;rabbitmq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - .&#x2F;app&#x2F;rabbitmq&#x2F;etc&#x2F;rabbitmq.conf:&#x2F;etc&#x2F;rabbitmq&#x2F;rabbitmq.conf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - .&#x2F;app&#x2F;rabbitmq&#x2F;etc&#x2F;definitions.json:&#x2F;etc&#x2F;rabbitmq&#x2F;definitions.json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - .&#x2F;app&#x2F;rabbitmq&#x2F;data:&#x2F;var&#x2F;lib&#x2F;rabbitmq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - .&#x2F;app&#x2F;rabbitmq&#x2F;logs:&#x2F;var&#x2F;log&#x2F;rabbitmq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - ~&#x2F;.aws:&#x2F;root&#x2F;.aws:cached&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ports:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;      # AMQP protocol port&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - 5672:5672&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;      # HTTP management UI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - 15672:15672&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    environment:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      TZ: Asia&#x2F;Tokyo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      LANG: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;ja_JP.UTF-8&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    env_file:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - .env&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# networks:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;#   default:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;#     external:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;#       name: teamaya-network-async&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;p&gt;今回のシステムのディレクトリ構成は以下になります．少し冗長な構成になっているが，&lt;code&gt;.&#x2F;app&#x2F;producer&lt;&#x2F;code&gt; と &lt;code&gt;.&#x2F;app&#x2F;consumer&lt;&#x2F;code&gt; 配下に Producer と Consumer の処理を行うスクリプトを用意しています．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── Dockerfile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── README.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── app&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── consumer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   ├── base.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   ├── consumer.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   └── tasks.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── logger.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── main.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── producer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   ├── base.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   ├── producer.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   └── schema.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   ├── rabbitmq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │   └── etc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │       ├── definitions.json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   │       └── rabbitmq.conf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   └── test&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│       ├── __init__.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│       ├── conftest.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│       ├── data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│       │   └── test_diabetes.csv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│       └── unit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│           ├── __init__.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│           └── test_tasks.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── docker-compose.yml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── requirements.lock&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└── requirements.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;producer-noshi-zhuang&quot;&gt;Producer の実装&lt;&#x2F;h2&gt;
&lt;p&gt;それぞれのファイルの説明をしておくと，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;base.py&lt;&#x2F;code&gt;: RabbitMQ に接続するための初期化や Consumer にメッセージを送信するための処理を実装したファイル&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;producer.py&lt;&#x2F;code&gt;: &lt;code&gt;base.py&lt;&#x2F;code&gt; のクラスを継承して，個別のタスクに合わせて送信するメッセージの実行する API を実装したファイル&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;schema.py&lt;&#x2F;code&gt;: データの入出力のスキーマを定義したファイル
&lt;ul&gt;
&lt;li&gt;FastAPI では入出力を Pydantic というライブラリを用いて Data validation を行う．型ヒントを利用するためのスキーマ定義になる&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;details&gt;
&lt;summary&gt;sample: producer.py&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; ast&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; uuid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; fastapi&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; APIRouter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; logger&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; get_logger&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; producer.base&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; BaseProducer, QueueNames, RepQueueNames&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; producer.schema&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; ApiSchemaPredict, ApiSchemaTrain, ProducerResult&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;LOGGER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; get_logger()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;router&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; APIRouter(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;prefix&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; tags&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;producers&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;ProducerTrain&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;font-style: italic;text-decoration: underline;&quot;&gt;BaseProducer&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; queue_name&lt;&#x2F;span&gt;&lt;span&gt;: QueueNames,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; rep_queue_name&lt;&#x2F;span&gt;&lt;span&gt;: RepQueueNames):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        BaseProducer.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;__init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, queue_name, rep_queue_name)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; run&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; params&lt;&#x2F;span&gt;&lt;span&gt;: ApiSchemaTrain):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;Run to send message to train consumer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        Args:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            params (ApiSchemaTrain): schema for train&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        model_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;(uuid.uuid4())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;model_id&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: model_id,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;dataset_id&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: params.dataset_id,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;features&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: params.features,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;target&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: params.target&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;        # self.send_message_to_consumer(message)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;        LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Produce message for train.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.send_message_to_consumer(message)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ast.literal_eval(response.decode())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;        LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Reply Response from consumer: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; ProducerResult(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;response)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;ProducerPredict&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;font-style: italic;text-decoration: underline;&quot;&gt;BaseProducer&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; queue_name&lt;&#x2F;span&gt;&lt;span&gt;: QueueNames,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; rep_queue_name&lt;&#x2F;span&gt;&lt;span&gt;: RepQueueNames):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        BaseProducer.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;__init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, queue_name, rep_queue_name)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; run&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; params&lt;&#x2F;span&gt;&lt;span&gt;: ApiSchemaPredict):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;Run to send message to predict consumer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        Args:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            params (ApiSchemaPredict): schema for predict&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;model_id&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: params.model_id,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;dataset_id&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: params.dataset_id,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;input_data&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: params.input_data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;        LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Produce message for predict.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.send_message_to_consumer(message)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ast.literal_eval(response.decode())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;        LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Reply Response from consumer: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; ProducerResult(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;response)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;@router.post&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&#x2F;train&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; response_model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;ProducerResult,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;train&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;async def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; train&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;params&lt;&#x2F;span&gt;&lt;span&gt;: ApiSchemaTrain) -&amp;gt; ProducerResult:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;Train model&amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; ProducerTrain(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;queue_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;queue.model.train&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; rep_queue_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;queue.reply.train&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;).run(params)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;@router.post&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&#x2F;predict&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; response_model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;ProducerResult,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;predict&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;async def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; predict&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;params&lt;&#x2F;span&gt;&lt;span&gt;: ApiSchemaPredict) -&amp;gt; ProducerResult:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;Predict model&amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; ProducerPredict(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;queue_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;queue.model.predict&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; rep_queue_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;queue.reply.predict&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;).run(params)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;p&gt;&lt;code&gt;ProducerTrain&lt;&#x2F;code&gt; と &lt;code&gt;ProducerPredict&lt;&#x2F;code&gt; はタスク実行用のメッセージを送るキューの &lt;code&gt;queue_name&lt;&#x2F;code&gt; と Consumer 側からの返信用のキューである &lt;code&gt;rep_queue_name&lt;&#x2F;code&gt; の2つを引数に取ります．実際の学習や予測処理を行う部分は Consumer 側で実装しています．&lt;&#x2F;p&gt;
&lt;details&gt;
&lt;summary&gt;sample: base.py&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; os&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; uuid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; typing&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; Literal&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pika&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; logger&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; get_logger&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;LOGGER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; get_logger()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Possible values as queue name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;QueueNames&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Literal[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;queue.model.train&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;queue.model.predict&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RepQueueNames&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Literal[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;queue.reply.train&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;queue.reply.predict&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;BaseProducer&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; queue_name&lt;&#x2F;span&gt;&lt;span&gt;: QueueNames,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; rep_queue_name&lt;&#x2F;span&gt;&lt;span&gt;: RepQueueNames):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.queue_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; queue_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.rep_queue_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; rep_queue_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.pika_params&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pika.ConnectionParameters(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;            host&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;rabbitmq&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;            port&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;os.getenv(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;RABBITMQ_PORT&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 5672&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;            connection_attempts&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;            heartbeat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.connection&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pika.BlockingConnection(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.pika_params)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.channel&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.connection.channel()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;        LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;Pika connection initialized.&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        result&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.channel.queue_declare(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;queue&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.rep_queue_name,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; exclusive&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.callback_queue&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; result.method.queue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.channel.basic_consume(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;queue&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.callback_queue,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; on_message_callback&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.on_response,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; auto_ack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; on_response&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; ch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; method&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; props&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; body&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.corr_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; props.correlation_id:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; body&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; run&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; NotImplementedError&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; send_message_to_consumer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; message&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; dict&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;Send message&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        Args:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            message (dict): message info&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; None&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.corr_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;(uuid.uuid4())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        message_json&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; json.dumps(message)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.channel.basic_publish(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;            exchange&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;            routing_key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.queue_name,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;            body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;message_json,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;            properties&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;pika.BasicProperties(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;                content_type&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;application&#x2F;json&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;                delivery_mode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;  # make message persistent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;                reply_to&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.callback_queue,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;                correlation_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.corr_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;        LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Sent message. [q] &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.queue_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39; [x] Body: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;message_json&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.connection.process_data_events()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.close()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.response&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; close&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.channel.close()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.connection.close()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;__init__&lt;&#x2F;code&gt; 関数:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;RabbitMQ のサーバーと接続するために &lt;code&gt;pika.BlockingConnection()&lt;&#x2F;code&gt; で &lt;code&gt;host&lt;&#x2F;code&gt; , &lt;code&gt;port&lt;&#x2F;code&gt; などのパラメータを渡してインスタンス化を行う&lt;&#x2F;li&gt;
&lt;li&gt;Consumer からの Reply 用に rep_queue_name に指定したキュー名で callback_queue を作成する&lt;&#x2F;li&gt;
&lt;li&gt;basic_consume では subscribe するキューが存在すればそれを実行する&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;send_message_to_consumer&lt;&#x2F;code&gt; 関数:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;メッセージを json.dump し，basic_publish の body につめて Exchange に送る&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;consumer-noshi-zhuang&quot;&gt;Consumer の実装&lt;&#x2F;h2&gt;
&lt;p&gt;それぞれのファイルの説明をしておくと，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;base.py&lt;&#x2F;code&gt;: RabbitMQ に接続してキューにあるメッセージを受信し，処理を実行するベースファイル
&lt;ul&gt;
&lt;li&gt;callback 部分は &lt;code&gt;tasks.py&lt;&#x2F;code&gt; で実装しています&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;consumer.py&lt;&#x2F;code&gt;: スレッド数を決める &lt;code&gt;num_threads&lt;&#x2F;code&gt; をコマンドライン引数に取り，コンテナ上ではこのファイルが実行される&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;tasks.py&lt;&#x2F;code&gt;: 機械学習によるモデル作成や学習済みモデルをロードして予測を行う処理を実装したファイル
&lt;ul&gt;
&lt;li&gt;callback メソッドに実行したい処理を実装する&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;if __name__ == &quot;__main__&quot;:&lt;&#x2F;code&gt; 以下には &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cml.dev&#x2F;&quot;&gt;Continuous Machine Learning (CML)&lt;&#x2F;a&gt; で利用する CT 用の処理を実装している&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;details&gt;
&lt;summary&gt;sample: tasks.py&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; os&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; sys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; traceback&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; typing&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; Any, Dict&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; matplotlib.pyplot&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; plt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; numpy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pandas&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pika&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; logger&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; get_logger&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; sklearn.ensemble&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; RandomForestRegressor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; sklearn.model_selection&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; train_test_split&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; base&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; BaseConsumer, EvalMetrics, QueueNames&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;LOGGER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; get_logger()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;S3_BUCKET_NAME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; os.getenv(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;S3_BUCKET_NAME&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;S3_PATH_NAME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; os.getenv(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;S3_PATH_NAME&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;S3_MODEL_PATH_NAME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; os.getenv(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;S3_MODEL_PATH_NAME&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;TrainConsumer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;font-style: italic;text-decoration: underline;&quot;&gt;BaseConsumer&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; queue_name&lt;&#x2F;span&gt;&lt;span&gt;: QueueNames):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        BaseConsumer.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;__init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, queue_name)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; callback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; ch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; method&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; props&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; body&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        params&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.body2dict(body)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        payload&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;#39;status&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;TASK_RECEIVED&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;#39;model_id&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: params[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;model_id&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; json.dumps(payload)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ch.basic_publish(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;            exchange&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;            routing_key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;props.reply_to,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;            properties&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;pika.BasicProperties(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;correlation_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;props.correlation_id),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;            body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;response&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;        # ch.basic_ack(delivery_tag=method.delivery_tag)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.download_from_s3(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;S3_BUCKET_NAME&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; S3_PATH_NAME&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;data&#x2F;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;, params[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;dataset_id&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;.csv&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;        LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Download dataset from S3.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        dataset_path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;data&#x2F;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; params[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;dataset_id&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;.csv&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        df&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd.read_csv(dataset_path)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;        LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Read csv file and transform to dataframe.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            result&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; train(df, params)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;            # save model&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            model_path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;data&#x2F;model.pkl&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.save_model(result[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;model&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;], model_path)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;            LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Save trained model to local.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;            # upload model to cloud storage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            model_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; params[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;model_id&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.upload_to_s3(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;S3_BUCKET_NAME&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; S3_MODEL_PATH_NAME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;model_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&#x2F;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;data&#x2F;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;model.pkl&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;            LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Upload trained model to S3.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;            LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;TASK_COMPLETED&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        except&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; Exception&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; e:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            _, _, tb&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sys.exc_info()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;            LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.error(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Exception Error: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; || Type: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(e))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; || Traceback Message: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;traceback.format_tb(tb)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;            LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.error(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;TASK_ERROR&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;PredictConsumer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;font-style: italic;text-decoration: underline;&quot;&gt;BaseConsumer&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; queue_name&lt;&#x2F;span&gt;&lt;span&gt;: QueueNames):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        BaseConsumer.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;__init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, queue_name)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; callback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; ch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; method&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; props&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; body&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        params&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.body2dict(body)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        model_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; params[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;model_id&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.download_from_s3(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;S3_BUCKET_NAME&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; S3_MODEL_PATH_NAME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;model_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&#x2F;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;data&#x2F;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;model.pkl&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;        LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Download model file from S3.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        model_path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;data&#x2F;model.pkl&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.load_model(model_path)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;        LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Load model for prediction.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            result&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; predict(model, params)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            payload&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;                &amp;#39;status&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;TASK_COMPLETED&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;                &amp;#39;pred_proba&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: result[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;pred_proba&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; json.dumps(payload)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        except&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; Exception&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; e:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            _, _, tb&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sys.exc_info()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;            LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.error(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;                f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Exception Error: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; || Type: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(e))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; || Traceback Message: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;traceback.format_tb(tb)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            payload&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;                &amp;#39;status&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;TASK_ERROR&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;                &amp;#39;pred_proba&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; None&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; json.dumps(payload)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ch.basic_publish(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;            exchange&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;            routing_key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;props.reply_to,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;            properties&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;pika.BasicProperties(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;correlation_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;props.correlation_id),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;            body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;response&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;        # ch.basic_ack(delivery_tag=method.delivery_tag)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; train&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;df&lt;&#x2F;span&gt;&lt;span&gt;: pd.DataFrame,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; params&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; dict&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; Dict[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;, Any]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;Train machine learning model (RandomForestRegressor)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    Args:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        df (pd.DataFrame): dataset for training model&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        params (dict): parameters for training&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; params[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;features&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    target&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; params[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;target&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    X, y&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df[features], df[target].values&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;    # train&#x2F;test split&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    X_train, X_valid, y_train, y_valid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; train_test_split(X, y,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; test_size&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0.2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; random_state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;42&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;    LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Start model training.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;    # machine learning model: RandomForestRegressor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    reg_model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; RandomForestRegressor(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;max_depth&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; random_state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;42&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; n_estimators&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;100&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    reg_model.fit(X_train, y_train)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;    LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Model fit for training.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;    # evaluate model&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pred&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; reg_model.predict(X_valid)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;    # evaluate metrics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    eval_metrics&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; EvalMetrics()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    rmse&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; eval_metrics.rmse_score(y_valid, pred)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;    LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Evaluate metrics=RMSE for valid dataset : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;%.3f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span&gt; rmse)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;    LOGGER&lt;&#x2F;span&gt;&lt;span&gt;.info(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Finish model training.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    result&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;#39;y_pred&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: pred,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;#39;y_true&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: y_valid,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;#39;metrics&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;rmse&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: rmse},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;#39;model&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: reg_model&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; predict&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;model&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; object&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; params&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; dict&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; Dict[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;, Any]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;Prediction for dataset using trained model&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    Args:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        model (object): trained model&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        params (dict): parameters for prediction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    Returns:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        float: predict probability&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    input_data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; params[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;input_data&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pred_proba&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; model.predict(pd.DataFrame([input_data]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    result&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;#39;pred_proba&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: pred_proba[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;ul&gt;
&lt;li&gt;学習パート
&lt;ul&gt;
&lt;li&gt;今回，機械学習モデルは何でもよかったので，RandomForest で回帰を行う処理にしている&lt;&#x2F;li&gt;
&lt;li&gt;学習済みモデルは S3 に保存しているので，この処理を実行する場合は &lt;code&gt;.env&lt;&#x2F;code&gt; ファイルに自身で利用している AWS のバケット情報などを載せる&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;S3_BUCKET_NAME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = os.getenv&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;&amp;#39;S3_BUCKET_NAME&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;S3_PATH_NAME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = os.getenv&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;&amp;#39;S3_PATH_NAME&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;S3_MODEL_PATH_NAME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = os.getenv&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;&amp;#39;S3_MODEL_PATH_NAME&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;モデル学習時のメタ情報も DB に残しておくのが良いと思いますが，今回はその部分は実装していないです🙏&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;予測パート
&lt;ul&gt;
&lt;li&gt;S3 に保存したモデルをロードして，与えらたデータに対して予測を行う&lt;&#x2F;li&gt;
&lt;li&gt;モデル ID は学習時に発行された UUID をコピーして貼り付ける必要があり，出力されたログから拾うのでちょっといけてないが，モックなのでご勘弁を...&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;details&gt;
&lt;summary&gt;sample: consumer.py&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; concurrent.futures&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; ThreadPoolExecutor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; click&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; tasks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;@click.command&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;@click.option&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;--num_threads&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; type&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; help&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;the number of threads&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; default&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;@click.option&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;--max_workers&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; type&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; help&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;the number of max workers&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; default&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;num_threads&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; max_workers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;    # Consumer execution&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    with&lt;&#x2F;span&gt;&lt;span&gt; ThreadPoolExecutor(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;max_workers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;max_workers)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; executor:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(num_threads):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span&gt; task&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                tasks.TrainConsumer(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;queue_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;queue.model.train&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                tasks.PredictConsumer(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;queue_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;queue.model.predict&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                executor.submit(task.run)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; __name__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    main()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;p&gt;引数に指定したスレッド数に応じて Consumer が複数立ち上がります．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;shi-xing-jie-guo&quot;&gt;実行結果&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;docker compose up&lt;&#x2F;code&gt; でコンテナを起動して，&lt;code&gt;http:&#x2F;&#x2F;localhost:5000&#x2F;docs&lt;&#x2F;code&gt; にアクセスすると Swagger による表示がされます．FastAPI はデフォルトで OpenAPI を自動生成してくれて，Swagger や ReDoc で表示することができます．この辺はとても便利だなと感じていて，データを簡単に GET&#x2F;POST することで動作を確認することできます．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Swagger の画面&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;async_ml_processing_fastapi_rabbitmq&#x2F;teamaya-async-img2.png&quot; alt=&quot;Swagger の画面&quot; title=&quot;Swagger&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ReDoc の画面&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;async_ml_processing_fastapi_rabbitmq&#x2F;teamaya-async-img3.png&quot; alt=&quot;ReDoc の画面&quot; title=&quot;ReDoc&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;xue-xi-bian&quot;&gt;学習編&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&#x2F;train&lt;&#x2F;code&gt; にリクエストを POST する&lt;&#x2F;li&gt;
&lt;li&gt;事前に S3 に保存したデータセット名を &lt;code&gt;dataset_id&lt;&#x2F;code&gt; に，使用する特徴量（説明変数）を &lt;code&gt;features&lt;&#x2F;code&gt; に，目的変数を &lt;code&gt;target&lt;&#x2F;code&gt; に指定する&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -X&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;POST&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  &amp;#39;http:&#x2F;&#x2F;localhost:5000&#x2F;train&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;  -H&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;accept: application&#x2F;json&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;  -H&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;Content-Type: application&#x2F;json&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;  -d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  &amp;quot;dataset_id&amp;quot;: &amp;quot;diabetes&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  &amp;quot;features&amp;quot;: [&amp;quot;age&amp;quot;, &amp;quot;bmi&amp;quot;, &amp;quot;bp&amp;quot;, &amp;quot;s1&amp;quot;, &amp;quot;s2&amp;quot;, &amp;quot;s3&amp;quot;, &amp;quot;s4&amp;quot;, &amp;quot;s5&amp;quot;, &amp;quot;s6&amp;quot;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  &amp;quot;target&amp;quot;: &amp;quot;target&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;}&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;出力されるログは以下のような感じになります．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;4行目は Producer がキューに対して送信したメッセージ（Consumer に渡したい情報）&lt;&#x2F;li&gt;
&lt;li&gt;7行目（中略後1行目）は Consumer からの Reply メッセージ&lt;&#x2F;li&gt;
&lt;li&gt;最後の Consumer からのログは学習処理を実行中に出力されるログ&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;producer  | [2022-04-24 15:49:09] [ INFO] Created channel=1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;producer  | [2022-04-24 15:49:09] [ INFO] Pika connection initialized.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;producer  | [2022-04-24 15:49:09] [ INFO] Produce message for train.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;producer  | [2022-04-24 15:49:09] [ INFO] Sent message. [q] &amp;#39;queue.model.train&amp;#39; [x] Body: message_json=&amp;#39;{&amp;quot;model_id&amp;quot;: &amp;quot;c7632288-442d-44c5-9102-31ccda2af6b7&amp;quot;, &amp;quot;dataset_id&amp;quot;: &amp;quot;diabetes&amp;quot;, &amp;quot;features&amp;quot;: [&amp;quot;age&amp;quot;, &amp;quot;bmi&amp;quot;, &amp;quot;bp&amp;quot;, &amp;quot;s1&amp;quot;, &amp;quot;s2&amp;quot;, &amp;quot;s3&amp;quot;, &amp;quot;s4&amp;quot;, &amp;quot;s5&amp;quot;, &amp;quot;s6&amp;quot;], &amp;quot;target&amp;quot;: &amp;quot;target&amp;quot;}&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;consumer  | [2022-04-24 15:49:09] [ INFO] Convert message to dict type.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;~中略~&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;producer  | [2022-04-24 15:49:09] [ INFO] Reply Response from consumer: {&amp;#39;status&amp;#39;: &amp;#39;TASK_RECEIVED&amp;#39;, &amp;#39;model_id&amp;#39;: &amp;#39;c7632288-442d-44c5-9102-31ccda2af6b7&amp;#39;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;producer  | INFO:     172.24.0.1:57222 - &amp;quot;POST &#x2F;train HTTP&#x2F;1.1&amp;quot; 200 OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rabbitmq  | 2022-04-24 06:49:09.367236+00:00 [info] &amp;lt;0.5900.0&amp;gt; closing AMQP connection &amp;lt;0.5900.0&amp;gt; (172.24.0.4:46266 -&amp;gt; 172.24.0.2:5672, vhost: &amp;#39;&#x2F;&amp;#39;, user: &amp;#39;guest&amp;#39;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;consumer  | [2022-04-24 15:49:09] [ INFO] Found credentials in shared credentials file: ~&#x2F;.aws&#x2F;credentials&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;consumer  | [2022-04-24 15:49:09] [ INFO] Download dataset from S3.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;consumer  | [2022-04-24 15:49:09] [ INFO] Read csv file and transform to dataframe.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;consumer  | [2022-04-24 15:49:09] [ INFO] Start model training.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;consumer  | [2022-04-24 15:49:09] [ INFO] Model fit for training.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;consumer  | [2022-04-24 15:49:09] [ INFO] Evaluate metrics=RMSE for valid dataset : 53.039&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;consumer  | [2022-04-24 15:49:09] [ INFO] Finish model training.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;consumer  | [2022-04-24 15:49:09] [ INFO] Save trained model to local.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;consumer  | [2022-04-24 15:49:10] [ INFO] Upload trained model to S3.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;consumer  | [2022-04-24 15:49:10] [ INFO] TASK_COMPLETED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;yu-ce-bian&quot;&gt;予測編&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&#x2F;predict&lt;&#x2F;code&gt; にリクエストを POST する&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;model_id&lt;&#x2F;code&gt; を元に学習済みモデルを S3 からロードする&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;input_data&lt;&#x2F;code&gt; には，モデルに入力するデータを辞書形式で特徴量とその値という組で渡す．ただし，&lt;code&gt;model_id&lt;&#x2F;code&gt; は学習編のログ出力にある &lt;code&gt;model_id&lt;&#x2F;code&gt; を使用する必要がある&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -X&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;POST&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  &amp;#39;http:&#x2F;&#x2F;localhost:5000&#x2F;predict&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;  -H&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;accept: application&#x2F;json&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;  -H&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;Content-Type: application&#x2F;json&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;  -d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  &amp;quot;model_id&amp;quot;: &amp;quot;c7632288-442d-44c5-9102-31ccda2af6b7&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  &amp;quot;dataset_id&amp;quot;: &amp;quot;diabetes&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  &amp;quot;input_data&amp;quot;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;age&amp;quot;: 0.038076,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;bmi&amp;quot;: 0.061696,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;bp&amp;quot;: 0.021872,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;s1&amp;quot;: -0.044223,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;s2&amp;quot;: -0.034821,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;s3&amp;quot;: -0.043401,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;s4&amp;quot;: -0.002592,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;s5&amp;quot;: 0.019908,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;s6&amp;quot;: -0.017646&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;}&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;出力されるログは以下のような感じになります．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;4行目は Producer がキューに対して送信したメッセージ（Consumer に渡したい情報）&lt;&#x2F;li&gt;
&lt;li&gt;5行目の Consumer からのログは予測処理を実行中に出力されるログ&lt;&#x2F;li&gt;
&lt;li&gt;（中略後1行目）は Consumer からの Reply メッセージで，予測結果が入っている&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;producer  | [2022-04-24 18:00:16] [ INFO] Created channel=1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;producer  | [2022-04-24 18:00:16] [ INFO] Pika connection initialized.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;producer  | [2022-04-24 18:00:16] [ INFO] Produce message for predict.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;producer  | [2022-04-24 18:00:16] [ INFO] Sent message. [q] &amp;#39;queue.model.predict&amp;#39; [x] Body: message_json=&amp;#39;{&amp;quot;model_id&amp;quot;: &amp;quot;c7632288-442d-44c5-9102-31ccda2af6b7&amp;quot;, &amp;quot;dataset_id&amp;quot;: &amp;quot;diabetes&amp;quot;, &amp;quot;input_data&amp;quot;: {&amp;quot;age&amp;quot;: 0.038076, &amp;quot;bmi&amp;quot;: 0.061696, &amp;quot;bp&amp;quot;: 0.021872, &amp;quot;s1&amp;quot;: -0.044223, &amp;quot;s2&amp;quot;: -0.034821, &amp;quot;s3&amp;quot;: -0.043401, &amp;quot;s4&amp;quot;: -0.002592, &amp;quot;s5&amp;quot;: 0.019908, &amp;quot;s6&amp;quot;: -0.017646}}&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;consumer  | [2022-04-24 18:00:16] [ INFO] Convert message to dict type.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;consumer  | [2022-04-24 18:00:16] [ INFO] Download model file from S3.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;consumer  | [2022-04-24 18:00:16] [ INFO] Load model for prediction.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;~中略~&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;producer  | [2022-04-24 18:00:16] [ INFO] Reply Response from consumer: {&amp;#39;status&amp;#39;: &amp;#39;TASK_COMPLETED&amp;#39;, &amp;#39;pred_proba&amp;#39;: 208.6445780005619}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rabbitmq  | 2022-04-24 09:00:16.565636+00:00 [info] &amp;lt;0.8348.0&amp;gt; closing AMQP connection &amp;lt;0.8348.0&amp;gt; (172.24.0.4:46664 -&amp;gt; 172.24.0.2:5672, vhost: &amp;#39;&#x2F;&amp;#39;, user: &amp;#39;guest&amp;#39;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;producer  | INFO:     172.24.0.1:57624 - &amp;quot;POST &#x2F;predict HTTP&#x2F;1.1&amp;quot; 200 OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;FastAPI と RabbitMQ を用いて WebAPI 形式で，機械学習タスクの非同期処理を行う検証をしました．非同期処理だったり，RPC や Pub&#x2F;Sub の仕組みを少しは理解できたかなと思います．&lt;&#x2F;p&gt;
&lt;p&gt;今回は DB にメタデータを保存したり DB 周りの処理は実装していないので，この辺も時間があれば実装できればと...&lt;&#x2F;p&gt;
&lt;p&gt;非同期処理を行う上でメインの役割を果たした RabbitMQ についてもコメントすると，OSS で簡単に非同期処理を行える便利な技術だと感じました．Producer&#x2F;Exchange&#x2F;Queue&#x2F;Consumer の関係性も Tutorials の図などでイメージしやすくなるので，サンプルコードを見ながら比較的容易に実装することができます．一方で，Consumer から Producer に Reply メッセージを送る場合に，どのように実装すればいいかが分かりづらく，個人的にはハマりポイントでした．あと，なにげに FastAPI もほとんど使ったことなかったので良い勉強になりました！&lt;&#x2F;p&gt;
&lt;p&gt;最後に今後やりたいことについて列挙しておくと...&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;AWS SQS を使った非同期処理の実装&lt;&#x2F;li&gt;
&lt;li&gt;Celery を使った非同期処理の実装&lt;&#x2F;li&gt;
&lt;li&gt;Broker として Redis を用いた実装&lt;&#x2F;li&gt;
&lt;li&gt;DB を使ったメタデータの保存&lt;&#x2F;li&gt;
&lt;li&gt;etc...&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;fastapi.tiangolo.com&#x2F;&quot;&gt;FastAPI&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rabbitmq.com&#x2F;&quot;&gt;RabbitMQ&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rabbitmq.com&#x2F;getstarted.html&quot;&gt;RabbitMQ Tutorials&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;architecture&#x2F;microservices&#x2F;architect-microservice-container-applications&#x2F;asynchronous-message-based-communication&quot;&gt;Asynchronous message-based communication&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@si.allen&#x2F;part-1-deep-learning-scaling-your-neural-networks-with-containerization-and-a-message-broker-d9c872a8345b&quot;&gt;Deep Learning: Scaling your neural networks with containerization and a message broker&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;katanaml&#x2F;katana-skipper&quot;&gt;katanaml&#x2F;katana-skipper&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>各社の MLOps 事例を集めた MLOps Practices という Website を公開した</title>
        <published>2022-02-05T00:00:00+00:00</published>
        <updated>2022-02-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/start-mlops-practices-project/"/>
        <id>https://masatakashiwagi.com/blog/start-mlops-practices-project/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/start-mlops-practices-project/">&lt;p&gt;最近個人的に MLOps という領域に高い関心があって，日々情報収集をしたりしていますが，各社が実務で取り組んでいる事例や MLOps の各領域で使用されている技術やツールなど個別の Tips が点在していて見つけるのが大変だなという印象があります．&lt;&#x2F;p&gt;
&lt;p&gt;特に実際のユースケースが整理されていると嬉しいなーという気持ちから，じゃあ自分で整理すればいいのでは？と思い「&lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masatakashiwagi.github.io&#x2F;mlops-practices&#x2F;&quot;&gt;MLOps Practices&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;」という Website を作って公開することにしました．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mlops-practicestoha&quot;&gt;MLOps Practicesとは？&lt;&#x2F;h2&gt;
&lt;p&gt;海外には，&lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;applyingml.com&#x2F;&quot;&gt;ApplyingML&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; や &lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;visenger&#x2F;awesome-mlops&quot;&gt;Awesome MLOps&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; という Website&#x2F;Repository がありトピック毎に各社の事例が載っていたり，色々と網羅的に整理されておりサーベイの参考になるものがあります．&lt;&#x2F;p&gt;
&lt;p&gt;これと似たものがあったらいいなーと思って軽く探したところ，見当たらなかったので，それだったら自分のリファレンス用も兼ねて作ってみようかなという気持ちから &lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masatakashiwagi.github.io&#x2F;mlops-practices&#x2F;&quot;&gt;MLOps Practices&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; という Website を github pages で作成し，公開しました．&lt;&#x2F;p&gt;
&lt;p&gt;Knowledge には，各社で実際に導入されていた or されている事例を整理しています．特に会社のテックブログやイベントでの登壇資料を紹介するようにしていて，これは実運用されているケースを大事にしたいと思ったので，その部分にフォーカスを当てている感じです．&lt;&#x2F;p&gt;
&lt;p&gt;Tips（こちらは未整備）には，各ツールの使い方など個人ブログなどからも収集しようと考えていますが，数が膨大になるので要検討という感じです．&lt;&#x2F;p&gt;
&lt;p&gt;まだまだ始めたばかりで十分に整理網羅出来ていないが，細々と続けていきたいと思います．もし，「手伝ってもいいよー！」という方が居ましたら是非お声がけ下さい！&lt;&#x2F;p&gt;
&lt;p&gt;それ以外にも追加の事例などあったら，PR を出して貰えたら大変嬉しいです！&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;徐々に内容を充実させて行ければと思うので，今後も定期的に更新していきます！また，一緒に更新 &amp;amp; 運用していってくれる人も募集中なので，興味があればご連絡下さい！&lt;&#x2F;p&gt;
&lt;p&gt;Repository にスター追加して貰えると励みになるので，よろしくお願いします🙇&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;masatakashiwagi&#x2F;mlops-practices&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;gh-card.dev&#x2F;repos&#x2F;masatakashiwagi&#x2F;mlops-practices.svg?fullname=&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p lang=&quot;ja&quot; dir=&quot;ltr&quot;&gt;各社のMLOpsに対する実践事例を収集して整理するRepositoryを作ってWebsiteに公開したので，良ければご利用くださいー！&lt;a href=&quot;https:&#x2F;&#x2F;t.co&#x2F;JMOQGuDtf0&quot;&gt;https:&#x2F;&#x2F;t.co&#x2F;JMOQGuDtf0&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;&amp;mdash; asteriam (@asteriam_fp) &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;asteriam_fp&#x2F;status&#x2F;1484892084012449795?ref_src=twsrc%5Etfw&quot;&gt;January 22, 2022&lt;&#x2F;a&gt;&lt;&#x2F;blockquote&gt; &lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;applyingml.com&#x2F;&quot;&gt;ApplyingML&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;visenger&#x2F;awesome-mlops&quot;&gt;Awesome MLOps&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;MLOps Practices
&lt;ul&gt;
&lt;li&gt;Website: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;masatakashiwagi.github.io&#x2F;mlops-practices&#x2F;&quot;&gt;https:&#x2F;&#x2F;masatakashiwagi.github.io&#x2F;mlops-practices&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Repository: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;masatakashiwagi&#x2F;mlops-practices&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;masatakashiwagi&#x2F;mlops-practices&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Step Functions で自作 Dockerfile を使って SageMaker の GPU マシンを動かす方法</title>
        <published>2022-01-30T00:00:00+00:00</published>
        <updated>2022-01-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/aws-stepfunctions-gpu-setting-for-sagemaker-jobs/"/>
        <id>https://masatakashiwagi.com/blog/aws-stepfunctions-gpu-setting-for-sagemaker-jobs/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/aws-stepfunctions-gpu-setting-for-sagemaker-jobs/">&lt;p&gt;Step Functions で SageMaker のリソースを特にカスタムコンテナイメージで使う場合，単純に InstanceType として &lt;code&gt;ml.g4dn.xlarge&lt;&#x2F;code&gt; などの GPU マシンを設定するだけでは GPU を使った学習はできなくて，使いたい Dockerfile に少し手を加える必要があります．&lt;&#x2F;p&gt;
&lt;p&gt;今回は備忘録も兼ねて Dockerfile の中身を紹介しながら，GPU 環境での動作確認をしていきます．&lt;&#x2F;p&gt;
&lt;p&gt;以下の手順で動作確認をします．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;ローカルで Dockerfile と動作確認用の Python スクリプトを作成する&lt;&#x2F;li&gt;
&lt;li&gt;ローカルで build し，AWS ECR に build したイメージを push する&lt;&#x2F;li&gt;
&lt;li&gt;push したイメージの URI を SageMaker Training Job の TrainingImage に指定する&lt;&#x2F;li&gt;
&lt;li&gt;Step Functions を実行する&lt;&#x2F;li&gt;
&lt;li&gt;CloudWatch Logs を確認する&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;今回の動作確認フローは下図のようなイメージになっています．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2022&#x2F;aws_stepfunctions_gpu_setting_for_sagemaker_jobs&#x2F;aws-gpu-img1.png&quot; alt=&quot;動作確認フロー&quot; title=&quot;aws-gpu&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zi-zuo-no-dockerfile-gpu-huairu&quot;&gt;自作の「Dockerfile.gpu」ファイル&lt;&#x2F;h2&gt;
&lt;p&gt;今回は Tensorflow-gpu のベースイメージを使っていて，そのイメージに &lt;strong&gt;nvidia-docker&lt;&#x2F;strong&gt; を追加でインストールすることで Step Functions で GPU 用のカスタムコンテナイメージを使って SageMaker を動作させれます．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hub.docker.com&#x2F;r&#x2F;tensorflow&#x2F;tensorflow&#x2F;&quot;&gt;TensorFlow Docker Images&lt;&#x2F;a&gt;から好きな GPU 用のイメージを選択します．今回は &lt;code&gt;tensorflow&#x2F;tensorflow:2.6.1-gpu&lt;&#x2F;code&gt; を使用することにしました．&lt;strong&gt;Optional Features&lt;&#x2F;strong&gt; にも記載されていますが，nvidia-docker が必要だよとのことなので，この通りにしていきます．&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;-gpu&lt;&#x2F;code&gt; tags are based on Nvidia CUDA. You need nvidia-docker to run them. NOTE: GPU versions of TensorFlow 1.13 and above (this includes the &lt;code&gt;latest-&lt;&#x2F;code&gt; tags) require an NVidia driver that supports CUDA 10. See NVidia&#x27;s support matrix.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;大事な部分は以下の4行で，以前は&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;nvidiajapan&#x2F;nvidia-docker-%E3%81%A3%E3%81%A6%E4%BB%8A%E3%81%A9%E3%81%86%E3%81%AA%E3%81%A3%E3%81%A6%E3%82%8B%E3%81%AE-20-09-%E7%89%88-558fae883f44&quot;&gt;こちらの記事&lt;&#x2F;a&gt;にも書かれていますが，&lt;code&gt;nvidia-container-toolkit&lt;&#x2F;code&gt; をインストールする必要があったみたいですが，今は &lt;code&gt;nvidia-docker2&lt;&#x2F;code&gt; をインストールすることで，&lt;code&gt;nvidia-container-toolkit&lt;&#x2F;code&gt; も一緒にインストールされて，よりシンプルになっています．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; distribution=$(. &#x2F;etc&#x2F;os-release;echo $ID$VERSION_ID) \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; curl -s -L https:&#x2F;&#x2F;nvidia.github.io&#x2F;nvidia-docker&#x2F;gpgkey | sudo apt-key add - \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; curl -s -L https:&#x2F;&#x2F;nvidia.github.io&#x2F;nvidia-docker&#x2F;$distribution&#x2F;nvidia-docker.list | sudo tee &#x2F;etc&#x2F;apt&#x2F;sources.list.d&#x2F;nvidia-docker.list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install -y nvidia-docker2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;今回使用した Dockerfile 以下の通りです．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Dockerfile.gpu&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;FROM&lt;&#x2F;span&gt;&lt;span&gt; tensorflow&#x2F;tensorflow:2.6.1-gpu&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Set some environment variables.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# PYTHONUNBUFFERED keeps Python from buffering our standard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# output stream, which means that logs can be delivered to the user quickly.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;ENV&lt;&#x2F;span&gt;&lt;span&gt; PYTHONUNBUFFERED=TRUE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# PYTHONDONTWRITEBYTECODE keeps Python from writing the .pyc files which&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# are unnecessary in this case.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;ENV&lt;&#x2F;span&gt;&lt;span&gt; PYTHONDONTWRITEBYTECODE=TRUE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# DEBIAN_FRONTEND prevent from stoping docker build with tzdata&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;ENV&lt;&#x2F;span&gt;&lt;span&gt; DEBIAN_FRONTEND=noninteractive&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; apt-get -y update &amp;amp;&amp;amp; apt-get install -y --no-install-recommends \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        curl \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sudo \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        libmecab-dev \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        python3.8 \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        python3-distutils \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        python3-six \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        git \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        file \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        wget \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; apt-get clean \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; rm -rf &#x2F;var&#x2F;lib&#x2F;apt&#x2F;lists&#x2F;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# ここが今回のポイントで，nvidia-docker をインストールする&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; distribution=$(. &#x2F;etc&#x2F;os-release;echo $ID$VERSION_ID) \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; curl -s -L https:&#x2F;&#x2F;nvidia.github.io&#x2F;nvidia-docker&#x2F;gpgkey | sudo apt-key add - \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; curl -s -L https:&#x2F;&#x2F;nvidia.github.io&#x2F;nvidia-docker&#x2F;$distribution&#x2F;nvidia-docker.list | sudo tee &#x2F;etc&#x2F;apt&#x2F;sources.list.d&#x2F;nvidia-docker.list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install -y nvidia-docker2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# 必要なライブラリーを requirements.lock を使ってインストールする&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;COPY&lt;&#x2F;span&gt;&lt;span&gt; requirements.lock &#x2F;tmp&#x2F;requirements.lock&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; python3 -m pip install -U pip \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; python3 -m pip install -r &#x2F;tmp&#x2F;requirements.lock \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; python3 -m pip install sagemaker \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; python3 -m pip install sagemaker-training \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; rm &#x2F;tmp&#x2F;requirements.lock \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; rm -rf &#x2F;root&#x2F;.cache&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Timezone jst&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; ln -sf &#x2F;usr&#x2F;share&#x2F;zoneinfo&#x2F;Asia&#x2F;Tokyo &#x2F;etc&#x2F;localtime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Locale Japanese&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;ENV&lt;&#x2F;span&gt;&lt;span&gt; LC_ALL=ja_JP.UTF-8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Set up the program in the image&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;ENV&lt;&#x2F;span&gt;&lt;span&gt; PROGRAM_DIR=&#x2F;opt&#x2F;program&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;COPY&lt;&#x2F;span&gt;&lt;span&gt; app $PROGRAM_DIR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;WORKDIR&lt;&#x2F;span&gt;&lt;span&gt; $PROGRAM_DIR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;ENV&lt;&#x2F;span&gt;&lt;span&gt; PATH=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&#x2F;opt&#x2F;program:${PATH}&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; chmod +x $PROGRAM_DIR&#x2F;hello_gpu.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;CMD&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;python3&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;また，SageMaker で GPU を認識しているかを確認するための簡易的な Python スクリプトも載せておきます．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# hello_gpu.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; tensorflow&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; tf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; tensorflow.python.client&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; device_lib&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;    # TensorflowのGPU確認&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;GPUs Available: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;tf.test.is_gpu_available()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Num GPUs Available: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;(tf.config.list_physical_devices(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;GPU&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;device_lib.list_local_devices()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; __name__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    main()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;これらのファイルを用意して，ローカルで build を行い，build した後はそのイメージを ECR に push することで，Step Functions で使用できるようにします．&lt;&#x2F;p&gt;
&lt;p&gt;※ ECR への push 方法や設定は今回割愛します．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-functions-noshe-ding&quot;&gt;Step Functions の設定&lt;&#x2F;h2&gt;
&lt;p&gt;Step Functions とは，AWS が提供する各種サービスを組み合わせたパイプラインを構築するためのワークフローサービスです．機械学習向けのアクションも用意されていて，今回使用する SageMaker Training Job もその一つです．&lt;&#x2F;p&gt;
&lt;p&gt;設定は yaml ファイルのような形式で AWS のコンソール画面上で記述していきます．今回実施する内容の記述は以下の通りです．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Check GPU env&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  &amp;quot;StartAt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Hello-GPU&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;  &amp;quot;States&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;quot;Hello-GPU&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;Comment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;GPUの動作確認&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Task&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;Resource&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;arn:aws:states:::sagemaker:createTrainingJob.sync&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;RoleArn&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&amp;lt;SageMaker Training Jobの実行権限がアタッチされているロール&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;TrainingJobName&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;sample-training-job&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;AlgorithmSpecification&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;EnableSageMakerMetricsTimeSeries&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;TrainingImage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&amp;lt;アカウントID&amp;gt;.dkr.ecr.ap-northeast-1.amazonaws.com&#x2F;sample:latest-gpu&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;TrainingInputMode&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;File&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;EnableInterContainerTrafficEncryption&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;EnableManagedSpotTraining&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;Environment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;SAGEMAKER_PROGRAM&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&#x2F;opt&#x2F;program&#x2F;hello_gpu.py&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;ResourceConfig&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;InstanceCount&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;InstanceType&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;ml.g4dn.xlarge&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;VolumeSizeInGB&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;StoppingCondition&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;MaxRuntimeInSeconds&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 12345&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;MaxWaitTimeInSeconds&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 12345&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;End&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;細かい設定内容に関しては，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;sagemaker&#x2F;latest&#x2F;APIReference&#x2F;API_CreateTrainingJob.html&quot;&gt;CreateTrainingJob&lt;&#x2F;a&gt; というドキュメントを参考にすると良いかと思います．&lt;&#x2F;p&gt;
&lt;p&gt;ここで，Environment（環境変数）の &lt;strong&gt;SAGEMAKER_PROGRAM&lt;&#x2F;strong&gt; について説明しておくと，この変数に指定したプログラムは Training Job のエントリーポイントにすることができます．&lt;&#x2F;p&gt;
&lt;p&gt;元々は以下のコマンドが実行されるのですが（train.py があればそれが対象となる），実行したいプログラムのパスを指定することで任意のプログラムを実行することができます．&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;docker run &amp;lt;イメージ&amp;gt; train&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;ただし，実行権限を与えておく必要があるので，Dockerfile 内で &lt;code&gt;RUN chmod +x $PROGRAM_DIR&#x2F;hello_gpu.py&lt;&#x2F;code&gt; としています．あとは，実行結果を CloudWatch Logs で確認して，以下の内容がログに出力されていれば大丈夫です．&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;GPUs Available: True &lt;br &#x2F;&gt;
Num GPUs Available: 1&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は，Step Functions で SageMaker の Training Job をカスタムコンテナイメージを使って GPU 環境で動かす方法を紹介しました．この方法を使えば，深層学習などの GPU 環境を必要とした学習もパイプラインに組み込むことが可能になります．また，Training Job を使った学習ができれば，実験結果は SageMaker Experiments に保存されるので，再現性を担保することもできます．Step Functions でカスタムコンテナイメージを使って GPU 環境で学習させたい場合には，参考にして頂ければと！&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;awsdocs&#x2F;amazon-sagemaker-developer-guide&#x2F;blob&#x2F;master&#x2F;doc_source&#x2F;notebooks-available-instance-types.md&quot;&gt;Available SageMaker Studio Instance Types&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;nvidiajapan&#x2F;nvidia-docker-%E3%81%A3%E3%81%A6%E4%BB%8A%E3%81%A9%E3%81%86%E3%81%AA%E3%81%A3%E3%81%A6%E3%82%8B%E3%81%AE-20-09-%E7%89%88-558fae883f44&quot;&gt;NVIDIA Dockerって今どうなってるの？ (20.09 版)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>ValueError: Must setup local AWS configuration の対処方法</title>
        <published>2021-12-26T00:00:00+00:00</published>
        <updated>2021-12-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/value-error-local-aws-configuration/"/>
        <id>https://masatakashiwagi.com/blog/value-error-local-aws-configuration/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/value-error-local-aws-configuration/">&lt;p&gt;Step Functions で SageMaker ProceesingJob を使ってカスタムコンテナを実行した際に，その実行スクリプト内で ExperimentAnalytics の API を使用していたところ，&quot;&lt;strong&gt;ValueError: Must setup local AWS configuration with a region supported by SageMaker.&lt;&#x2F;strong&gt;&quot; というエラーが発生したので，その対処方法をメモしておきます．&lt;&#x2F;p&gt;
&lt;p&gt;結論から言いますと，エラー内容にある通り &lt;strong&gt;region&lt;&#x2F;strong&gt; の指定を行うことで解決できます．&lt;&#x2F;p&gt;
&lt;p&gt;方法としては2つあります．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;&lt;strong&gt;boto_session&lt;&#x2F;strong&gt;&quot; と &quot;&lt;strong&gt;sagemaker_client&lt;&#x2F;strong&gt;&quot; の &quot;&lt;strong&gt;region_name&lt;&#x2F;strong&gt;&quot; を指定する&lt;&#x2F;li&gt;
&lt;li&gt;環境変数に &quot;&lt;strong&gt;AWS_DEFAULT_REGION&lt;&#x2F;strong&gt;&quot; を設定する&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;2つ目の方法の Step Functions の定義ファイルに環境変数: &lt;code&gt;AWS_DEFAULT_REGION&lt;&#x2F;code&gt; を1行追記するのが簡単です．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;configuration-error&quot;&gt;Configuration Error&lt;&#x2F;h2&gt;
&lt;p&gt;SageMaker Experiments に保存されている実験結果は &lt;code&gt;sagemaker.analytics.ExperimentAnalytics&lt;&#x2F;code&gt; の API を使うことで取得することができます．今回 Step Functions で SageMaker ProceesingJob を使ってカスタムコンテナを実行した際に，以下のエラーが発生しました．&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;ValueError: Must setup local AWS configuration with a region supported by SageMaker.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Configuration は公式ドキュメントを見ると，以下のことが書かれています．&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Configuration - Overview &lt;br&gt;
Boto3 looks at various configuration locations until it finds configuration values. Boto3 adheres to the following lookup order when searching through sources for configuration values:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A Config object that&#x27;s created and passed as the config parameter when creating a client&lt;&#x2F;li&gt;
&lt;li&gt;Environment variables&lt;&#x2F;li&gt;
&lt;li&gt;The ~&#x2F;.aws&#x2F;config file&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;上から順番に優先度が高いものになっており，下位で設定している内容よりも上位で設定した内容が優先的に反映されます．&lt;&#x2F;p&gt;
&lt;p&gt;今回の場合は，1番目と2番目は特段設定していないので，3番目が採用されて問題ないかなと思ってましたが，上述のエラーが発生しました．AWS のクレデンシャル情報（config, credentials）はローカルの &lt;code&gt;~&#x2F;.aws&#x2F;&lt;&#x2F;code&gt; 配下に置かれており，build 時にローカルにあるファイルを volumes マウントしてコンテナ内と同期しています．&lt;&#x2F;p&gt;
&lt;p&gt;この設定では上手くいかなかったので，1番目 or 2番目の設定を行ったところ正常に動作したので，こちらの方法を記載しておきます．もし，volumes マウントの方法で上手くいく方法があったら教えてください！&lt;&#x2F;p&gt;
&lt;h2 id=&quot;config-object-wo-boto3-client-nidu-sufang-fa&quot;&gt;Config object を boto3 client に渡す方法&lt;&#x2F;h2&gt;
&lt;p&gt;公式ドキュメントに記載されている優先度が1番高い方法です．&lt;code&gt;botocore.config.Config&lt;&#x2F;code&gt; をインスタンス化して使うことで解決する方法になりますが，今回はわざわざ Config object を使わずに &lt;code&gt;region_name&lt;&#x2F;code&gt; を指定する方法を説明します．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; boto3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; sagemaker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# sessionとclientの設定を行う&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;boto_session&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; boto3.session.Session(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;region_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;ap-northeast-1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sagemaker_client&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; boto_session.client(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;service_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;sagemaker&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; region_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;ap-northeast-1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sagemaker_session&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sagemaker.session.Session(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;boto_session&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;boto_session,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; sagemaker_client&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;sagemaker_client)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# ExperimentAnalyticsをインスタンス化する&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;trial_component_analytics&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sagemaker.analytics.ExperimentAnalytics(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;    experiment_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;sample-experiments01&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;    sagemaker_session&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;sagemaker_session&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# データフレーム化&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;analytics_tables&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; trial_component_analytics.dataframe()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;コードの流れは以下になります．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;boto_session と sagemaker_client を作成する&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;sagemaker.session.Session&lt;&#x2F;code&gt; の引数にそれぞれを渡す&lt;&#x2F;li&gt;
&lt;li&gt;sagemaker_session を &lt;code&gt;sagemaker.analytics.ExperimentAnalytics&lt;&#x2F;code&gt; の引数に渡す&lt;&#x2F;li&gt;
&lt;li&gt;取得した実験結果をデータフレーム化する&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;ここで，冒頭の &quot;boto_session&quot; と &quot;sagemaker_client&quot; を作成する部分で，&lt;code&gt;boto3.session.Session&lt;&#x2F;code&gt; の &quot;region_name&quot; と，この session を使った client の &quot;region_name&quot; に該当する region を指定する必要があります．この2つをセットしておくことで，今回発生したエラーを回避することができます．&lt;&#x2F;p&gt;
&lt;p&gt;この場合はカスタムコンテナで実行するスクリプトの修正変更が必要になってきますが，次に説明する環境変数に渡す方法はこの辺りの修正は必要ないので，簡単かなと思います．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;huan-jing-bian-shu-woshe-ding-surufang-fa&quot;&gt;環境変数を設定する方法&lt;&#x2F;h2&gt;
&lt;p&gt;Step Functions のワークフローを定義する json ファイルの Environment 変数に &quot;&lt;strong&gt;AWS_DEFAULT_REGION&lt;&#x2F;strong&gt;&quot; を設定する方法です．Step Functions の定義ファイルのパラメータ部分は下記のような感じです．（今回は SageMaker ProcessingJob を使って実行している）&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Parameters&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;AppSpecification&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;ImageUri&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;hogehoge.dkr.ecr.ap-northeast-1.amazonaws.com&#x2F;mlops-experiments:latest&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;ContainerEntrypoint&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;    &amp;quot;python3&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;    &amp;quot;&#x2F;opt&#x2F;ml&#x2F;code&#x2F;get_experiments.py&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;  &amp;quot;Environment&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    &amp;quot;AWS_DEFAULT_REGION&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt; &amp;quot;ap-northeast-1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;スクリプトの中身は以下になり．session の設定が必要なくなります．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; sagemaker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# ExperimentAnalyticsをインスタンス化する&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;trial_component_analytics&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sagemaker.analytics.ExperimentAnalytics(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;    experiment_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;sample-experiments01&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# データフレーム化&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;analytics_tables&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; trial_component_analytics.dataframe()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は，Step Functions で SageMaker ProceesingJob を使った際に発生したエラーの対処方法を備忘録として残しました．Configuration の設定に優先順位があることを知ったので，この辺りは今回に限らず注意が必要だなと思いました．今回のエラーに対する対処方法は複数あるので，開発している状況に合わせて使い分けて下さい．&lt;&#x2F;p&gt;
&lt;p&gt;あと，個人的には実行している Step Functions の region をセットして欲しい気持ちもありますが，まーこれは状況次第なので，なんとも言えない気もしています...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;boto3.amazonaws.com&#x2F;v1&#x2F;documentation&#x2F;api&#x2F;latest&#x2F;guide&#x2F;configuration.html&quot;&gt;Boto3 Docs - Configuration&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;55869651&#x2F;how-to-fix-aws-region-error-valueerror-must-setup-local-aws-configuration-with&quot;&gt;How to fix aws region error &quot;ValueError: Must setup local AWS configuration with a region supported by SageMaker&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>スプレッドシートから BigQuery へ Digdag を使ったデータ連携</title>
        <published>2021-12-22T00:00:00+00:00</published>
        <updated>2021-12-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/integrate-spreadsheets-to-bigquery-with-digdag/"/>
        <id>https://masatakashiwagi.com/blog/integrate-spreadsheets-to-bigquery-with-digdag/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/integrate-spreadsheets-to-bigquery-with-digdag/">&lt;p&gt;今回は，teamaya という個人プロジェクトで進めている&lt;strong&gt;データ連携&lt;&#x2F;strong&gt;の話をしようと思います．コードは以下のリポジトリに置いてあるので，ご自由に使用下さい！&lt;&#x2F;p&gt;
&lt;iframe class=&quot;hatenablogcard&quot; style=&quot;width:100%;height:155px;margin:15px 0;max-width:680px;&quot; title=&quot;masatakashiwagi&#x2F;teamaya: This is a repository for Data integration and Machine Learning Pipeline.&quot; src=&quot;https:&#x2F;&#x2F;hatenablog-parts.com&#x2F;embed?url=https:&#x2F;&#x2F;github.com&#x2F;masatakashiwagi&#x2F;teamaya&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;具体的には，手元にあるスプレッドシートのデータを BigQuery の特定のテーブルに連携します．普段家計簿のデータをスプレッドシートに手入力で管理しているのですが，そのデータを BigQuery に集めて色々と検証できればという思いから，データ連携を始めてみました．加えて，可視化していきたいので，Data Studio でダッシュボードを作ったりもしています．&lt;&#x2F;p&gt;
&lt;p&gt;データ連携をするだけであれば，Embulk を単体実行するで事足りますが，今回はサーバーモードで立ち上げた Digdag UI を使ってワークフローを実行していきます．スケジュール実行・ワークフロー管理や履歴管理などが UI からだとしやすく，使い心地などを知るためにも使用してみました．また，Docker コンテナで実行できるような構成にしました．Docker 化することで，簡単に別環境に持っていくことができるし，スクラップ &amp;amp; ビルドがしやすいのもあります．&lt;&#x2F;p&gt;
&lt;p&gt;今回は以下の2種類の方法でデータを連携する方法を紹介します．内容的には既に技術記事に書かれているものが多いと思いますが，今回は Docker コンテナで各タスクが実行できるようにしています．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Docker コンテナ内から Embulk を直接実行して，データを転送する方法&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Digdag UI からワークフローを実行して，データを転送する方法&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;こちらも裏側では，Embulk が実行される&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;今回のデータ連携フローのアーキテクチャーは以下のような感じです．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;integrate_spreadsheets_to_bigquery_with_digdag&#x2F;teamaya-data-workflow.png&quot; alt=&quot;データ連携フローのアーキテクチャー&quot; title=&quot;データ連携フローのアーキテクチャー&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;アンドリュー・カーネギーの以下の名言にもあるように，機械学習エコシステムを自分で作っていくために，一歩一歩進めている！&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;最も高い目標を達成するには、一歩一歩進むしかないという事実を、頭に入れておかなければならない。&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;bigquery-tosupuretudositonoshe-ding&quot;&gt;BigQuery とスプレッドシートの設定&lt;&#x2F;h2&gt;
&lt;p&gt;GCP のアカウント登録方法は割愛しますが，gmail があれば簡単に登録できます．登録が完了したら，適当な&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cloud.google.com&#x2F;resource-manager&#x2F;docs&#x2F;creating-managing-projects&quot;&gt;プロジェクトを作成&lt;&#x2F;a&gt;します．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;google-sheets-api-noyou-xiao-hua-woxing-u&quot;&gt;Google Sheets API の有効化を行う&lt;&#x2F;h3&gt;
&lt;p&gt;「APIとサービス」 → 「ライブラリ」と画面遷移し，検索窓に「&lt;strong&gt;Google Sheets API&lt;&#x2F;strong&gt;」と入力して検索すると，スプレッドシートの API を有効化できる画面に遷移するので，有効化を行います．ここで有効化しておかないと，この後スプレッドシートを使用したデータ連携が出来ないので要注意です！&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;integrate_spreadsheets_to_bigquery_with_digdag&#x2F;teamaya-google-sheets-api.png&quot; alt=&quot;Google Sheets API&quot; title=&quot;Google Sheets API&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sabisuakauntonozuo-cheng&quot;&gt;サービスアカウントの作成&lt;&#x2F;h3&gt;
&lt;p&gt;それが終わったら，サービスアカウントを作成していきます．「IAM と管理」 → 「サービスアカウント」へアクセスした後，必要な情報を入力し，キーの作成から JSON を選択してキーの作成を行います．そうすると，サービスアカウントの JSON ファイルがダウンロードされるので，これを &lt;code&gt;~&#x2F;.gcp&lt;&#x2F;code&gt; 配下に置いておきます．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sabisuakauntonomeruadoresuwosupuretudositonideng-lu&quot;&gt;サービスアカウントのメールアドレスをスプレッドシートに登録&lt;&#x2F;h3&gt;
&lt;p&gt;データ連携したいスプレッドシートを開き，右上の共有ボタンから「ユーザーやグループを追加」の枠にダウンロードしたサービスアカウントのメールアドレスをコピー &amp;amp; ペーストして，送信をクリックします．そうすることで，このスプレッドシートのデータを登録したサービスアカウントで転送することができるようになります．&lt;&#x2F;p&gt;
&lt;p&gt;ここで，メールアドレスの許可をしていない場合，Embulk 実行時に以下のエラーが発生します．&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Error: (ClientError) forbidden: The caller does not have permission&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;bigquery-nidetasetutowozuo-cheng&quot;&gt;BigQuery にデータセットを作成&lt;&#x2F;h3&gt;
&lt;p&gt;データを格納するために，事前にデータセットを作成しておく必要があるので，データセット ID を適当に決めて，データセットの作成を行っておきます．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-embulk-wozhi-jie-shi-xing-sitedetazhuan-song-woxing-uchang-he&quot;&gt;1. Embulk を直接実行してデータ転送を行う場合&lt;&#x2F;h2&gt;
&lt;p&gt;この方法は，Docker コンテナ内から Embulk を直接実行して，スプレッドシートのデータを BigQuery のテーブルに転送します．&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.embulk.org&#x2F;&quot;&gt;Embulk&lt;&#x2F;a&gt; の細かい説明は割愛しますが，簡単に言えば，バルクデータローダーの役割として BigQuery などのデータレイク&#x2F;データウェアハウスにデータ転送を行うことができます．&lt;&#x2F;p&gt;
&lt;p&gt;データ転送を行うために用意するものとしては，以下になります．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Gemfile&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Liquid ファイル&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Dockerfile &amp;amp; docker-compose.yml ファイル&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;gemfile-woyong-yi-suru&quot;&gt;Gemfile を用意する&lt;&#x2F;h3&gt;
&lt;p&gt;Embulk のプラグインを Gemfile&#x2F;Gemfile.lock でバージョン管理するために用意します．Embulk には，データの Input&#x2F;Output のプラグインがあリ，これを使うことで様々なデータソースからターゲットにデータを連携することができます．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Input: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;medjed&#x2F;embulk-input-google_spreadsheets&quot;&gt;embulk-input-google_spreadsheets&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Output: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;embulk&#x2F;embulk-output-bigquery&quot;&gt;embulk-output-bigquery&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;source &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;https:&#x2F;&#x2F;rubygems.org&#x2F;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# No versions are specified for &amp;#39;embulk&amp;#39; to use the gem embedded in embulk.jar.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Note that prerelease versions (e.g. &amp;quot;0.9.0.beta&amp;quot;) do not match the statement.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Specify the exact prerelease version (like &amp;#39;= 0.9.0.beta&amp;#39;) for prereleases.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gem &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;embulk&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# input spreadsheets plugin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gem &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;embulk-input-google_spreadsheets&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# ouput bigquery plugin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gem &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;embulk-output-bigquery&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gem &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;tzinfo-data&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;liquid-huairuwozuo-cheng-suru&quot;&gt;Liquid ファイルを作成する&lt;&#x2F;h3&gt;
&lt;p&gt;Embulk の設定ファイルとして Liquid ファイルを作成します．YAML ファイルに設定を記述することもできますが，以下のメリットで Liquid ファイルを使用しています．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;変数を設定することができる&lt;&#x2F;li&gt;
&lt;li&gt;同じ設定内容を共通ファイルとして使うことができる&lt;&#x2F;li&gt;
&lt;li&gt;etc...&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;BigQuery とスプレッドシートの情報は，&lt;code&gt;.env&lt;&#x2F;code&gt; ファイルを作成して，環境変数として管理していて，これらの変数を Liquid ファイルで使用しています．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;in&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; google_spreadsheets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  auth_method&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; service_account&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {% &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;comment %&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; GCPのサービスアカウントのJSONファイルパス {% endcomment %}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  json_keyfile&lt;&#x2F;span&gt;&lt;span&gt;: {{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; env.GCP_SERVICE_JSON&lt;&#x2F;span&gt;&lt;span&gt; }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {% &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;comment %&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; スプレッドシートのURL {% endcomment %}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  spreadsheets_url&lt;&#x2F;span&gt;&lt;span&gt;: {{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; env.SPREADSHEETS_TABLE&lt;&#x2F;span&gt;&lt;span&gt; }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  default_timezone&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;Asia&#x2F;Tokyo&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {% &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;comment %&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; スプレッドシートのワークシートタイトル {% endcomment %}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  worksheet_title&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; year_purchase_amount_2019&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {% &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;comment %&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; headerを指定している場合は2行目からとなる {% endcomment %}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  start_row&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {% &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;comment %&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; カラム名と型を指定する {% endcomment %}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  columns&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; long&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; date&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; timestamp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; format&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;%Y&#x2F;%m&#x2F;%d&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; timezone&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;Asia&#x2F;Tokyo&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; category&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; purchaser&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; purchase_amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; long&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; memo&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;out&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; bigquery&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  mode&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; replace&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  auth_method&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; service_account&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  json_keyfile&lt;&#x2F;span&gt;&lt;span&gt;: {{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; env.GCP_SERVICE_JSON&lt;&#x2F;span&gt;&lt;span&gt; }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {% &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;comment %&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; BigQueryのプロジェクト名 {% endcomment %}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  project&lt;&#x2F;span&gt;&lt;span&gt;: {{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; env.BIGQUERY_PROJECT&lt;&#x2F;span&gt;&lt;span&gt; }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {% &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;comment %&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; BigQueryのデータセット名 {% endcomment %}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  dataset&lt;&#x2F;span&gt;&lt;span&gt;: {{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; env.BIGQUERY_PURCHASE_AMOUNT_DATASET&lt;&#x2F;span&gt;&lt;span&gt; }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {% &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;comment %&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; BigQueryのテーブル名 {% endcomment %}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  table&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; daily_purchase_amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  auto_create_table&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  source_format&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; NEWLINE_DELIMITED_JSON&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  default_timezone&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;Asia&#x2F;Tokyo&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  default_timestamp_format&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;%Y-%m-%d&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  formatter&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; jsonl&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  encoders&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; gzip&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  retries&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;.env&lt;&#x2F;code&gt; ファイルの説明も補足しておくと，適宜設定している環境に合わせて修正していきます．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SPREADSHEETS_TABLE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;該当するスプレッドシートのURL:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; https:&#x2F;&#x2F;docs.google.com&#x2F;spreadsheets&#x2F;d&#x2F;sample&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;BIGQUERY_PROJECT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;BigQueryのプロジェクト名&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;BIGQUERY_PURCHASE_AMOUNT_DATASET&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;BigQueryのデータセット名&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;GCP_SERVICE_JSON&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&#x2F;root&#x2F;.gcp&#x2F;hoge.json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;dockerfile-docker-compose-yml-huairuwozuo-cheng-suru&quot;&gt;Dockerfile &amp;amp; docker-compose.yml ファイルを作成する&lt;&#x2F;h3&gt;
&lt;p&gt;今回は docker 環境から実行するので，Dockerfile と docker-compose.yml ファイルを作成します．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;FROM&lt;&#x2F;span&gt;&lt;span&gt; openjdk:8-alpine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;LABEL&lt;&#x2F;span&gt;&lt;span&gt; MAINTAINER=masatakashiwagi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;ENV&lt;&#x2F;span&gt;&lt;span&gt; DIGDAG_VERSION=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;0.9.42&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;ENV&lt;&#x2F;span&gt;&lt;span&gt; EMBULK_VERSION=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;0.9.23&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; apk --update add --virtual build-dependencies \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    curl \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tzdata \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    coreutils \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bash \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; curl --create-dirs -o &#x2F;bin&#x2F;digdag -L &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;https:&#x2F;&#x2F;dl.digdag.io&#x2F;digdag-${DIGDAG_VERSION}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; curl --create-dirs -o &#x2F;bin&#x2F;embulk -L &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;https:&#x2F;&#x2F;dl.embulk.org&#x2F;embulk-$EMBULK_VERSION.jar&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; chmod +x &#x2F;bin&#x2F;digdag \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; chmod +x &#x2F;bin&#x2F;embulk \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; cp &#x2F;usr&#x2F;share&#x2F;zoneinfo&#x2F;Asia&#x2F;Tokyo &#x2F;etc&#x2F;localtime \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;amp;&amp;amp; apk del build-dependencies --purge&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;ENV&lt;&#x2F;span&gt;&lt;span&gt; PATH=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;$PATH:&#x2F;bin&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Install libc6-compat for Embulk Plugins to use JNI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# cf: https:&#x2F;&#x2F;github.com&#x2F;jruby&#x2F;jruby&#x2F;wiki&#x2F;JRuby-on-Alpine-Linux&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# https:&#x2F;&#x2F;github.com&#x2F;classmethod&#x2F;docker-embulk&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; apk --update add libc6-compat&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Copy Embulk configuration&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;COPY&lt;&#x2F;span&gt;&lt;span&gt; .&#x2F;embulk&#x2F;task &#x2F;opt&#x2F;workflow&#x2F;embulk&#x2F;task&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Make bundle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;WORKDIR&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;opt&#x2F;workflow&#x2F;embulk&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; embulk mkbundle bundle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Copy Gemfile file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# This is the workaround, because jruby directory is not created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;COPY&lt;&#x2F;span&gt;&lt;span&gt; .&#x2F;embulk&#x2F;bundle&#x2F;Gemfile &#x2F;opt&#x2F;workflow&#x2F;embulk&#x2F;bundle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;COPY&lt;&#x2F;span&gt;&lt;span&gt; .&#x2F;embulk&#x2F;bundle&#x2F;Gemfile.lock &#x2F;opt&#x2F;workflow&#x2F;embulk&#x2F;bundle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;WORKDIR&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;opt&#x2F;workflow&#x2F;embulk&#x2F;bundle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Install Embulk Plugins&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; embulk bundle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Set up Digdag Server&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;COPY&lt;&#x2F;span&gt;&lt;span&gt; .&#x2F;digdag &#x2F;opt&#x2F;workflow&#x2F;digdag&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# ADD https:&#x2F;&#x2F;github.com&#x2F;ufoscout&#x2F;docker-compose-wait&#x2F;releases&#x2F;download&#x2F;2.9.0&#x2F;wait &#x2F;bin&#x2F;wait&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# RUN chmod +x &#x2F;bin&#x2F;wait&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;WORKDIR&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;opt&#x2F;workflow&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;CMD&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;tail&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;-f&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&#x2F;dev&#x2F;null&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;bundle 辺りでまわりくどいやり方をしていますが，&lt;code&gt;RUN embulk bundle&lt;&#x2F;code&gt; を実行した際に上手くインストールできなかったため，ワークアラウンドとして，&lt;code&gt;mkbundle&lt;&#x2F;code&gt; した後に Gemfile&#x2F;Gemfile.lock を docker コンテナ内に &lt;code&gt;COPY&lt;&#x2F;code&gt; した上で，&lt;code&gt;RUN embulk bundle&lt;&#x2F;code&gt; を行っています．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;embulk-wo-docker-kontenadeshi-xing-surufang-fa&quot;&gt;Embulk を docker コンテナで実行する方法&lt;&#x2F;h3&gt;
&lt;p&gt;では，実際に Embulk の実行を行うために，まずは Embulk のコンテナサービスを立ち上げます．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# コンテナの立ち上げ&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; compose up&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; embulk&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;バックグラウンドでコンテナを起動しておく．次に dry-run を行うために preview コマンドを実行します．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# dry-run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; exec embulk sh &#x2F;bin&#x2F;embulk preview&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; embulk&#x2F;bundle embulk&#x2F;task&#x2F;spreadsheet&#x2F;export_hab_purchase_amount.yml.liquid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;dry-run 実行後の結果を載せておきます．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;integrate_spreadsheets_to_bigquery_with_digdag&#x2F;teamaya-exec-img1.png&quot; alt=&quot;Embulk dry-run&quot; title=&quot;Embulk dry-run&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;dry-run が問題なかった場合，本番実行を行っていきます．本番は run コマンドを実行します．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# production-run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; exec embulk sh &#x2F;bin&#x2F;embulk run&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; embulk&#x2F;bundle embulk&#x2F;task&#x2F;spreadsheet&#x2F;export_hab_purchase_amount.yml.liquid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;本番実行が上手くいくと BigQuery にデータが入っていることを確認できます．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;integrate_spreadsheets_to_bigquery_with_digdag&#x2F;teamaya-bigquery-img1.png&quot; alt=&quot;Embulk production-run&quot; title=&quot;Embulk production-run&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2-digdag-ui-karawakuhurowoshi-xing-sitedetazhuan-song-woxing-uchang-he&quot;&gt;2. Digdag UI からワークフローを実行してデータ転送を行う場合&lt;&#x2F;h2&gt;
&lt;p&gt;次に説明する方法は，digdag server を立ち上げて，UI 上からワークフローを実行して，スプレッドシートのデータを BigQuery のテーブルに転送する方法になります（バックグラウンドで Embulk が動いている）．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.digdag.io&#x2F;&quot;&gt;Digdag&lt;&#x2F;a&gt; の細かい説明も割愛しますが，こちらも簡単に言えば，設定ファイルでバッチのワークフロー実行を定義・管理できるワークフローエンジンになります．スケジュール実行や失敗時の通知などを行うことができます．&lt;&#x2F;p&gt;
&lt;p&gt;Digdag のワークフローからデータ転送を行うために用意するものとしては，以下になります．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;dig ファイル&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;serverのproperties ファイル&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;docker-compose.yml ファイル&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;上記に加えて，1で説明した Embulk 実行に必要なファイルも用意します．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;dig-huairuwoyong-yi-suru&quot;&gt;dig ファイルを用意する&lt;&#x2F;h3&gt;
&lt;p&gt;個別のワークフローを単発実行する場合は，&lt;code&gt;digdag run hoge.dig&lt;&#x2F;code&gt; で良いですが，今回はUIから実行したいので，厳密には dig ファイルの中身が必要になります．記述する内容としては，ワークフローで実行していくタスクをコードに落としていきます．&lt;&#x2F;p&gt;
&lt;p&gt;Digdag では，エラーの場合や成功した場合に，どういった処理をするのかを書くことができるので，例えば，それぞれの場合で slack に通知もできます．リトライ回数の設定やスケジュール実行の設定もここでできます．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;+task:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    _retry:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    sh&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &#x2F;bin&#x2F;embulk run&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &#x2F;opt&#x2F;workflow&#x2F;embulk&#x2F;bundle &#x2F;opt&#x2F;workflow&#x2F;embulk&#x2F;task&#x2F;spreadsheet&#x2F;export_hab_purchase_amount.yml.liquid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    _error:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;        echo&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; workflow error...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;+success:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; workflow success!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;今回は以下のワークフローになっています．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;task:
&lt;ul&gt;
&lt;li&gt;リトライ回数: 1回&lt;&#x2F;li&gt;
&lt;li&gt;Embulk の実行&lt;&#x2F;li&gt;
&lt;li&gt;エラーの場合は &lt;code&gt;workflow error...&lt;&#x2F;code&gt; を echo する&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;success:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;workflow success!&lt;&#x2F;code&gt; を echo する&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;success は task が正常に終了した場合に，実行されることになります．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;server-no-properties-huairuwoyong-yi-suru&quot;&gt;server の properties ファイルを用意する&lt;&#x2F;h3&gt;
&lt;p&gt;サーバーモードで起動するために，引数にオプションを指定する必要がありますが，それらの設定を &lt;code&gt;server.properties&lt;&#x2F;code&gt; ファイルに集約しています．設定内容は色々とあるので詳しくは&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.digdag.io&#x2F;command_reference.html#server-mode-commands&quot;&gt;公式ドキュメント: server-mode-commands&lt;&#x2F;a&gt;に書かれています．&lt;&#x2F;p&gt;
&lt;p&gt;このファイルには，サーバーの情報やデータベースの情報を記載しています．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;server.bind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0.0.0.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;server.port&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 65432&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;server.admin.bind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0.0.0.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;server.admin.port&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 65433&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;server.access-log.pattern&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;server.access-log.path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &#x2F;var&#x2F;log&#x2F;digdag&#x2F;access_logs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;log-server.type&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = local&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# database情報&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# database.type = memory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;database.type&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = postgresql&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;database.user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = digdag&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;database.password&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = digdag&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;database.host&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = postgres&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;database.port&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 5432&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;database.database&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = digdag&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;database.maximumPoolSize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;サーバーモードで起動すると，ワークフローの情報を保存するために，データベースの設定が必要になります．今回は PostgreSQL を別コンテナで立てて，Digdag コンテナと接続することにしています．ちなみに，これらの情報をインメモリで保存することもできます（この場合は，&lt;code&gt;database.type = memory&lt;&#x2F;code&gt; とする）．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;docker-compose-yml-huairuwozuo-cheng-suru&quot;&gt;docker-compose.yml ファイルを作成する&lt;&#x2F;h3&gt;
&lt;p&gt;色々と試して上手くいかなかったですが，最終的には以下の内容で落ち着きました．service 共通の定義は &lt;code&gt;x-template&lt;&#x2F;code&gt; にまとめています．service は3つありますが，Digdag を使う場合は digdag と postgres のみを立ち上げます．&lt;&#x2F;p&gt;
&lt;p&gt;docker の &lt;code&gt;depends_on&lt;&#x2F;code&gt; は依存関係（起動順序）を指定できますが，DB 起動後のアプリ起動までを制御できるわけではないので，postgres の起動完了前に digdag がアクセスしてしまい起動失敗する事があります．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.docker.com&#x2F;compose&#x2F;startup-order&#x2F;&quot;&gt;Control startup and shutdown order in Compose&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;このため，&lt;code&gt;condition: service_started&lt;&#x2F;code&gt; と設定することで，postgres が起動後に digdag が立ち上がるようにしています．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;depends_on&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  postgres&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    condition&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; service_started&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;また，&lt;code&gt;tty&lt;&#x2F;code&gt; を true に設定しているのは，コンテナが正常終了して止まらないようにするためです．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;version&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;3.8&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Common definition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;x-template&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;template&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  volumes&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ~&#x2F;.gcp:&#x2F;root&#x2F;.gcp:cached&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &#x2F;tmp:&#x2F;tmp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  env_file&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; .env&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;services&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  digdag&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    container_name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; digdag&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    build&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    tty&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    ports&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; 65432:65432&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; 65433:65433&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    volumes&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &#x2F;var&#x2F;run&#x2F;docker.sock:&#x2F;var&#x2F;run&#x2F;docker.sock&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    command&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;java&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;-jar&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&#x2F;bin&#x2F;digdag&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;server&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;-c&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;digdag&#x2F;server.properties&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;--log&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&#x2F;var&#x2F;log&#x2F;digdag&#x2F;digdag_server.log&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;--task-log&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&#x2F;var&#x2F;log&#x2F;digdag&#x2F;task_logs&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    depends_on&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;      postgres&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        condition&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; service_started&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;    &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;template&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  postgres&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    image&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; postgres:13.1-alpine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    container_name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; postgres&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    ports&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; 5432:5432&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    environment&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;      POSTGRES_DB&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; digdag&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;      POSTGRES_USER&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; digdag&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;      POSTGRES_PASSWORD&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; digdag&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    volumes&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &#x2F;tmp&#x2F;data:&#x2F;var&#x2F;lib&#x2F;postgresql&#x2F;data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    tty&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;    &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;template&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  embulk&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    container_name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; embulk&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    build&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;    &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;template&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;networks&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;  default&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    external&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;      name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; teamaya&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;digdag-wo-docker-kontenadeshi-xing-surufang-fa&quot;&gt;Digdag を docker コンテナで実行する方法&lt;&#x2F;h3&gt;
&lt;p&gt;では，Digdag UI を使うために Digdag をサーバーモードで起動します．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# コンテナの立ち上げ&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; compose up&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; digdag&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;バックグラウンドでコンテナを起動しておきます．&lt;code&gt;docker ps&lt;&#x2F;code&gt; コマンドでコンテナが立ち上がっていることを確認したら，&lt;code&gt;http:&#x2F;&#x2F;localhost:65432&#x2F;&lt;&#x2F;code&gt; で UI にアクセスして，以下の画面が表示されたら問題ないです．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;integrate_spreadsheets_to_bigquery_with_digdag&#x2F;teamaya-digdag-ui-img1.png&quot; alt=&quot;Digdag UI&quot; title=&quot;Digdag UI&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;New project から Name を設定したら，Add file をクリックして，dig ファイルのコードをコピー &amp;amp; ペーストします．貼り付けたら，Save で内容を保存します．そしたら，Workflows のタブを選択し，先ほど追加したワークフローが表示されているのでクリックします．右上の Run ボタンを押して実行が完了すると，以下のような結果になります．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;integrate_spreadsheets_to_bigquery_with_digdag&#x2F;teamaya-digdag-ui-img2.png&quot; alt=&quot;Digdag UI&quot; title=&quot;Digdag UI&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Status が Success になっていれば，正常終了で BigQuery にデータが入っているはずです！&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は，手元にあるスプレッドシートのデータを Digdag&#x2F;Embulk を用いて BigQuery に連携するを紹介しました．&lt;&#x2F;p&gt;
&lt;p&gt;やっぱり，UI で直感的に状況や情報がわかるのはメリットだなと感じました．複数のワークフローが動作したりする環境だとそれらも管理できるので良いし，スケジュール実行やエラーや成功時の通知設定なども出来るので活用したいです．また今回は，データ連携に Digdag を使いましたが，他にも Apache Airflow やそのマネージドサービスである Cloud Composer を使っても同等のことができるはずで，この辺りも別途試していきたいです．&lt;&#x2F;p&gt;
&lt;p&gt;個人的な次のステップとしては，Dataform や dbt を使った「&lt;strong&gt;データの品質管理&lt;&#x2F;strong&gt;」に興味があるので，データを Transform したり，テストしたりすることを考えていきたいです．加えて，データレイク&#x2F;データウェアハウス&#x2F;データマートの設計などを併せて学習していきたいです！&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;recruit.gmo.jp&#x2F;engineer&#x2F;jisedai&#x2F;blog&#x2F;introduction-to-digdag&#x2F;&quot;&gt;Digdag 入門&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.slideshare.net&#x2F;ToruTakahashi4&#x2F;embulkdigdag&quot;&gt;EmbulkとDigdagとデータ分析基盤と&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;yukiyan.hatenablog.jp&#x2F;entry&#x2F;2017&#x2F;01&#x2F;23&#x2F;102411&quot;&gt;digdagを DockerizeしてECS上で運用することにしました - 雑なメモ&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gotohayato.com&#x2F;content&#x2F;533&#x2F;&quot;&gt;Docker Compose の depends_on の使い方まとめ&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zenn.dev&#x2F;hohner&#x2F;articles&#x2F;43a0da20181d34&quot;&gt;DockerのTTYって何?&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>teamaya という個人プロジェクトをはじめてみた</title>
        <published>2021-12-12T00:00:00+00:00</published>
        <updated>2021-12-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/personal-project-teamaya/"/>
        <id>https://masatakashiwagi.com/blog/personal-project-teamaya/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/personal-project-teamaya/">&lt;p&gt;最近，データエンジニアリングと MLOps の領域への関心が個人的に高まっていて，何か個人プロジェクトで出来ないかと考えていたところ，普段スプレッドシートで記録している家計簿のデータを使って，データエンジニアリングと MLOps の技術検証をしようという考えに至りました．&lt;&#x2F;p&gt;
&lt;p&gt;そもそも，なんで上記領域への関心が高まってきたかというと，以前までは，ある問題設定に対して，どういったアプローチでその問題を解くかといったモデリング部分に興味があり，特徴量エンジニアリングや新しいアルゴリズムを試すといった部分が楽しいと感じていました．&lt;&#x2F;p&gt;
&lt;p&gt;一方で最近は，そこで作ったモデルはそのままでは機能せず，何らかのシステムに載せて動かし続けることで真価を発揮すると思っていますし，動かし続けて使っていかないと意味がなく，せっかく作ったモデルがもったいないなーという気持ちがあります．&lt;&#x2F;p&gt;
&lt;p&gt;機械学習モデルのシステム化のためには，どういったことを知っておくといいのかを考えた場合，データ連携を含めたデータを貯める部分とモデル作成後の MLOps 部分を理解しておくことが大事だと思うので，ここをより深めていきたいと思った次第です．&lt;&#x2F;p&gt;
&lt;p&gt;データ連携周りは自分自身でモデルを作る際にも，「簡単にデータを取り出せる，品質が保たれているデータ」というのは大事な部分であり，世の中的にもデータを活用する流れはこれからも進んでいき，データ基盤を作れる人の価値は上がっていくと思うので，じゃあそこを自分でも出来るようになっておこうという感じです．&lt;&#x2F;p&gt;
&lt;p&gt;もう一つの MLOps は構成要素が色々あり技術的にも興味深い（サービス名とかは知っているけど，どうやって使うの？的な部分もある）のと，まだまだこの分野の知見は日本でも多くないなという印象なので，しっかり理解しておくと今後より活きてくるかなと感じています．そういった流れの中で，理解も含めて個人プロジェクトでできることをしたいという気持ちです．&lt;&#x2F;p&gt;
&lt;p&gt;技術スタックとしては，普段 BigQuery 以外は業務でもあまり触れる機会がない Google Cloud Platform (GCP) のサービスと OSS を組み合わせてできることをしようと考えています．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;puroziekutoming-teamaya&quot;&gt;プロジェクト名: teamaya&lt;&#x2F;h2&gt;
&lt;p&gt;プロジェクトを始めるにあたりプロジェクト名を決めるとワクワクするので，最初に決めることにしました．沖縄好きなので，沖縄の言葉を組み合わせて何か名前を付けたいと考えていて，沖縄県と東京都のハーフである妻にも相談しながら今回の「&lt;strong&gt;teamaya&lt;&#x2F;strong&gt;」という名前にしました．&lt;&#x2F;p&gt;
&lt;p&gt;github のリポジトリは以下になります（スターもらえると泣いて喜びます😂）．&lt;&#x2F;p&gt;
&lt;iframe class=&quot;hatenablogcard&quot; style=&quot;width:100%;height:155px;margin:15px 0;max-width:680px;&quot; title=&quot;masatakashiwagi&#x2F;teamaya: This is a repository for Data integration and Machine Learning Pipeline.&quot; src=&quot;https:&#x2F;&#x2F;hatenablog-parts.com&#x2F;embed?url=https:&#x2F;&#x2F;github.com&#x2F;masatakashiwagi&#x2F;teamaya&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;&lt;strong&gt;teamaya&lt;&#x2F;strong&gt; は &quot;&lt;strong&gt;team&lt;&#x2F;strong&gt;&quot; と &quot;&lt;strong&gt;maya&lt;&#x2F;strong&gt;&quot; を組み合わせた造語で，team は「〔動物に引かせて～を〕運ぶ、運搬する」という意味があり，maya（マヤー）は沖縄の方言で猫という意味があるので，猫にデータを運んで貰うという意味を込めてこの名前にしました．&lt;&#x2F;p&gt;
&lt;p&gt;ちなみに，リポジトリにあるアイコンのハイビスカス🌺を付けた猫😸は妻に書いてもらいました！&lt;&#x2F;p&gt;
&lt;h2 id=&quot;douitutapuroziekutonanoka&quot;&gt;どういったプロジェクトなのか&lt;&#x2F;h2&gt;
&lt;p&gt;今のところ考えているのは，大きく2つあります．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;データ連携&lt;&#x2F;strong&gt;
&lt;ol&gt;
&lt;li&gt;ローカルのデータをクラウド上に連携&lt;&#x2F;li&gt;
&lt;li&gt;連携したデータをELTツールで変換 &amp;amp; データの品質管理&lt;&#x2F;li&gt;
&lt;li&gt;データの可視化&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;機械学習システムの構築&lt;&#x2F;strong&gt;
&lt;ol&gt;
&lt;li&gt;パイプライン構築&lt;&#x2F;li&gt;
&lt;li&gt;実験管理&lt;&#x2F;li&gt;
&lt;li&gt;モニタリング &amp;amp; 通知&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;まず，データ連携については．ローカルからクラウドへの連携，特に特定のデータソースから BigQuery に連携する部分を実施して，データウェアハウス（DWH）を作ろうと思っています．そこから ELT ツールでデータマート（DM）を作成し，BI ツール（Data Studio など）でデータの可視化を行うといった流れを検証しようと考えています．&lt;&#x2F;p&gt;
&lt;p&gt;個人的には，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dataform.co&#x2F;&quot;&gt;Dataform&lt;&#x2F;a&gt; や &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.getdbt.com&#x2F;&quot;&gt;dbt&lt;&#x2F;a&gt; といったサービスで ELT パイプラインを作って，データ変換やデータの品質管理を一通り試してみたいです．&lt;&#x2F;p&gt;
&lt;p&gt;機械学習システムの構築に関しては，機械学習モデル作成のためのパイプラインや実験管理などを行いつつ，コードのテストやデータ・予測結果のモニタリングなどをできるようにしたいのと，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;feast.dev&#x2F;&quot;&gt;Feast&lt;&#x2F;a&gt; などの feature store を試したりもしたいです．&lt;&#x2F;p&gt;
&lt;p&gt;現状では上記2つを構築していきたいと思っていますが，進めていく中で興味が湧いたものを適宜取り入れていきたいです．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回はプロジェクトを新しく始めたので，その紹介になります．ローカルからクラウドにデータ連携する部分については，既に作成しているので別途内容を紹介したいです．&lt;&#x2F;p&gt;
&lt;p&gt;試行錯誤しながら面白そうなものは色々と取り入れて進めていきますので，もし面白いツールなどがあれば Twitter で教えて欲しいです！&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mlops.toys&#x2F;&quot;&gt;MLOps.toys&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Buy Me a Coffee をブログに追加した話</title>
        <published>2021-12-07T00:00:00+00:00</published>
        <updated>2021-12-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/implement-buy-me-a-coffee-option/"/>
        <id>https://masatakashiwagi.com/blog/implement-buy-me-a-coffee-option/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/implement-buy-me-a-coffee-option/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.buymeacoffee.com&#x2F;&quot;&gt;Buy Me a Coffee&lt;&#x2F;a&gt; というコーヒー1杯をクリエイター活動のサポートという形で寄付するサービスを皆さんは知っていますか？僕はこのサービスの存在を以前から他のエンジニアの個人ブログなどで知っていましたが，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;hurutoriya&quot;&gt;@hurutoriya&lt;&#x2F;a&gt; さんが投稿された&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;shunyaueta.com&#x2F;posts&#x2F;2021-12-04&#x2F;&quot;&gt;こちらの記事&lt;&#x2F;a&gt;を見て，僕も同意することが多かったので，自分の個人ブログでも導入してみたというお話です．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kurieitanohuo-dong-wosapotosurusabisu&quot;&gt;クリエイターの活動をサポートするサービス&lt;&#x2F;h2&gt;
&lt;p&gt;Buy Me a Coffee 以外にも最近は色々とクリエイターの活動をサポートする寄付サービスがあるので紹介しておきます．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.buymeacoffee.com&#x2F;&quot;&gt;Buy Me a Coffee&lt;&#x2F;a&gt;: コーヒー1杯（実際には$5）をクリエイター活動のためにサポートするサービス&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ko-fi.com&#x2F;&quot;&gt;Ko-fi&lt;&#x2F;a&gt;: 名前の通り，サポートしたい人に対してコーヒー代を送るというサービス&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ofuse.me&#x2F;&quot;&gt;OFUSE&lt;&#x2F;a&gt;: 1文字2円で OFUSE レターや OFUSE コメントを書いてサポートするというサービス&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;buy-me-a-coffee-wodao-ru-siyoutosi-tutali-you&quot;&gt;Buy Me a Coffee を導入しようと思った理由&lt;&#x2F;h2&gt;
&lt;p&gt;hurutoriya さんが書かれた内容と概ね一緒ですが，お金が欲しいからというわけではなく（お金が欲しいなら広告を貼ると思う），感謝を伝える1つの手段として，コーヒーを1杯プレゼントするよーという表現が良いなと感じました．また，個人的にコーヒーが好きなので😉&lt;&#x2F;p&gt;
&lt;p&gt;いいね！なども記事を書いた側からすると読んでくれた人からの嬉しいリアクションの1つです．ただ，いいね！以上に読んだ人にとって価値がある技術記事などに対しては，このようなサポートで感謝を伝える方法があってもいいのかなと感じます．サポートして貰った側からすると，誰かのためになってるという感覚をより感じることができるし，何よりもっと有益な内容を届けていこうというモチベーションにも繋がるなと思います．&lt;&#x2F;p&gt;
&lt;p&gt;これらの理由と僕もより良い記事を届けていきたいという想いから，今回 Buy Me a Coffee を導入してみようと思いました．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;実装については，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.buymeacoffee.com&#x2F;brand&quot;&gt;ブランドサイト&lt;&#x2F;a&gt;からロゴやグラフィックがダウンロードすることができます．また，挿入する文字やそのフォント・色など自由にカスタマイズできる Generate ページがあり，そこから Generate を実行すると，HTML に使用できる image code が出来上がるので，それをコピーして簡単にサイトに導入するできます．&lt;&#x2F;p&gt;
&lt;p&gt;今回は，Buy Me a Coffee のサポートセクションをページ最下部に導入して，その導入したお気持ちを書いたポエムでした．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;shunyaueta.com&#x2F;posts&#x2F;2021-12-04&#x2F;&quot;&gt;投げ銭サービスのBuy me a cofee をBlog に導入してみた&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;note.com&#x2F;bissybissy&#x2F;n&#x2F;ncc99bf0d6379&quot;&gt;コーヒー1杯で支援するサービス「ko-fi」と、開発者がコーヒーを奢られる仕組みの話☕&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;note.com&#x2F;sozi_inc&#x2F;n&#x2F;na9d9753263a7&quot;&gt;さまざまな収益化機能をひとつに。クリエイター応援プラットフォーム「OFUSE（オフセ）」誕生。&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>スプレッドシートで行う Mann-Whitney の U 検定</title>
        <published>2021-11-16T00:00:00+00:00</published>
        <updated>2021-11-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/mann-whitney-utest-in-spreadsheet/"/>
        <id>https://masatakashiwagi.com/blog/mann-whitney-utest-in-spreadsheet/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/mann-whitney-utest-in-spreadsheet/">&lt;p&gt;普段は Python の &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;scipy.org&#x2F;&quot;&gt;SciPy&lt;&#x2F;a&gt; というライブラリを用いて，AB テスト実施後の2群間における有意差を調べるために検定を行っていますが，Python を使っていない or このようなライブラリに触れたことがない人でも簡単に検定が行えるようにスプレッドシートを使って Mann-Whitney の U 検定を用意してみました．&lt;&#x2F;p&gt;
&lt;p&gt;公開中のスプレッドシート → &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.google.com&#x2F;spreadsheets&#x2F;d&#x2F;1fxzMimSCCsrONp3dIkaVcxLsv915YGmxM4U4n6XH67I&#x2F;edit?usp=sharing&quot;&gt;Mann-Whitney U-test in spreadsheet&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;コピーしてご自由にお使い下さい（ただし，全自動でない部分があるのでご留意下さい）．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mann-whitney-no-u-jian-ding-toha&quot;&gt;Mann-Whitney の U 検定とは&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mann%E2%80%93Whitney_U_test&quot;&gt;Mann-Whitney（マン・ホイットニー）の U 検定（ウィルコクソンの順位和検定）&lt;&#x2F;a&gt;とは，2つの母集団が特定の分布であることを仮定しないで，「&lt;strong&gt;2つの分布の重なり具合&lt;&#x2F;strong&gt;」を検定します（ノンパラメトリック方法の一つ）．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;del&gt;これは，2つの母集団の中央値の差に注目しています．&lt;&#x2F;del&gt; → &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;elsur.jpn.org&#x2F;mt&#x2F;2018&#x2F;09&#x2F;002684.html&quot;&gt;Divine, et al. (2018) Mann-Whitney 検定は中央値の検定ではない&lt;&#x2F;a&gt;のブログを見ると，中央値の検定というわけではないみたいでした（自分も誤って理解していた）．&lt;&#x2F;p&gt;
&lt;p&gt;U 検定の特徴としては，外れ値の影響を受けにくいなどが挙げられます．一方でよく使われる t 検定の場合は，平均値を見ているので外れ値があるとその影響を受けます．そのため，外れ値除去などの対処が必要なケースが発生します．&lt;&#x2F;p&gt;
&lt;p&gt;ここで，U 検定には以下の仮定があります．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;2つの母集団は互いに独立&lt;&#x2F;li&gt;
&lt;li&gt;2つの母集団の分布が正規分布であると仮定できない&lt;&#x2F;li&gt;
&lt;li&gt;2つの母集団のサンプルサイズが同数でなくても良い&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;また，帰無仮説は下記になります．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;帰無仮説: 2群間に差がない（2つの分布が等しい）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;jian-ding-woxing-ushou-shun&quot;&gt;検定を行う手順&lt;&#x2F;h2&gt;
&lt;p&gt;検定を行う手順を紹介すると，まず A 群と B 群の2つの群を考えます．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;それぞれのサンプルサイズを n1, n2 とした場合に，2つの群を混ぜたデータ (n1+n2) を用意する&lt;&#x2F;li&gt;
&lt;li&gt;1のデータを昇順に並び替える&lt;&#x2F;li&gt;
&lt;li&gt;並び替えたものに対して，順位を割り当てる（ランク付け）．もし同順位を持つ要素が存在する場合は，順位の平均を計算し，その順位の平均を各要素に割り当てる&lt;&#x2F;li&gt;
&lt;li&gt;A 群に属するサンプルの順位和を計算する（=&lt;i&gt;R1&lt;&#x2F;i&gt;）&lt;&#x2F;li&gt;
&lt;li&gt;同様に B 群に属するサンプルの順位和を計算する（=&lt;i&gt;R2&lt;&#x2F;i&gt;）&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;ここまで計算すると，検定統計量（U値）は下記のようになります．&lt;&#x2F;p&gt;
&lt;p&gt;$$ U_1 = n_1n_2 + \frac{n_1(n_1 + 1)}{2} - R_1 $$&lt;&#x2F;p&gt;
&lt;p&gt;$$ U_2 = n_2n_1 + \frac{n_2(n_2 + 1)}{2} - R_2 $$&lt;&#x2F;p&gt;
&lt;p&gt;$$ U = min(U_1, U_2) $$&lt;&#x2F;p&gt;
&lt;p&gt;U が計算できたら，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.real-statistics.com&#x2F;statistics-tables&#x2F;mann-whitney-table&#x2F;&quot;&gt;Mann-Whitney 検定表&lt;&#x2F;a&gt;を用いて有意差5%で棄却できるかどうかを確認します．&lt;&#x2F;p&gt;
&lt;p&gt;α=0.05 の表を眺めて，今回のサンプルサイズ n1, n2 に該当する値と計算した U 値の大小関係を比較して，計算した値が小さい場合には，帰無仮説を棄却する，つまり有意差ありとなります．逆に計算した値の方が大きい場合には，帰無仮説を棄却できないので，有意差なしとなります．&lt;&#x2F;p&gt;
&lt;p&gt;ここで，サンプルサイズが n1&amp;gt;20 または n2&amp;gt;20 の時は，検定統計量 U を標準化して z 値を求めて，標準正規分布で近似する方法を用います．平均値，標準偏差，z値は以下の計算式で求められます．&lt;&#x2F;p&gt;
&lt;p&gt;$$ \mu_u = \frac{n_1n_2}{2} $$&lt;&#x2F;p&gt;
&lt;p&gt;$$ \sigma_u = \sqrt{\frac{n_1n_2(n_1+n_2+1)}{12}} $$&lt;&#x2F;p&gt;
&lt;p&gt;$$ z = \frac{U - \mu_u}{\sigma_u} $$&lt;&#x2F;p&gt;
&lt;p&gt;z 値が計算できたら，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;unit.aist.go.jp&#x2F;mcml&#x2F;rg-orgp&#x2F;uncertainty_lecture&#x2F;normsdist.html&quot;&gt;標準正規分布表&lt;&#x2F;a&gt;を用いて，該当する p 値を確認します．&lt;&#x2F;p&gt;
&lt;p&gt;(z 値をスプレッドシートの組み込み関数である &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;support.google.com&#x2F;docs&#x2F;answer&#x2F;3094089&quot;&gt;NORMSDIST&lt;&#x2F;a&gt; に代入して，1から引くことで p 値を計算している: 式=1-NORMSDIST(z))&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;p≧α の時，帰無仮説を棄却できない&lt;&#x2F;li&gt;
&lt;li&gt;p&amp;lt;α の時，帰無仮説を棄却する．つまり，有意差ありとなる&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;supuretudositode-u-jian-ding-woxing-u&quot;&gt;スプレッドシートで U 検定を行う&lt;&#x2F;h2&gt;
&lt;p&gt;再掲だが，公開しているスプレッドシートは&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.google.com&#x2F;spreadsheets&#x2F;d&#x2F;1fxzMimSCCsrONp3dIkaVcxLsv915YGmxM4U4n6XH67I&#x2F;edit?usp=sharing&quot;&gt;こちら&lt;&#x2F;a&gt;になります．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;mann_whitney_utest_in_spreadsheet&#x2F;u-test1.png&quot; alt=&quot;スプレッドシートで U 検定&quot; title=&quot;U-test&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;サンプルデータとしてグループ AB の身長のデータを載せています．こちらのデータを検定したい2群のデータに適宜変更して貰うと，#検定を行う手順 で紹介した方法に則って p 値の計算がされます．&lt;&#x2F;p&gt;
&lt;p&gt;サンプルサイズが n&amp;lt;=20 の場合は，U値での評価になるので，その場合はリンクにあるマン・ホイットニーの U 検定表を用いて，該当する値から検定結果を見積って貰うと良いです．&lt;&#x2F;p&gt;
&lt;p&gt;※ 補足:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;サンプルデータのデータ順序は意識しないで問題ないです．順序並び替えで自動的に昇順で並び変わります．ただし，順位については，スプレッドシートのマウスオーバーでセルの右下に表示される黒い部分をデータが存在している部分まで下にズラして貰う必要があります（スプレッドシートを完璧に使いこなしているわけではないので，特に順位をつけてる部分が自動化できていないです．もしご存知の方は，方法を教えて貰えると大変助かります🙏）．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は，スプレッドシートを使って Mann-Whitney の U 検定を試してみました．Python を使っていない非エンジニアの方でも検定を行えるようにスプレッドシートに実装してみました．AB テストを実施して検定するまでを誰でも簡単にできるようになれば良いなと思っています．実装していて，スプレッドシートって意外と組み込みの関数が用意されていることを改めて知ることができました．&lt;&#x2F;p&gt;
&lt;p&gt;また，普段ライブラリを何気なく使っていますが，内部の計算方法やどうゆう手続きで出力されるのか，またその値をちゃんと理解して使っていかないとなーということを改めて感じました．例えば，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.scipy.org&#x2F;doc&#x2F;scipy&#x2F;reference&#x2F;generated&#x2F;scipy.stats.mannwhitneyu.html&quot;&gt;scipy.stats.mannwhitneyu&lt;&#x2F;a&gt; は p 値を出すだけであれば良いが，U 値を使いたい場合には少し使いづらいです...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.real-statistics.com&#x2F;statistics-tables&#x2F;mann-whitney-table&#x2F;&quot;&gt;Mann-Whitney Table&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Tensorflow の Callback 関数をカスタマイズ</title>
        <published>2021-11-10T00:00:00+00:00</published>
        <updated>2021-11-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/customize-tensorflow-callback/"/>
        <id>https://masatakashiwagi.com/blog/customize-tensorflow-callback/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/customize-tensorflow-callback/">&lt;p&gt;AWS の SageMaker 上で SageMaker Python SDK を使用して独自の機械学習モデルを作成することができますが，その際に学習や評価が行える &lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sagemaker.readthedocs.io&#x2F;en&#x2F;stable&#x2F;api&#x2F;training&#x2F;estimators.html&quot;&gt;Estimator&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; という SageMaker の interface があります．&lt;&#x2F;p&gt;
&lt;p&gt;一方で，SageMaker Experiments で実験管理を行いたい場合には，この Estimator に色々と渡してあげる必要があります．その中でも学習時に出力される loss の値や評価メトリクスを記録するためには，Estimator の metric_definitions に正規表現を記述して，ログから上手く取得しないといけないです．これをより簡単にするために，CustomCallback 関数を用意しました．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;callback-guan-shu-nokasutamaizu&quot;&gt;Callback 関数のカスタマイズ&lt;&#x2F;h2&gt;
&lt;p&gt;Tensorflow，厳密には Keras の Callback 関数をカスタマイズします．&lt;code&gt;tf.keras.callbacks.Callback&lt;&#x2F;code&gt; クラスを継承した &lt;code&gt;CustomCallBack(tf.keras.callbacks.Callback)&lt;&#x2F;code&gt; クラスを作成し，この作成したクラスを &lt;code&gt;model.fit&lt;&#x2F;code&gt; 時の引数に callbacks として渡します．&lt;&#x2F;p&gt;
&lt;p&gt;今回は SageMaker Experiments で使うことを想定したもので，Estimator の metric_definitions に渡す Regex として，以下のようなログが出力されて欲しいとします（メトリクスは RMSE とした場合を想定）．MetricDefinitions はこちらの &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;sagemaker&#x2F;latest&#x2F;dg&#x2F;automatic-model-tuning-define-metrics.html&quot;&gt;Define Metrics&lt;&#x2F;a&gt; が参考になります．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sagemaker.estimator.Estimator(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;    metric_definitions&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;Name&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;Train Loss&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;Regex&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;train_loss: (.*?);&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;Name&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;Validation Loss&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;Regex&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;val_loss: (.*?);&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;Name&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;Train Metrics&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;Regex&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;train_root_mean_squared_error: (.*?);&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;Name&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;Validation Metrics&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;Regex&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;val_root_mean_squared_error: (.*?);&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;しかしながら，Keras でモデルを作成する際のデフォルトでは，学習時の Loss は &lt;code&gt;loss&lt;&#x2F;code&gt;，メトリクスは &lt;code&gt;root_mean_squared_error&lt;&#x2F;code&gt; で prefix が無い状態になっています．これを Callback 関数をカスタマイズすることで prefix に &lt;code&gt;train_&lt;&#x2F;code&gt; を付けて，Regex で簡単に取得したいというお気持ちです．&lt;&#x2F;p&gt;
&lt;p&gt;Tensorflow 公式ドキュメントの &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.tensorflow.org&#x2F;guide&#x2F;keras&#x2F;custom_callback?hl=en&quot;&gt;Writing your own callbacks&lt;&#x2F;a&gt; や &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.tensorflow.org&#x2F;api_docs&#x2F;python&#x2F;tf&#x2F;keras&#x2F;callbacks&#x2F;Callback&quot;&gt;tf.keras.callbacks.Callback&lt;&#x2F;a&gt; を参考に作成しました．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; tensorflow&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; tf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;CustomCallback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;font-style: italic;text-decoration: underline;&quot;&gt;tf&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;font-style: italic;text-decoration: underline;&quot;&gt;keras&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;font-style: italic;text-decoration: underline;&quot;&gt;callbacks&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;font-style: italic;text-decoration: underline;&quot;&gt;Callback&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; on_train_begin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; logs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;Called at the beginning of training.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; on_train_end&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; logs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;Called at the end of training.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; on_epoch_begin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; logs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;Called at the start of an epoch.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; on_epoch_end&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; logs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;Called at the end of an epoch.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; on_train_batch_begin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; batch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; logs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;Called at the beginning of a training batch in fit methods.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; on_train_batch_end&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; batch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; logs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;Called at the end of a training batch in fit methods.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;上記コードの中で必要なものを修正すれば良くて，今回は学習の開始終了とエポックの終了時に呼ぶように修正しました．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; tensorflow&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; tf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; datetime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;CustomCallBack&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;font-style: italic;text-decoration: underline;&quot;&gt;tf&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;font-style: italic;text-decoration: underline;&quot;&gt;keras&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;font-style: italic;text-decoration: underline;&quot;&gt;callbacks&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;font-style: italic;text-decoration: underline;&quot;&gt;Callback&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; on_train_begin&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; logs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;Called at the beginning of training.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Start training - &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;(datetime.datetime.now())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;        # get parameters&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.epochs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.params[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;epochs&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;        # the epoch when training is stopped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.stopped_epoch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;        # initialize the best loss as infinity&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.best_loss&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np.Inf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;        # list of best metrics values&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.best_metrics_values_list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; on_train_end&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; logs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;Called at the end of training.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.stopped_epoch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            best_values&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39; - &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;.join(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.best_metrics_values_list)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;            print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Epoch &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.stopped_epoch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;: early stopping&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;            print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;Final results: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;best_values&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;Finish training - &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;(datetime.datetime.now())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; on_epoch_end&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; epoch&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; logs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;Called at the end of an epoch.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        keys&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; list&lt;&#x2F;span&gt;&lt;span&gt;(logs.keys())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        metrics_values_list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; keys:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; key.startswith(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;val_&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                metrics_values_list.append(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;logs.get(key)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;:.4f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                metrics_values_list.append(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;train_&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;logs.get(key)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;:.4f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        values&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39; - &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;.join(metrics_values_list)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Epoch &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;epoch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;1}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.epochs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; - &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;values&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        current_loss&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; logs.get(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;val_loss&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; np.less(current_loss,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.best_loss):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.best_loss&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; current_loss&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.best_metrics_values_list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; metrics_values_list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.stopped_epoch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; epoch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F44747;&quot;&gt;--&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;-&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# fit時にcallbacksに作成したカスタマイズクラスをインスタンス化したものを渡す&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;model.fit(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;    callbacks&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;[CustomCallBack()],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;出力は以下のような感じになります．今回は &lt;code&gt;print&lt;&#x2F;code&gt; 文で出力していますが，logger を用意して &lt;code&gt;logger.info&lt;&#x2F;code&gt; を使うのも良さそうです．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Start training&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2021&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F44747;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;48&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;12.787257&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Epoch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; train_loss:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 4.6889&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; train_root_mean_squared_error:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2.1654&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; val_loss:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 11.1416&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; val_root_mean_squared_error:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 3.3379&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F44747;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Finish training&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2021&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F44747;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;48&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;15.095133&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は SageMaker Experiments で実験管理を行う上で，ログ出力の形式を修正したいという動機から CallBack 関数をカスタマイズしました．Callback 関数の中身を知るためにソースコードを読んだりして勉強になりました．Tensorflow のフレームワークは拡張性があり，カスタマイズの方法もドキュメントに整備されているので，比較的容易に修正できます．今回は時間経過や予測時間の表示は省いてしまったので，余裕があればログにこれらを出力するようにしていきたいです．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zhui-ji&quot;&gt;追記&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;2022&#x2F;02&#x2F;24: 更新&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;earlystopping に対応する形式に CallBack 関数を修正しました．&lt;code&gt;current_loss = logs.get(&#x27;val_loss&#x27;)&lt;&#x2F;code&gt; で logs から get する value は &lt;code&gt;callbacks.EarlyStopping(monitor=&#x27;val_loss&#x27;)&lt;&#x2F;code&gt; で &lt;code&gt;monitor&lt;&#x2F;code&gt; に指定している値になります．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sagemaker.readthedocs.io&#x2F;en&#x2F;stable&#x2F;api&#x2F;training&#x2F;estimators.html&quot;&gt;Sagemaker Training APIs - Estimator&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.tensorflow.org&#x2F;guide&#x2F;keras&#x2F;custom_callback?hl=en&quot;&gt;Writing your own callbacks&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.tensorflow.org&#x2F;api_docs&#x2F;python&#x2F;tf&#x2F;keras&#x2F;callbacks&#x2F;Callback&quot;&gt;tf.keras.callbacks.Callback&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Podcast による配信のキッカケとその方法</title>
        <published>2021-06-13T00:00:00+00:00</published>
        <updated>2021-06-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/podcast-broadcast-method/"/>
        <id>https://masatakashiwagi.com/blog/podcast-broadcast-method/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/podcast-broadcast-method/">&lt;p&gt;6月から友人の &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;navitacion&quot;&gt;@navitacion&lt;&#x2F;a&gt; さんと一緒に Podcast の配信を開始しました．テック系の話題など自分たちが興味のある内容をあれこれと話す予定です．Anchor という無料で配信できるプラットフォームを使用していて，チャンネル名は「&lt;strong&gt;Double-M2.fm&lt;&#x2F;strong&gt;」にしました．&lt;&#x2F;p&gt;
&lt;iframe class=&quot;hatenablogcard&quot; style=&quot;width:100%;height:155px;margin:15px 0;max-width:680px;&quot; title=&quot;Double-M2 • A podcast on Anchor&quot; src=&quot;https:&#x2F;&#x2F;hatenablog-parts.com&#x2F;embed?url=https:&#x2F;&#x2F;anchor.fm&#x2F;double-m2&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;各 Episode の要約もあるので，興味を持って頂いた方はこちらからどうぞ．&lt;&#x2F;p&gt;
&lt;iframe class=&quot;hatenablogcard&quot; style=&quot;width:100%;height:155px;margin:15px 0;max-width:680px;&quot; title=&quot;double-m2ml&#x2F;podcast.fm: podcast用のレポジトリ&quot; src=&quot;https:&#x2F;&#x2F;hatenablog-parts.com&#x2F;embed?url=https:&#x2F;&#x2F;github.com&#x2F;double-m2ml&#x2F;podcast.fm&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;このブログでは，navi さんと Podcast を始めたキッカケと実際の配信方法をまとめています．配信方法はあまり検索しても記事が無かったりしたので，これから始めようとしている人の参考になればと，そして Podcast 配信者が一人でも多く増えればなーと想いを込めています．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pei-xin-nokitukake&quot;&gt;配信のキッカケ&lt;&#x2F;h2&gt;
&lt;p&gt;配信のキッカケは初回配信時にもチラッと触れましたが，大きく2つ（+1）あります！&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;コロナ禍で，オフラインイベントが無くなったことで，イベント後に参加者同士で雑談したり，情報交換したりする機会が無くなってしまったので，それを定期的にしたいという想いから&lt;&#x2F;li&gt;
&lt;li&gt;アウトプットを意識するようになって，それを継続的に行っていく場の一つとして，音声による方法もあるのではという想いから&lt;&#x2F;li&gt;
&lt;li&gt;話のタネとしていいかなと笑&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;一つずつ説明していくと，まず①について，これは同じ考えの人も多いんじゃないかなと思いますが，コロナ禍でオンラインでのイベントは多く開催されていて，オフライン時に比べたら移動する手間もなくハードルが下がって，参加人数の制限も実質無制限で，抽選漏れの懸念も無くなりと良いことも多くある一方で，イベント後に参加者同士での会話がほぼほぼ無くなって，雑談とか情報交換したりする機会がかなり減ったと個人的に感じています．&lt;&#x2F;p&gt;
&lt;p&gt;そういった状況で，社外の人と雑談など会話する時間が圧倒的に減ったというのもあり，定期的に情報交換したり意見を言い合える場があると良いなーということで今回 Podcast を始めました（最近だと，Twitter が音声会話サービスの Space を始めて，そこで気軽に会話が生まれるのがスゴく良い）．&lt;&#x2F;p&gt;
&lt;p&gt;②については，かなーーりサボり気味でしたが，アウトプットをちゃんとして行かないとなーという気持ちが高まり，それを強制的に行う一つの方法だったりもします！Podcast で話すために，何かしらの話題を探したり，書籍・論文などを読んで調べたりとトピックの内容を整理する必要があります．また，内容を自分の言葉で相手に説明することで理解の助けになると考えています（人に説明してみると，思ったよりわかってないなーと感じることあるあるだと思う）．&lt;&#x2F;p&gt;
&lt;p&gt;アウトプットの方法の一つとして，ブログにまとめるということ以外に音声でもやろうかなといったところです．あと，普段から「これ！ Podcast で話せるかも」とった意識をするだけで理解の仕方が変わると思うので，この習慣を付けたい狙いも個人的にあります！&lt;&#x2F;p&gt;
&lt;p&gt;最後に③について，これは Twitter 上ではお互い認知していても，リアルだと会ったことない人との話のネタの一つにしようかなという魂胆だったりします笑&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pei-xin-fang-fa&quot;&gt;配信方法&lt;&#x2F;h2&gt;
&lt;p&gt;配信するプラットフォームは，僕が聞いている他の Podcast 配信者のを参考にして，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;anchor.fm&#x2F;&quot;&gt;Anchor&lt;&#x2F;a&gt; にした．Anchor は携帯でも簡単に録音することができて，それを配信できちゃったりもします．&lt;&#x2F;p&gt;
&lt;p&gt;下記が僕たちが配信している各種構成になっています．&lt;&#x2F;p&gt;
 &lt;!----&gt;


&lt;div
  class=&quot;my-4 flex flex-col rounded-lg bg-[var(--admonition-bg)]&quot;
  style=&quot;--admonition-bg: rgba(0, 191, 165, 0.1)&quot;
&gt;
  &lt;div class=&quot;flex items-center rounded-t-lg bg-[var(--admonition-bg)] p-1&quot;&gt;
    &lt;div
      class=&quot;mx-2 h-4 w-4 text-[0] [background:var(--url)_center_center_no-repeat] dark:invert&quot;
      style=&quot;--url: url(.&#x2F;icons&#x2F;tip.svg)&quot;
    &gt;
      tip
    &lt;&#x2F;div&gt;
    &lt;span&gt;&lt;strong&gt;tip&lt;&#x2F;strong&gt;&lt;&#x2F;span&gt;
  &lt;&#x2F;div&gt;
  &lt;div class=&quot;pl-4&quot;&gt;&lt;p&gt;全て無料で行うために，これらの構成にしている，有料でもいい場合はここで紹介したような複数ツールを使わなくて済む．&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;メール: Gmail&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;配信プラットフォーム: Anchor&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;録音: Zencastr&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;画面共有: Google Meet&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;スクリプト: Scrapbox + GitHub&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;編集: Audacity&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;音楽 (BGM): Evoke Music&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;アイコン: Canva&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;1-meru&quot;&gt;1. メール&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;各種サイトにアカウント登録する際にはメールアドレスが必須なので，まず共通で利用するメールアドレスを取得した．&lt;&#x2F;li&gt;
&lt;li&gt;簡単に作成できるので，Gmail を新規作成し利用している．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;2-pei-xin-puratutohuomu&quot;&gt;2. 配信プラットフォーム&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;最初にも書いたが，配信プラットフォームは Anchor を採用した．&lt;&#x2F;li&gt;
&lt;li&gt;アカウントを作成し，Podcast name, description などを設定するだけでよい．無料で使うことができるのでおすすめ！&lt;&#x2F;li&gt;
&lt;li&gt;New Episode から録音したり，既にある音源をアップロードすることも可能になっている．また，BGM なども用意されている．&lt;&#x2F;li&gt;
&lt;li&gt;ただ，遠隔地にいる人同士での複数人録音は出来なさそうだったので，僕たちは録音は別ツールを使うことにした．&lt;&#x2F;li&gt;
&lt;li&gt;音源をアップロードすると，スケジュールでの投稿予約ができる．そして，最初の Episode が登録されると，自分たちだけの Public Site が生成され，そこで新しい Podcast を聴くことができる．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;podcast_broadcast_method&#x2F;podcast-img1.png&quot; alt=&quot;Podcast&quot; title=&quot;Podcast配信画面&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;WHERE TO LISTEN の部分ですが，新しい Podcast が配信されたら，RSS のクローラーが検知して，色んなアプリで聴くことができます！ただし，Spotify と Apple Podcasts に関しては，RSS の URL を登録する必要があります．詳しくは&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;note.com&#x2F;pachi480&#x2F;n&#x2F;nf21f49dee3d5&quot;&gt;こちらのnote記事&lt;&#x2F;a&gt;が参考になるかと思います．ちなみに，RSS の URL は配信が開始したら表示される Settings → Distribution から確認することができます．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-lu-yin&quot;&gt;3. 録音&lt;&#x2F;h3&gt;
&lt;p&gt;録音は Anchor 上では行わず，Zencastr というツールを使っています．Zencastr は複数人の録音も行うことができるので，非常に便利です！&lt;&#x2F;p&gt;
&lt;iframe class=&quot;hatenablogcard&quot; style=&quot;width:100%;height:155px;margin:15px 0;max-width:680px;&quot; title=&quot;Podcasting recording made easy! Start your podcast today&quot; src=&quot;https:&#x2F;&#x2F;hatenablog-parts.com&#x2F;embed?url=https:&#x2F;&#x2F;zencastr.com&#x2F;&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;プランは無料の Hobbyist と有料の Professional があり，僕たちは無料プランを使っていますが，制限としては以下があります．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;無料プランの制限：
&lt;ol&gt;
&lt;li&gt;ゲストは2名まで&lt;&#x2F;li&gt;
&lt;li&gt;1ヶ月あたり8時間の録音時間&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;基本的に二人での配信かつ週1回30分程度の録音時間なので，無料プランで全く問題ないです．また，Zencastr では画面の録画もできるみたいです（※ コロナ期間は，無料プランでもゲストと録音時間が無制限になっている）．&lt;&#x2F;p&gt;
&lt;p&gt;アカウント作成後，Create New Episode で新規作成を行うと，画面と音声の録画・音声録画（画面表示あり）・音声録画のみの3パターンから選択できます．&lt;&#x2F;p&gt;
&lt;p&gt;タイトルを入れて作成すると，下記のような画面が出ます．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;podcast_broadcast_method&#x2F;podcast-img2.png&quot; alt=&quot;Podcast&quot; title=&quot;Zencaster配信画面&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;ここで，Invite をクリックすると同時に会話する人のメールアドレスにリンクを送付する形で招待することができます．Invite した人が入ってくると，そのまま通話状態になり録音を開始することで，そのまま両方の音声を録音することができます．あとは，録音終了後参加していた人の音声を MP3 でダウンロードすることができます（これは管理者のみ可能な操作）．&lt;&#x2F;p&gt;
&lt;p&gt;僕たちは使わなかったですが，Mac でネット通話の音声を録音する方法（Soundflower, LadioCast, GarageBand）の記事を紹介しておきます．→ &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kimu3.net&#x2F;20151109&#x2F;3556&quot;&gt;Mac でネット通話の音声を録音する方法（Soundflower, LadioCast, GarageBand）&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;4-hua-mian-gong-you&quot;&gt;4. 画面共有&lt;&#x2F;h3&gt;
&lt;p&gt;スクリプトなり資料なりを見ながら会話をすることが多いので，画面共有が必要になってきます．そのために，Google Meet を使って画面共有しながら会話するようにしています．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;5-sukuriputo-tai-ben-yao-yue-nado&quot;&gt;5. スクリプト（台本・要約など）&lt;&#x2F;h3&gt;
&lt;p&gt;収録を行う前に，事前に30分程度会話して何を話すか決めてから始めています．その際に，Scrapbox を活用して台本を作成したり，ネタ帳なども雑多に書いたりしています．あとは，共有しておきたいことを Scrapbox に書いて基本的にはここを見ながらいつも収録しています．&lt;&#x2F;p&gt;
&lt;p&gt;参考にした記事 → &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;note.com&#x2F;asteriam&#x2F;n&#x2F;n66527811e0a0&quot;&gt;初めてのポッドキャスト、試して気づいた「声」の醍醐味と9つのティップス&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Scrapbox の他には，GitHub も使っている．こちらは，Organization を作成し，そこに Podcast 用のリポジトリをさらに作成して，自己紹介ページや各配信の収録内容の要約を書き記しています．ページの更新時には issue を作成し，何をしたか記録が残るようにしています．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;podcast_broadcast_method&#x2F;&#x2F;podcast-img3.png&quot; alt=&quot;Podcast&quot; title=&quot;Github画面&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;6-bian-ji&quot;&gt;6. 編集&lt;&#x2F;h3&gt;
&lt;p&gt;編集に関しては，特別何かしているわけではないです．なるべく時間をかけず無理なく進めていきたいと思っているので，下記2点を実施しています．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;音量調整・BGM 挿入&lt;&#x2F;li&gt;
&lt;li&gt;収録中に予期しない割り込みが入って，収録を止めた際のトリミング・不要な会話の削除&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;一通り自分たちの会話を聞いて，気になる部分があればトリミングなどしているぐらいです．&lt;&#x2F;p&gt;
&lt;p&gt;編集ソフトは &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.audacityteam.org&#x2F;&quot;&gt;Audacity&lt;&#x2F;a&gt; を使っていて，Windows・Mac どちらも使用することができる昔からある音楽編集ソフトになります．他に，Mac の場合だと初めから入っている GarageBand なども使えるみたいです．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;7-yin-le-bgm&quot;&gt;7. 音楽 (BGM)&lt;&#x2F;h3&gt;
&lt;p&gt;Podcast を配信する時には，自分たちの音声に加えて BGM を追加しています．ただ，自分たちのコンテンツに BGM を使用する場合には，著作権などが絡んでくるので，安易に好きな曲を使用することはできないです．楽曲1つ1つ確認するのは大変なので，今回は著作権フリーで AI が曲を作成してくれる &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;evokemusic.ai&#x2F;ja&quot;&gt;Evoke Music&lt;&#x2F;a&gt; というサイトの音源を使用しています．&lt;&#x2F;p&gt;
&lt;p&gt;このサイトでは，キーワードを指定することで，そのキーワードに合った曲を AI が自動で作成してくれて，1曲あたり数分程度の曲になります．&lt;&#x2F;p&gt;
 &lt;!----&gt;


&lt;div
  class=&quot;my-4 flex flex-col rounded-lg bg-[var(--admonition-bg)]&quot;
  style=&quot;--admonition-bg: rgba(255, 145, 0, 0.1)&quot;
&gt;
  &lt;div class=&quot;flex items-center rounded-t-lg bg-[var(--admonition-bg)] p-1&quot;&gt;
    &lt;div
      class=&quot;mx-2 h-4 w-4 text-[0] [background:var(--url)_center_center_no-repeat] dark:invert&quot;
      style=&quot;--url: url(.&#x2F;icons&#x2F;warning.svg)&quot;
    &gt;
      warning
    &lt;&#x2F;div&gt;
    &lt;span&gt;&lt;strong&gt;warning&lt;&#x2F;strong&gt;&lt;&#x2F;span&gt;
  &lt;&#x2F;div&gt;
  &lt;div class=&quot;pl-4&quot;&gt;&lt;p&gt;β版の時は無料で使えていたが，今は有料になってしまったみたい．&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;8-aikon-kabaatonado&quot;&gt;8. アイコン（カバーアートなど）&lt;&#x2F;h3&gt;
&lt;p&gt;Anchor にはカバーアートが設定できるので，そのアイコンなどを作成するために，Canva というデザインサイトを利用しています．Canva は豊富なテンプレートデザインがあるので，それをベースに自分でいい感じに編集するだけでかなりオシャレなロゴなどを作成することができます．&lt;&#x2F;p&gt;
&lt;p&gt;無料プランだと保存時の画像サイズや解像度などを変更できないので，少し残念ですが，総じて使い勝手が良いです．有料だともっと出来る幅が増えそうですが，現状だと無料プランでも十分かなと思っています．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は6月から開始した Podcast について，やろうと思ったキッカケとその配信方法をまとめました．配信方法については意外と記事がなかったので，もしこれから配信しようと考えている人の参考になれば嬉しいです！一人でも多くのテック系 Podcast が増えて盛り上がると良いなと思います！！&lt;&#x2F;p&gt;
&lt;p&gt;P.S. 細かい設定や登録など聞きたいことがある場合には，遠慮なく Twitter などでご連絡下さい．また，こちらのブログは内容が古くなっているので，ご注意下さい！&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Kaggle-Shopee コンペの振り返りとソリューション</title>
        <published>2021-05-14T00:00:00+00:00</published>
        <updated>2021-05-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/kaggle-shopee-solution/"/>
        <id>https://masatakashiwagi.com/blog/kaggle-shopee-solution/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/kaggle-shopee-solution/">&lt;p&gt;Kaggle-Shopee に参加したので，コンペの振り返りとソリューションを書き留めます．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kaggle-shopee-konpenozhen-rifan-ri&quot;&gt;Kaggle-Shopee コンペの振り返り&lt;&#x2F;h2&gt;
&lt;p&gt;2021&#x2F;03&#x2F;09~2021&#x2F;05&#x2F;11の期間で&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&quot;&gt;Shopee コンペ&lt;&#x2F;a&gt;が開催されました．&lt;&#x2F;p&gt;
&lt;p&gt;2週間程度しか手を動かせなかったですが，久しぶりに参加したので備忘録として記録を残しておきます．最終的な結果は179th&#x2F;2464の銅メダルで，特に凝ったことは何もしていなかったので，妥当かなと思います．このコンペは上位10チーム中7チームが日本人チームで，日本人のレベルの高さを改めて実感できるコンペでした！&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gai-yao&quot;&gt;概要&lt;&#x2F;h2&gt;
&lt;p&gt;コンペの内容は簡単に言うと，画像とテキスト情報を用いて2つの画像の類似性を比較し，どのアイテムが同じ商品であるかを予測するコンペになります．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;開催期間: 2021&#x2F;03&#x2F;09 ~ 2021&#x2F;05&#x2F;11&lt;&#x2F;li&gt;
&lt;li&gt;参加チーム数: 2464&lt;&#x2F;li&gt;
&lt;li&gt;予測対象: &lt;code&gt;posting_id&lt;&#x2F;code&gt; 列にマッチする全ての posting_id
&lt;ul&gt;
&lt;li&gt;ただし，posting_id は必ず self-match し，グループの上限は50個となっている&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;データ: 投稿ID，画像，商品のタイトル，画像の知覚ハッシュ (perceptual hash)，ラベルグループID&lt;&#x2F;li&gt;
&lt;li&gt;評価指標: F1-Score&lt;&#x2F;li&gt;
&lt;li&gt;その他: コードコンペ&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;my-solution&quot;&gt;My Solution&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;kaggle_shopee_solution&#x2F;my-solution.png&quot; alt=&quot;My Solution&quot; title=&quot;my solution&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;画像特徴量・テキスト特徴量・画像の phash 値を concat して結果をユニーク化したものを最終的な予測値としました．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;image-model&quot;&gt;Image Model&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;eca_nfnet_l0
&lt;ul&gt;
&lt;li&gt;loss: ArcFace&lt;&#x2F;li&gt;
&lt;li&gt;pooling: AdaptiveAvgPool2d&lt;&#x2F;li&gt;
&lt;li&gt;scheduler: CosineAnnealingLR&lt;&#x2F;li&gt;
&lt;li&gt;loss(criterion): CrossEntropyLoss&lt;&#x2F;li&gt;
&lt;li&gt;size: 512*512&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;eca_nfnet_l1
&lt;ul&gt;
&lt;li&gt;loss: CurricularFace&lt;&#x2F;li&gt;
&lt;li&gt;pooling: MAC&lt;&#x2F;li&gt;
&lt;li&gt;scheduler: CosineAnnealingLR&lt;&#x2F;li&gt;
&lt;li&gt;loss(criterion): FocalLoss&lt;&#x2F;li&gt;
&lt;li&gt;size: 512*512&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;efficientnet_b3
&lt;ul&gt;
&lt;li&gt;loss: ArcFace&lt;&#x2F;li&gt;
&lt;li&gt;pooling: GeM&lt;&#x2F;li&gt;
&lt;li&gt;scheduler: CosineAnnealingLR&lt;&#x2F;li&gt;
&lt;li&gt;loss(criterion): FocalLoss&lt;&#x2F;li&gt;
&lt;li&gt;size: 512*512&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;swin_small_patch4_window7_224
&lt;ul&gt;
&lt;li&gt;loss: CurricularFace&lt;&#x2F;li&gt;
&lt;li&gt;scheduler: CosineAnnealingLR&lt;&#x2F;li&gt;
&lt;li&gt;loss(criterion): FocalLoss&lt;&#x2F;li&gt;
&lt;li&gt;size: 224*224&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;common
&lt;ul&gt;
&lt;li&gt;augmentation by albumentations.
&lt;ul&gt;
&lt;li&gt;HorizontalFlip&lt;&#x2F;li&gt;
&lt;li&gt;VerticalFlip&lt;&#x2F;li&gt;
&lt;li&gt;Rotate&lt;&#x2F;li&gt;
&lt;li&gt;RandomBrightness&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;optimizer
&lt;ul&gt;
&lt;li&gt;Adam&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;shao-sigong-fu-sitapointo&quot;&gt;少し工夫したポイント&lt;&#x2F;h4&gt;
&lt;p&gt;画像特徴量を抽出する部分で，いくつか工夫した点をあげます（&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;cmp.felk.cvut.cz&#x2F;cnnimageretrieval&#x2F;&quot;&gt;CNN Image Retrieval&lt;&#x2F;a&gt; を参考にした）．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;loss に &lt;code&gt;ArcFace&lt;&#x2F;code&gt; と &lt;code&gt;CurricularFace&lt;&#x2F;code&gt; を用いた
&lt;ul&gt;
&lt;li&gt;ArcFace を使っている人が多かったが，CurricularFace も使った．スコア的には CurricularFace の方がよかった．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;いくつかのモデルで pooling 層に &lt;code&gt;GeM&lt;&#x2F;code&gt; と &lt;code&gt;MAC&lt;&#x2F;code&gt; を用いた
&lt;ul&gt;
&lt;li&gt;Google Landmark Retrieval Challenge で上手くいっていた GeM や MAC などのプーリング手法を用いた．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;loss (criterion) に &lt;code&gt;FocalLoss&lt;&#x2F;code&gt; を用いた&lt;&#x2F;li&gt;
&lt;li&gt;最終的に得られた特徴量を concat した後，&lt;code&gt;ZCAWhitening&lt;&#x2F;code&gt; による次元削減を行った&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 id=&quot;you-xiao-denakatutamono&quot;&gt;有効でなかったもの&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;一方で，上手くいかなかった取り組み
&lt;ul&gt;
&lt;li&gt;resnext50_32x4d&lt;&#x2F;li&gt;
&lt;li&gt;swin_small_patch4_window7_224 with ArcFace&lt;&#x2F;li&gt;
&lt;li&gt;CosFace, AdaCos&lt;&#x2F;li&gt;
&lt;li&gt;PCA Whitening (worse than ZCAWhitening)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;text-model&quot;&gt;Text Model&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;paraphrase-xlm-r-multilingual-v1
&lt;ul&gt;
&lt;li&gt;loss: ArcFace&lt;&#x2F;li&gt;
&lt;li&gt;scheduler: linear schedule with warmup&lt;&#x2F;li&gt;
&lt;li&gt;loss(criterion): CrossEntropyLoss&lt;&#x2F;li&gt;
&lt;li&gt;optimizer: AdamW&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;TF-IDF&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;text のモデルは特に改良する時間が取れなかったので，ほとんど手を付けれてなかったです．Transformer と TF-IDF で得られた特徴量それぞれに対して，Cosine Similarity を計算し，text の prediction を作成した程度です．最終的な予測値は画像特徴量とテキスト特徴量に加えて，画像の phash 値を追加して，ユニークを取った値としました．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fan-sheng&quot;&gt;反省&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;post-processing が全然できていなかった
&lt;ul&gt;
&lt;li&gt;他の解法を見るに，post-processing でスコアが伸びているので，この部分は結構大事だったんだなと感じている．&lt;&#x2F;li&gt;
&lt;li&gt;6位の解法にもあるが，今回のコンペでは，label_group の長さが2以上であることから，「予測した結果の posting_id が1つしかない場合，強制的に似たものを持ってきて，2つにする」というアイデアで LB がかなり上がるみたい．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Image と Text を Multi-modal 的にモデルに組み込んで学習することができていなかった&lt;&#x2F;li&gt;
&lt;li&gt;グラフ理論全然わかっていない&lt;&#x2F;li&gt;
&lt;li&gt;色々と細かい部分
&lt;ul&gt;
&lt;li&gt;SAM などの他の optimizer を試したりはできなかった．&lt;&#x2F;li&gt;
&lt;li&gt;Database-side feature augmentation (DBA) &#x2F; Query Extension (QE)
&lt;ul&gt;
&lt;li&gt;全然知らなかったので，&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1610.07940.pdf&quot;&gt;End-to-end Learning of Deep Visual Representations for Image Retrieval&lt;&#x2F;a&gt; を読んで勉強したい．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;閾値の調整&lt;&#x2F;li&gt;
&lt;li&gt;テキストモデルの追加&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;ここからは上位の解法を紹介していきます．数もそれなりにあるので，載せるのは上位5つにしますが，上位5つ以外にも Discussions に投稿されている解法のリンクを載せておきます．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1st-place-solution&quot;&gt;1st Place Solution&lt;&#x2F;h2&gt;
&lt;p&gt;解法はこちら: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238136&quot;&gt;1st Place Solution - From Embeddings to Matches&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;model&quot;&gt;Model&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Image: 2つのモデル
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;eca_nfnet_l1&lt;&#x2F;code&gt; * 2&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Text: 5つのモデル
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;xlm-roberta-large&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;xlm-roberta-base&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;cahya&#x2F;bert-base-indonesian-1.5G&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;indobenchmark&#x2F;indobert-large-p1&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;bert-base-multilingual-uncased&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;loss: ArcFace&lt;&#x2F;li&gt;
&lt;li&gt;pooling した後に batch normalization と feature-wise normalization を行った&lt;&#x2F;li&gt;
&lt;li&gt;ArcFace のチューニングを行った
&lt;ul&gt;
&lt;li&gt;学習段階で徐々に margin を大きくした（埋め込み表現の quality に影響する）
&lt;ul&gt;
&lt;li&gt;画像に対する margin: 0.8~1.0&lt;&#x2F;li&gt;
&lt;li&gt;テキストに対する margin: 0.6~0.8&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;margin を大きくすると，モデルの収束に問題が出たので，以下を行った
&lt;ul&gt;
&lt;li&gt;warmup steps を大きくする&lt;&#x2F;li&gt;
&lt;li&gt;cosinehead に対する learning rate をより大きくする&lt;&#x2F;li&gt;
&lt;li&gt;gradient clipping を行う&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;class-size-adaptive margin も試したが，不均衡性が小さかったため，改善は少しだけだった
&lt;ul&gt;
&lt;li&gt;image: &lt;code&gt;class_size^-0.1&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;text: &lt;code&gt;class_size^-0.2&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;global average pooling の後に FC 層を追加するとモデルが悪くなるが，feature-wise normalization の前に batch normalization を追加するとスコアが改善した&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;kaggle_shopee_solution&#x2F;1st-solution-model.png&quot; alt=&quot;Model&quot; title=&quot;1st solution model&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;features&quot;&gt;Features&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Combining Image &amp;amp; Text Matches（マッチングさせる方法をいくつかトライしている）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ol&gt;
&lt;li&gt;画像の embedding によるマッチングとテキストの embedding によるマッチングを結合する&lt;&#x2F;li&gt;
&lt;li&gt;画像の embedding とテキストの embedding を concat してからマッチングする&lt;&#x2F;li&gt;
&lt;li&gt;1と2を組み合わせてマッチングする&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;これにより，画像の embedding が強く示唆するアイテム・テキストの embedding が強く示唆するアイテム・画像とテキストの embedding がどちらも適度に示唆するアイテムを取り入れることができます．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;kaggle_shopee_solution&#x2F;comb-match.png&quot; alt=&quot;Features&quot; title=&quot;comb match&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Iterative Neighborhood Blending (INB)
&lt;ul&gt;
&lt;li&gt;QE&#x2F;DBA とは少し異なる，embedding からマッチする商品を検索するパイプラインを作った&lt;&#x2F;li&gt;
&lt;li&gt;k-Nearest Neighbor Search:
&lt;ul&gt;
&lt;li&gt;近隣探索ラリブラリ: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;facebookresearch&#x2F;faiss&quot;&gt;faiss&lt;&#x2F;a&gt; (k=51: 50(自身以外)) + 1(自身)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Threshold:
&lt;ul&gt;
&lt;li&gt;コサイン類似度をコサイン距離(=1-コサイン類似度)に変換し，distance &amp;lt; threshold を満たす &lt;code&gt;(matches, distances)&lt;&#x2F;code&gt; のペアを取得した&lt;&#x2F;li&gt;
&lt;li&gt;閾値処理を行う場合，1つのクエリに対して少なくとも2つ以上のマッチがあることがコンペで保証されているので，distance が min2-threshold を超えた場合にのみ，二番目に近いマッチを除外する&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Neighborhood Blending:
&lt;ul&gt;
&lt;li&gt;kNN によるサーチと min2 による閾値処理をした後，各アイテムの &lt;code&gt;(matches, similarities)&lt;&#x2F;code&gt; ペアを取得し，グラフを作成する
&lt;ul&gt;
&lt;li&gt;各ノードはアイテム，エッジの重みは2つのノード間の類似性を示す&lt;&#x2F;li&gt;
&lt;li&gt;近傍のみが繋がっており，閾値条件と min2 条件を満たさないノードは切断される&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;近傍のアイテムの情報を使いたいので，クエリアイテムの embedding を改良し，よりクラスタを明確にする
&lt;ul&gt;
&lt;li&gt;重みとして類似性を持つ近傍の embedding を加重合計し，それをクエリ embedding に追加する
&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;kaggle_shopee_solution&#x2F;nb.png&quot; alt=&quot;Neighborhood Blending&quot; title=&quot;neighborhood blending&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;上図を簡単に説明すると，最初 A は [B,C,D] と繋がっているが，加重合計した結果閾値=0.5の場合，C との接続が切れて，A は [B,D] のみと接続していることがわかる&lt;&#x2F;li&gt;
&lt;li&gt;この NB の処理を評価指標の改善が止まるまで繰り返し実行する&lt;&#x2F;li&gt;
&lt;li&gt;最終的な NB のパイプラインは以下になる
&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;kaggle_shopee_solution&#x2F;nb-pipeline.png&quot; alt=&quot;Neighborhood Blending pipeline&quot; title=&quot;neighborhood blending pipeline&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;About Threhsold Tuning:
&lt;ul&gt;
&lt;li&gt;調整する閾値は全部で10種類ある
&lt;ul&gt;
&lt;li&gt;stage1 の text, image, combination の閾値が3つ&lt;&#x2F;li&gt;
&lt;li&gt;stage2 の閾値が1つ&lt;&#x2F;li&gt;
&lt;li&gt;stage3 の閾値が1つ&lt;&#x2F;li&gt;
&lt;li&gt;直接最終結合部分に繋がる stage1 の text, image の閾値が2つ&lt;&#x2F;li&gt;
&lt;li&gt;stage1~3 の min2 閾値が3つ&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;最終的には stage2,3 の閾値を2つ調整するだけでよかった&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Visualizations of Embeddings before&#x2F;after INB
&lt;ul&gt;
&lt;li&gt;INB の効果を可視化したノートブックが公開されている
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;harangdev&#x2F;shopee-embedding-visualizations-before-after-inb&quot;&gt;(SHOPEE) Embedding Visualizations before&#x2F;after INB&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;見るからに各点が凝集されたクラスタを形成していることがわかる&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;others&quot;&gt;Others&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;画像に対する CutMix(p=0.1)&lt;&#x2F;li&gt;
&lt;li&gt;画像の augmentation
&lt;ul&gt;
&lt;li&gt;horizontal flip のみがよかった&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;madgrad optimizer: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;facebookresearch&#x2F;madgrad&quot;&gt;facebookresearch&#x2F;madgrad&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;学習データ全体を使った学習&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;2nd-place-solution&quot;&gt;2nd Place Solution&lt;&#x2F;h2&gt;
&lt;p&gt;解法はこちら: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238022&quot;&gt;2nd place solution (matching prediction by GAT &amp;amp; LGB)&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238362&quot;&gt;2nd Place Solution Code&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;1st stage: 画像・テキスト・画像+テキストデータに対するコサイン類似度を得るために Metric Learning によるモデルを学習する&lt;&#x2F;li&gt;
&lt;li&gt;2nd stage: 同じ label group に属するアイテムのペアかどうかを識別するために&quot;メタ&quot;モデルを学習する&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;model-1&quot;&gt;Model&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;image: 2つのモデル
&lt;ul&gt;
&lt;li&gt;backbone
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nfnet-F0&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;ViT&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;loss: CurricularFace&lt;&#x2F;li&gt;
&lt;li&gt;optimizer: SAM&lt;&#x2F;li&gt;
&lt;li&gt;embedding の結合: &lt;code&gt;F.normalize(torch.cat([F.normalize(emb1), F.normalize(emb2)], axis=1))&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;text: 3つのモデル + TF-IDF
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;indonesian-bert&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;multilingual-bert&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;paraphrase-xlm&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;image+text: &lt;code&gt;nfnet-F0&lt;&#x2F;code&gt; と &lt;code&gt;indonesian-bert&lt;&#x2F;code&gt; の FC 層の embedding を結合したもの&lt;&#x2F;li&gt;
&lt;li&gt;Training Tips:
&lt;ul&gt;
&lt;li&gt;label group のサイズに基づいた Sample Weighting
&lt;ul&gt;
&lt;li&gt;1 &#x2F; (label group size) ** 0.4&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;features-1&quot;&gt;Features&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;graph-features&quot;&gt;Graph features&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;それぞれのアイテムの top-K コサイン類似度の平均と分散
&lt;ul&gt;
&lt;li&gt;K=5, 10, 15, 30, etc&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;標準化（mean=0, std=1）&lt;&#x2F;li&gt;
&lt;li&gt;Pagerank&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;others-1&quot;&gt;Others&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;テキストの長さ&lt;&#x2F;li&gt;
&lt;li&gt;#の記号&lt;&#x2F;li&gt;
&lt;li&gt;Levenshtein距離&lt;&#x2F;li&gt;
&lt;li&gt;画像ファイルのサイズ&lt;&#x2F;li&gt;
&lt;li&gt;画像の高さと幅&lt;&#x2F;li&gt;
&lt;li&gt;Query Extension&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;ensemble&quot;&gt;Ensemble&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;methodology&quot;&gt;Methodology&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;ローカルデータでそれぞれのモデルのベストな閾値を計算する&lt;&#x2F;li&gt;
&lt;li&gt;上記閾値でそれぞれのモデルの予測値を差し引く&lt;&#x2F;li&gt;
&lt;li&gt;差し引かれた予測値を合計する&lt;&#x2F;li&gt;
&lt;li&gt;合計値&amp;gt;0の場合，アイテムペアが同じグループに属するとする&lt;&#x2F;li&gt;
&lt;li&gt;お互いにエッジを持たないペアを削除する
&lt;ul&gt;
&lt;li&gt;A-B はあるが，B-A がない場合は両方を削除する&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;post-processing&quot;&gt;Post-Processing&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;中間中心性が最も高いエッジを再帰的に削除する（Graph-Based）&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;others-2&quot;&gt;Others&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Performance and Memory Tunings
&lt;ul&gt;
&lt;li&gt;CuDF, cupy, cugraph: GPU を有効に使うためには大事&lt;&#x2F;li&gt;
&lt;li&gt;ForestInference: 40分かかる CPU での推論が2分になる&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Not worked
&lt;ul&gt;
&lt;li&gt;Graph-based の特徴量&lt;&#x2F;li&gt;
&lt;li&gt;固有ベクトルの中心性と jaccard&lt;&#x2F;li&gt;
&lt;li&gt;End-to-end model&lt;&#x2F;li&gt;
&lt;li&gt;Local feature matching&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;3rd-place-solution&quot;&gt;3rd Place Solution&lt;&#x2F;h2&gt;
&lt;p&gt;解法はこちらになります: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238515&quot;&gt;3rd Place Solution (Triplet loss, Boosting, Clustering)&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;model-2&quot;&gt;Model&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;image: 2つのモデル
&lt;ul&gt;
&lt;li&gt;backbone
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;efficientnet_b2&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;ViT (DINO)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;text: 2つのモデル (異なるtokenizersとCLIP)
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;indonesian-bert&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;multilingual-bert&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;common
&lt;ul&gt;
&lt;li&gt;loss: TripletLoss (margin=0.1)&lt;&#x2F;li&gt;
&lt;li&gt;各エポック，label_groups から重複したペアを作成し，各バッチで label_groups から1ペアが挿入される．バッチサイズは128を使っていたため，バッチ毎に64の重複を取得し，ランダムな5点でそれらの各々を比較する&lt;&#x2F;li&gt;
&lt;li&gt;5fold CV で，validation スコアを計算する時は，validation-fold の中から候補を選ぶのではなく，学習サンプル全体から候補を探した
&lt;ul&gt;
&lt;li&gt;この方法は CV&#x2F;LB の gap を抑えて，相関を取ることが出来る&lt;&#x2F;li&gt;
&lt;li&gt;oof を用意して，2nd-level の予測に使用する&lt;&#x2F;li&gt;
&lt;li&gt;CV から得られた5つのモデルで，テストデータに対して推論を行った&lt;&#x2F;li&gt;
&lt;li&gt;より速く推論するためには，validation なしの1つのモデルでテストデータにfitさせること&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;ArcFace は上手くいかなかった&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;features-2&quot;&gt;Features&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;複数モデルを用いて，異なる表現方法を作成するのが良い&lt;&#x2F;li&gt;
&lt;li&gt;全ての embeddings から候補となる近しいものを結合し，ペアが実際に重複しているかどうかにかかわらず，binary target を使用してペアオブジェクトのサンプルを作成する
&lt;ul&gt;
&lt;li&gt;3M点のペアがあり，重複率は4%だった&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;これらに対して，GBM(=CatBoost) を作成し，embedding 毎に計算する
&lt;ul&gt;
&lt;li&gt;pairwise-distances (コサイン類似度，ユークリッド距離など)&lt;&#x2F;li&gt;
&lt;li&gt;両方の点周辺の密度&lt;&#x2F;li&gt;
&lt;li&gt;points ranks&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;最終的には500個特徴量を作成し，CV や LB を使いながら，重複確率による閾値の候補を出す → LB:0.76+&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;post-processing-1&quot;&gt;Post-Processing&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;クラスタリングを行ったが，embeddings を使うのではなく，pairwise-distance を使う&lt;&#x2F;li&gt;
&lt;li&gt;重複推定のために GBM(=CatBoost) の確率を使い，類似度を求める&lt;&#x2F;li&gt;
&lt;li&gt;凝集クラスタリングのアイデアを採用
&lt;ul&gt;
&lt;li&gt;各単一点をクラスタとして開始し，平均的なクラスタサイズが閾値に等しくなるまでそれらをマージしていく&lt;&#x2F;li&gt;
&lt;li&gt;クラスタが単一の場合，最も近傍のクラスタにマージする → LB:0.79&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;others-3&quot;&gt;Others&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;最適化するために
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;half precision(torch AMP)&lt;&#x2F;code&gt; を使って学習と推論を行った&lt;&#x2F;li&gt;
&lt;li&gt;画像モデルの場合，画像の読み込みとリサイズに &lt;code&gt;NVIDIA DALI&lt;&#x2F;code&gt; を使った&lt;&#x2F;li&gt;
&lt;li&gt;GBM の推論には，Rapids ForestInference Library を使った&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;上記の方法を使わないと，2時間で全てのモデルを推論することは不可能だった&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;4th-place-solution&quot;&gt;4th Place Solution&lt;&#x2F;h2&gt;
&lt;p&gt;解法はこちら: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238295&quot;&gt;4th Place Solution&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;model-3&quot;&gt;Model&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;image: backbone に &lt;code&gt;nfnet&lt;&#x2F;code&gt; と &lt;code&gt;efficientnet&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;pooling: GeM＆Avg pooling&lt;&#x2F;li&gt;
&lt;li&gt;embedding が大きいほど，LB のスコアがよくなった&lt;&#x2F;li&gt;
&lt;li&gt;loss: ArcFace&lt;&#x2F;li&gt;
&lt;li&gt;margin の調整が大事だった&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;text: BERTベース + TF-IDF
&lt;ul&gt;
&lt;li&gt;TF-IDF: かなり大きい embedding を生成し，notebook 上ではメモリの制約を受けるため，Random Sparse Projection で次元削減を行った&lt;&#x2F;li&gt;
&lt;li&gt;loss: ArcFace&lt;&#x2F;li&gt;
&lt;li&gt;margin の調整が大事だった&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;kaggle_shopee_solution&#x2F;4th-solution-model.png&quot; alt=&quot;Model&quot; title=&quot;4th solution model&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ensemble-1&quot;&gt;Ensemble&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;画像の embedding・テキスト（BERTベース）の embedding・TF-IDF の embedding を結合して，正規化した&lt;&#x2F;li&gt;
&lt;li&gt;これらのベクトル表現のそれぞれに対して，pairwise コサイン類似度を計算し，3つの行列を作成した
&lt;ul&gt;
&lt;li&gt;最初に二乗し，その後加重平均を取って行列を結合した&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;post-processing-2&quot;&gt;Post-Processing&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;閾値の調整&lt;&#x2F;li&gt;
&lt;li&gt;Rank2 matching
&lt;ul&gt;
&lt;li&gt;もし，A が Rank2 に B を持っており，B は Rank2 に A を持っている場合，お互いに追加する&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Rank2 と Rank3 の違いが大きい場合，Rank2 の ID を追加する&lt;&#x2F;li&gt;
&lt;li&gt;少なくとも1つの他とのマッチング（Rank2 のコサイン類似度が極端に小さくなければ）&lt;&#x2F;li&gt;
&lt;li&gt;Query Expansion&lt;&#x2F;li&gt;
&lt;li&gt;マッチしていない行との再マッチング&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;sonota-shang-wei-jie-fa-norinku&quot;&gt;その他上位解法のリンク&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;vtI8P-ttPrk&quot;&gt;Kaggle ShopeeコンペPrivate LB待機枠＆プチ反省会&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238078&quot;&gt;5th Place Solution&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238010&quot;&gt;6th place solution&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238174&quot;&gt;7th place solution&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238125&quot;&gt;8th Place Solution Overview&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238039&quot;&gt;Public 16th &#x2F; Private 10th Solution&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238181&quot;&gt;11th Place Solution&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238033&quot;&gt;14th Place Gold - Image Text Decision Boundary&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238029&quot;&gt;15th place solution&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238128&quot;&gt;Public 13th &#x2F; Private 16th solution&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;237972&quot;&gt;18th place solution - You really don&#x27;t need big models&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238146&quot;&gt;19 place. Voting and similarity chain&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238126&quot;&gt;26th Place Solution : Effective Cluster Separation and Neighbour Search&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238322&quot;&gt;[31st Place] Object Detection approach&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238110&quot;&gt;Public 39th &#x2F; Private 37th Solution&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238263&quot;&gt;48th Place Silver - Simple Baseline&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238079&quot;&gt;Public 56th &#x2F; Private 57th Solution&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238149&quot;&gt;62th Place Solution (Stacking Logistic Regression)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;shopee-product-matching&#x2F;discussion&#x2F;238167&quot;&gt;72nd place solution&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>VSCode と git を連携して push できるようにするまで</title>
        <published>2021-03-26T00:00:00+00:00</published>
        <updated>2021-03-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/vscode-git-connect/"/>
        <id>https://masatakashiwagi.com/blog/vscode-git-connect/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/vscode-git-connect/">&lt;p&gt;今まで仕事では，開発環境として IntelliJ を使ってましたが，最近は VSCode の人気が高く Extensions も便利なものが多くあるということで，個人的な作業をする時は VSCode を使ってみようと思って使ってます．そんな中で，タイトルにもあるように VSCode から git push しようとしたら，&lt;code&gt;&amp;lt;アカウント名&amp;gt;@github.com: Permission denied (publickey).&lt;&#x2F;code&gt; とエラーが出たので，それを解消して VSCode で git push できるようにした備忘録になります．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;erayuan-yin-ssh-jie-sok-era&quot;&gt;エラー原因（SSH 接続エラー）&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Permission denied (publickey)&lt;&#x2F;strong&gt; とあり，GitHub に SSH 接続するために，公開鍵を登録しておかないといけないのですが，それをしていなかったので，エラーが発生したという感じです．&lt;&#x2F;p&gt;
&lt;p&gt;以下のコマンドを打つことで接続を確認することができます．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;ssh&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -T&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; git@github.com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; git@github.com: Permission denied (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;publickey&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;ではどうすればいいかと言うと，鍵を生成して GitHub に登録すればいいです．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gong-kai-jian-tomi-mi-jian-nozuo-cheng&quot;&gt;公開鍵と秘密鍵の作成&lt;&#x2F;h2&gt;
&lt;p&gt;詳細な作成方法は&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;qiita.com&#x2F;shizuma&#x2F;items&#x2F;2b2f873a0034839e47ce&quot;&gt;こちらの記事&lt;&#x2F;a&gt;が参考になります．&lt;&#x2F;p&gt;
&lt;p&gt;簡単に手順を載せておきます．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ~&#x2F;.ssh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;ssh-keygen&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; rsa&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -b 4096 -C&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&amp;lt;メールアドレス&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; github_rsa&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;  # オプションをいくつか設定して，鍵を生成&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# 以下実行結果（一部マスクしてます）&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;Generating&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; public&#x2F;private rsa key pair.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;Enter&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; passphrase&lt;&#x2F;span&gt;&lt;span&gt; (empty&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; for no passphrase&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;Enter&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; same passphrase again:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;Your&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; identification has been saved in github_rsa.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;Your&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; public key has been saved in github_rsa.pub.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;The&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; key fingerprint is:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;メールアドレ&lt;&#x2F;span&gt;&lt;span&gt;ス&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;The&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; key&amp;#39;s randomart image is:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;+---[RSA 4096]----+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;|===              |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;|.B      o     .  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;|o..  . *     . o |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;|. . . B +. oo .o*|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;| . o * OSo.oooo*+|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;|  . = + = o ..*..|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;|   E . . o . . ..|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;|        . .      |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;|                 |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;+----[SHA256]-----+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;鍵の種類を RSA にし，鍵の長さを4096にしています．ファイル名は github_rsa と設定しました．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;github-nisheng-cheng-sitagong-kai-jian-wodeng-lu&quot;&gt;GitHub に生成した公開鍵を登録&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ~&#x2F;.ssh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;ssh-add&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -K&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; github_rsa&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;  # 秘密鍵をssh-agentデーモンに登録&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;pbcopy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; github_rsa.pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;  # pbcopyコマンドで公開鍵の中身をクリップボードにコピー&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;この後は，コピーした公開鍵の中身を GitHub に登録します．GitHub のアカウントから Settings に進み，SSH and GPG keys を選択し，New SSH key を押して，先程コピーした中身をペーストし，名前を決めて保存します．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ssh-jie-sok-que-ren&quot;&gt;SSH 接続確認&lt;&#x2F;h2&gt;
&lt;p&gt;保存が完了したら，SSH 接続できるか確認するために，以下のコマンドを打って確認します．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;ssh&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -T&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; git@github.com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;Hi &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;ユーザー名&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; You&amp;#39;ve successfully authenticated, but GitHub does not provide shell access.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;remote-she-ding-noshang-shu-ki&quot;&gt;Remote 設定の上書き&lt;&#x2F;h2&gt;
&lt;p&gt;ここまで来たら後一息で，最後に remote の設定を上書きします．以下のような感じでリポジトリ名を書いて，実行すれば OK です．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; remote set-url origin git@github.com:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;ユーザー&lt;&#x2F;span&gt;&lt;span&gt;名&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;リポジトリ&lt;&#x2F;span&gt;&lt;span&gt;名&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;vscode-karagit-push&quot;&gt;VSCode からgit push&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2021&#x2F;vscode_git_connect&#x2F;vscode_git_connect_img.png&quot; alt=&quot;VSCodeからpush&quot; title=&quot;git push from VSCode&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;今までの設定が完了していれば，上記画像の手順で VSCode の画面から簡単に git に commit や push などの操作を行うことができます．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;まだまだ VSCode 初心者なので，使いやすい Extensions を取り入れて開発環境をカスタマイズしていきたいです！&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;qiita.com&#x2F;takuyanin&#x2F;items&#x2F;c6a097028a837052c90c&quot;&gt;初めてのgitは5ステップで完了&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;qiita.com&#x2F;shizuma&#x2F;items&#x2F;2b2f873a0034839e47ce&quot;&gt;GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>RuntimeError: CUDA error: Device-side assert triggered の解決方法</title>
        <published>2021-02-01T00:00:00+00:00</published>
        <updated>2021-02-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/cuda-error-device-side-assert-triggered/"/>
        <id>https://masatakashiwagi.com/blog/cuda-error-device-side-assert-triggered/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/cuda-error-device-side-assert-triggered/">&lt;p&gt;Pytorch でモデルを作成していた際に，「&lt;strong&gt;RuntimeError: CUDA error: device-side assert triggered&lt;&#x2F;strong&gt;」が発生し，原因がよくわからなかったので，調べたことをメモしておきます．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;erafa-sheng-noyuan-yin&quot;&gt;エラー発生の原因&lt;&#x2F;h2&gt;
&lt;p&gt;調べてみると，原因としては以下のようなものがありました．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ライブラリの Version が違う&lt;&#x2F;li&gt;
&lt;li&gt;ラベル&#x2F;クラスの数とネットワークの入出力の shape が異なる&lt;&#x2F;li&gt;
&lt;li&gt;Loss 関数の入力が正確でない&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;などなど...&lt;&#x2F;p&gt;
&lt;p&gt;よくあるのが，下2つかなと思います．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;raberu-kurasunoshu-tonetutowakunoru-chu-li-no-shape-gayi-naru&quot;&gt;ラベル&#x2F;クラスの数とネットワークの入出力の shape が異なる&lt;&#x2F;h3&gt;
&lt;p&gt;想定しているラベルもしくはクラス数とネットワークの出力のクラス数が異なる場合，この場合は FC 層の最後に &lt;code&gt;nn.Linear(input, num_class)&lt;&#x2F;code&gt; を入れて調整する必要があります．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;loss-guan-shu-noru-li-gazheng-que-denai&quot;&gt;Loss 関数の入力が正確でない&lt;&#x2F;h3&gt;
&lt;p&gt;僕が遭遇したのはこちらのパターンになります．&lt;&#x2F;p&gt;
&lt;p&gt;例えば，BCELoss を考えた場合，計算するためには値としては0~1を取る必要があり，そのため普通は最終出力に &lt;strong&gt;Sigmoid関数&lt;&#x2F;strong&gt; or &lt;strong&gt;Softmax関数&lt;&#x2F;strong&gt; を入れます．&lt;&#x2F;p&gt;
&lt;p&gt;それ以外にも Loss の設計で以下のようにしておくと良いです．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;BCELoss&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;font-style: italic;text-decoration: underline;&quot;&gt;nn&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;font-style: italic;text-decoration: underline;&quot;&gt;Module&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;__init__&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.bce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nn.BCELoss()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; forward&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; target&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;        input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch.where(torch.isnan(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;), torch.zeros_like(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;        input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch.where(torch.isinf(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;), torch.zeros_like(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;        input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; torch.where(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, torch.ones_like(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;  # 1を超える場合には1にする&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        target&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; target.float()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.bce(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;, target)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;ta-nojie-jue-fang-fa&quot;&gt;他の解決方法&lt;&#x2F;h3&gt;
&lt;p&gt;他にも調べていると解決方法として CUDA の設定を &lt;code&gt;CUDA_LAUNCH_BLOCKING=1&lt;&#x2F;code&gt; にすると良いなどもありましたが，解決するかどうかはよくわからないです．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は，Pytorch でのモデル作成時に発生したエラーについて簡単に整理しました，モデル作成時にはモデルの In&#x2F;Out や Loss 関数の定義をきちんと理解しておく必要があると改めて感じました．同様のエラーが起きた場合には，この辺りをまずは調べてみるのが良さそうです．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;towardsdatascience.com&#x2F;cuda-error-device-side-assert-triggered-c6ae1c8fa4c3&quot;&gt;CUDA error 59: Device-side assert triggered&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Kaggle-MoA の振り返り</title>
        <published>2020-12-11T00:00:00+00:00</published>
        <updated>2020-12-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/kaggle-moa/"/>
        <id>https://masatakashiwagi.com/blog/kaggle-moa/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/kaggle-moa/">&lt;p&gt;Kaggle-MoA に参加したので，その振り返りを備忘録として残しておきます．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kaggle-moa-konpeni-team-90-s-dechu-can-jia&quot;&gt;Kaggle-MoA コンペに Team 90&#x27;s で初参加&lt;&#x2F;h2&gt;
&lt;p&gt;このブログは2020&#x2F;9&#x2F;4~12&#x2F;1まで開催していた &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kaggle.com&#x2F;c&#x2F;lish-moa&quot;&gt;MoA コンペ&lt;&#x2F;a&gt;での取り組みを紹介します（コンペの詳細な内容については割愛します）．&lt;&#x2F;p&gt;
&lt;p&gt;今回のコンペでは，同世代のメンバーでチームを組んで取り組みました！チーム結成の経緯は，Twitter でお互いが90年生まれということを知って，同世代で Kaggle チーム組んで戦いたいねーというのが少し前のことで，当時取り組める良い感じのコンペがなかったのですが，今回テーブルデータのコンペで取り組めそうということで始まりました．&lt;&#x2F;p&gt;
&lt;p&gt;チームでの取り組みはとにかく学びが多く，終盤までモチベーションを保つことができたのが大きかったです．また，議論することで理解なども深まっていくので，コンペを通してより取り組み方やアイデアなど吸収できたと感じます．&lt;&#x2F;p&gt;
&lt;p&gt;今回の僕たちのチームでの取り組み方を紹介すると，&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;1. 情報は Slack で共有&lt;&#x2F;strong&gt;
&lt;strong&gt;2. 分析方針や実験結果は Github の issue で管理&lt;&#x2F;strong&gt;
&lt;strong&gt;3. 毎週末に2時間程度のディスカッション&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;といった感じでした．&lt;&#x2F;p&gt;
&lt;p&gt;3番目の週末のディスカッションは強制ではなく，参加可能な人が参加する形式で運用してました（と言いつつもみんな真面目に毎回参加していた笑）．&lt;&#x2F;p&gt;
&lt;p&gt;今回はチームでの取り組み方針の具体的な内容について少しだけ掘り下げます．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;1-qing-bao-ha-slack-degong-you&quot;&gt;1. 情報は Slack で共有&lt;&#x2F;h3&gt;
&lt;p&gt;Slack をどうゆう感じで活用していたのかというと，コンペの Discussion や Notebook の内容について疑問点などを話し合ったり，それ以外にも進め方の相談や雑談などを基本的に行ってました．あとは submit する時は一言声をかけるなどの submit 管理もしていました．&lt;&#x2F;p&gt;
&lt;p&gt;こうゆうのがあれば良かったなーというところでは，新着の Discussion や Notebook を Kaggle から連携して通知する仕組みを用意しておければ尚良かったのかなと．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-fen-xi-fang-zhen-yashi-yan-jie-guo-ha-github-no-issue-deguan-li&quot;&gt;2. 分析方針や実験結果は Github の issue で管理&lt;&#x2F;h3&gt;
&lt;p&gt;Github をどうゆう感じで活用していたのかというと，分析での実験毎に1つの issue を立てて，そこでどうゆう実験をしたのか submit した結果のスコアがどうだったのかなどを記録として残していました．また，共通で使える特徴量生成のコードだったり，CV の切り方のコードなどの共有も行ってました．その他には Discussion の内容を整理したり，情報をまとめるために活用したり．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-mei-zhou-mo-ni2shi-jian-cheng-du-nodeisukatusiyon&quot;&gt;3. 毎週末に2時間程度のディスカッション&lt;&#x2F;h3&gt;
&lt;p&gt;週末に Google meet でオンラインディスカッションを行いました．そこで何をしていたかというと，基本的には今週何をしたのかを各々共有したり，わからない部分を話し合ってどうゆうふうに次進めて行くかなどをチームで考えていました．あとは，次の週でどうゆうことをするかの方向性を決めて終わる感じでした．もちろん雑談や仕事での苦労を労ったりもしてました笑&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zui-zhong-shun-wei&quot;&gt;最終順位&lt;&#x2F;h2&gt;
&lt;p&gt;最終順位は4373チーム中&lt;strong&gt;34位の銀メダル&lt;&#x2F;strong&gt;で、金メダルまであともう少しのところまで行ったので，とても悔しい結果となりました．個人的には Inference の処理がエラーで通らない状況に最後の3日ぐらいで発生して泣きそうになってました．チームメンバーには weight0 の状態で非常に申し訳なかったなと思います泣&lt;&#x2F;p&gt;
&lt;p&gt;学習時に回していたノートブックでは，スコアがチーム内で作ったモデルの中でも上位5つ以内に入っていたので，アンサンブル時には効いてただろうなと思うと尚更残念です．個人的な成長としては，テーブルデータに対して NN モデルが有効に作用する場面について多少理解が深まったと感じています．&lt;&#x2F;p&gt;
&lt;p&gt;今回の MoA では，マルチラベルの予測だったので，一度に大量のクラスを予測する場合には NN が有効でかつ GBDT 系と比較して計算速度も速いんだなと感じました．また，特徴量的にも交互作用的な部分は NN 内部の中間層の組み方などで実現できるので，GBDT 系みたく大量に特徴量を用意しなくても対処できるのが大きいのかなと思っています（今回のケースだと GBDT で大量のモデルを作るとなると速度的な部分で特徴量が膨大になるとかなり厳しい）．&lt;&#x2F;p&gt;
&lt;p&gt;あとは，NN の実装を Pytorch で行ったこともあり，Pytorch の扱い方がわかるようになったのは大きかったです（仕事では Tensorflow だったりするので...）．Pytorch での実装に関してはもっと進めて行きたいのとコードの整理も合わせてやっていきます．次に参加予定のコンペではその辺りも意識して挑めたらなーと思います．&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Python でネストしたリストの更新処理をする</title>
        <published>2020-09-12T00:00:00+00:00</published>
        <updated>2020-09-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/python-update-nested-list-object/"/>
        <id>https://masatakashiwagi.com/blog/python-update-nested-list-object/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/python-update-nested-list-object/">&lt;p&gt;Python でリストを複製して，それを更新したい場合はどうするのが良いでしょうか．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;chu-qi-hua-sitarisutonogeng-xin-chu-li-dehamatutesimatuta&quot;&gt;初期化したリストの更新処理でハマってしまった&lt;&#x2F;h2&gt;
&lt;p&gt;今回は，初期化したリストを更新した際にハマってしまった失敗があるので，備忘録として残しておきます．詳しい内容は参考サイトに載っています．&lt;&#x2F;p&gt;
&lt;p&gt;Python で決まった形のリストを予め作成しておきたい場合に，以下のようにすることがあると思います．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;shape you want: [[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;]]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;  # 要素が2つあるリストが3つ&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; list1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; list1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;そして，上記リストを何かしらの値で更新したい場合を考えます．今回だと，&lt;code&gt;[0][0]&lt;&#x2F;code&gt; の要素を更新するとします．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; list1[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 3.5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; list1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;3.5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;3.5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;3.5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;結果は，各リストの0番目の要素が全て更新されます．この原因は，&lt;code&gt;list1 = [[0] * 2] * 3&lt;&#x2F;code&gt; と書くと，要素のリストが全て同じオブジェクトになってしまい，どこかの要素を変更すると全て変わってしまうからです．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dui-chu-fa&quot;&gt;対処法&lt;&#x2F;h2&gt;
&lt;p&gt;上記の結果を回避するためには，リスト内包表記を使うと解決することができます．先程の例の場合，以下のように書くと良いでしょう．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; list2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; list2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;内包表記を使うと，リストはそれぞれ異なるオブジェクトとして扱われます．なので，&lt;code&gt;[0][0]&lt;&#x2F;code&gt; の要素を更新すると，意図した部分だけが更新され問題が発生しません．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; list2[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 3.5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; list2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;3.5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;リストを初期化する際はこれらに注意しておかないと，本来の意図とは違う動きになってしまいます．こういうミスを気にしたくない場合には，numpy の array で作りたい shape を作成し，その後にリストに変換しても良いでしょう．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; np.zeros((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;)).tolist()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;  # 0で初期化&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0.0&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0.0&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0.0&lt;&#x2F;span&gt;&lt;span&gt;]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# 0以外の場合&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;np.ones((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;)).tolist()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;  # 1で初期化&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;np.full((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;).tolist()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;  # 任意の値で初期化&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;note.nkmk.me&#x2F;python-list-initialize&#x2F;&quot;&gt;Pythonのリスト（配列）を任意の値・要素数で初期化&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Hugo を使ったポートフォリオ作成</title>
        <published>2020-07-13T00:00:00+00:00</published>
        <updated>2020-07-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/hugo-portfolio/"/>
        <id>https://masatakashiwagi.com/blog/hugo-portfolio/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/hugo-portfolio/">&lt;p&gt;Hugo で簡単にポートフォリオを作成したので，その備忘録を書きました．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;potohuoriozuo-cheng&quot;&gt;ポートフォリオ作成&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;qiita.com&#x2F;ysdyt&#x2F;items&#x2F;a581277dd1312a0e83c3&quot;&gt;こちら&lt;&#x2F;a&gt;の Qiita の記事で Hugo を使って簡単にポートフォリオを作成できるというのを見かけたので，以前まで使っていた personal page を移植しました．移植した際に少し詰まった部分があるので，Tips としてこの記事で紹介します．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;u&gt;&lt;strong&gt;この記事は以前に使用していた Hugo Theme の内容になります&lt;&#x2F;strong&gt;&lt;&#x2F;u&gt;&lt;&#x2F;p&gt;
&lt;p&gt;最初は &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nodejh&#x2F;hugo-theme-cactus-plus&quot;&gt;Hugo Theme Cactus Plus&lt;&#x2F;a&gt; というテーマで作成してましたが，再度作り直して（再作成した理由は，少しだけ凝ったテーマを使って見たくなったため笑），作り直したテーマは &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;pacollins&#x2F;hugo-future-imperfect-slim&quot;&gt;Hugo Future Imperfect Slim&lt;&#x2F;a&gt; になります．Hugo はシンプルなデザインが多いので非常にオススメです．&lt;&#x2F;p&gt;
&lt;p&gt;基本的な構築方法は上記 Qiita の記事に沿って行っています．別途追加した要素としては，最初に作成した Hugo Theme Cactus Plus と作り直した Hugo Future Imperfect Slim それぞれあるので，この際どちらも紹介します．&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Hugo Theme Cactus Plus&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;メニューの追加設定&lt;&#x2F;li&gt;
&lt;li&gt;Custom-CSS の設定（custom-css の設定は簡単に設定できるので，今回は割愛する）&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Hugo Future Imperfect Slim&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;favicon の設定&lt;&#x2F;li&gt;
&lt;li&gt;github.io でサイトを host した場合の path 設定&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;個人的には，1回目に作成したテーマより2回目の方が簡単でした．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hugo-theme-cactus-plus&quot;&gt;Hugo Theme Cactus Plus&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;meniyunozhui-jia-she-ding&quot;&gt;メニューの追加設定&lt;&#x2F;h4&gt;
&lt;p&gt;Hugo Theme Cactus Plus のテーマでは，デフォルトで About&#x2F;Archive&#x2F;Tags の3つがメニューとして存在しています．今回はそこに Projects を新しく追加したので，その方法を載せておきます．実施することとしては，以下の4ステップになります．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;content&lt;&#x2F;code&gt; 配下に projects ディレクトリを作成し，&lt;code&gt;_index.md&lt;&#x2F;code&gt; ファイルを配置します．記事などのページ情報は &lt;code&gt;content&lt;&#x2F;code&gt; で管理します．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; content&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;│  &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ├── about&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;│  &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ├── posts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;│  &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; └── projects&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;│  &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;     └── _index.md&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;themes&#x2F;layouts&#x2F;partials&lt;&#x2F;code&gt; 配下にある &lt;code&gt;nav.html&lt;&#x2F;code&gt; に Projects のリンクを追記します．これは Tags などのリンクをコピーして，name の部分は projects に修正すれば問題ないです．メニューバーに Projects を表示させるために，この部分を修正する必要があります．&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;themes&#x2F;layouts&#x2F;section&lt;&#x2F;code&gt; 配下に &lt;code&gt;about.html&lt;&#x2F;code&gt; をコピーして，&lt;code&gt;projects.html&lt;&#x2F;code&gt; に rename します．ここに追加することで，セクションのトップページとして扱われることになります．&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;最後に，コマンドラインで &lt;code&gt;hugo&lt;&#x2F;code&gt; を実行します．&lt;code&gt;hugo&lt;&#x2F;code&gt; コマンドを実行することで，必要なものが自動生成・反映されます．&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;以上でメニューを追加することができます（他のテーマでは，もう少し簡単にメニュー追加が可能なものもある）．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hugo-future-imperfect-slim&quot;&gt;Hugo Future Imperfect Slim&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;favicon-noshe-ding&quot;&gt;favicon の設定&lt;&#x2F;h4&gt;
&lt;p&gt;favicon を設定する方法は，下記の3ステップになります．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;まず，下記のデフォルトの &lt;code&gt;config.toml&lt;&#x2F;code&gt; の内容のうち，&lt;code&gt;favicon&lt;&#x2F;code&gt; と &lt;code&gt;faviconVersion&lt;&#x2F;code&gt; を変更します．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;params.meta&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    description         = &amp;quot;A theme by HTML5 UP, ported by Julio Pescador. Slimmed and enhanced by Patrick Collins. Multilingual by StatnMap. Powered by Hugo.&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    author              = &amp;quot;HTML5UP and Hugo&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    favicon             = false &amp;lt;-- trueに変更する&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    svg                 = true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    faviconVersion      = &amp;quot;1&amp;quot; &amp;lt;-- 1を削除する&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    msColor             = &amp;quot;#ffffff&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    iOSColor            = &amp;quot;#ffffff&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;config.toml&lt;&#x2F;code&gt; を修正したら，static 配下に &lt;code&gt;favicon&lt;&#x2F;code&gt; ディレクトリを作成します．&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;static&#x2F;favicon&lt;&#x2F;code&gt; 配下に &lt;code&gt;favicon.ico&lt;&#x2F;code&gt; と &lt;code&gt;favicon-32x32.png&lt;&#x2F;code&gt; を配置します．なぜ favicon-32x32 かというと？&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;layouts&#x2F;partials&#x2F;meta.html&lt;&#x2F;code&gt; の &lt;code&gt;rel=icon&lt;&#x2F;code&gt; に以下が記載されています
&lt;ul&gt;
&lt;li&gt;favicon-32x32&lt;&#x2F;li&gt;
&lt;li&gt;favicon-16x16&lt;&#x2F;li&gt;
&lt;li&gt;site.webmanifest&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;なので，これに合わせて名前を変更するか webmanifest を新しく作成し，その中に諸々の内容を記載する必要があります．&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 id=&quot;github-io-desaitowo-host-sitachang-he-no-path-she-ding&quot;&gt;github.io でサイトを host した場合の path 設定&lt;&#x2F;h4&gt;
&lt;p&gt;今回作成したサイトを github.io で host した場合に起こった事象です．各メニューの URL として，&lt;code&gt;https:&#x2F;&#x2F;&amp;lt;アカウント名&amp;gt;.github.io&#x2F;portfolio&#x2F;home&#x2F;&lt;&#x2F;code&gt; などとなって欲しいのですが，&lt;code&gt;https:&#x2F;&#x2F;&amp;lt;アカウント名&amp;gt;.github.io&#x2F;portfolio&#x2F;portfolio&#x2F;home&#x2F;&lt;&#x2F;code&gt; と &lt;code&gt;portfolio&lt;&#x2F;code&gt; が重なってしまうエラーが発生しました．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;config.toml&lt;&#x2F;code&gt; ファイルに各メニューの設定をする箇所があります．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;menu&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;menu.main&lt;&#x2F;span&gt;&lt;span&gt;]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    name              = &amp;quot;Home&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    identifier        = &amp;quot;home&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    url               = &amp;quot;&#x2F;&amp;quot; &amp;lt;-- &#x2F;を削除する&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    pre               = &amp;quot;&amp;lt;i class=&amp;#39;fa fa-home&amp;#39;&amp;gt;&amp;lt;&#x2F;i&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    weight            = 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;menu.main&lt;&#x2F;span&gt;&lt;span&gt;]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    name              = &amp;quot;About&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    identifier        = &amp;quot;about&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    url               = &amp;quot;&#x2F;about&#x2F;&amp;quot; &amp;lt;-- 先頭の&#x2F;を削除する&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    pre               = &amp;quot;&amp;lt;i class=&amp;#39;far fa-id-card&amp;#39;&amp;gt;&amp;lt;&#x2F;i&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    weight            = 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;menu.main&lt;&#x2F;span&gt;&lt;span&gt;]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    name              = &amp;quot;Blog&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    identifier        = &amp;quot;blog&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    url               = &amp;quot;&#x2F;blog&#x2F;&amp;quot; &amp;lt;-- 先頭の&#x2F;を削除する&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    pre               = &amp;quot;&amp;lt;i class=&amp;#39;far fa-newspaper&amp;#39;&amp;gt;&amp;lt;&#x2F;i&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    weight            = 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;この &lt;code&gt;url&lt;&#x2F;code&gt; の先頭の &lt;code&gt;&#x2F;&lt;&#x2F;code&gt; を削除することで，上記問題を回避することできます．&lt;&#x2F;p&gt;
&lt;p&gt;参考となる記事などがあまりなかったので，試行錯誤しながら行いました．そのため，もっと簡単にする方法が他にもあるかもしれないです．&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Kaggle を始めて半年経って個人的に得たもの</title>
        <published>2019-12-20T00:00:00+00:00</published>
        <updated>2019-12-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/kaggle-get-something/"/>
        <id>https://masatakashiwagi.com/blog/kaggle-get-something/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/kaggle-get-something/">&lt;p&gt;Kaggle を始めて半年ほど経ち，個人的にこの半年で得たものを整理するという意味で「&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;qiita.com&#x2F;advent-calendar&#x2F;2019&#x2F;kaggle-part2&quot;&gt;kaggle その2 Advent Calendar 2019&lt;&#x2F;a&gt;」の20日目を担当します．&lt;&#x2F;p&gt;
&lt;p&gt;簡単な自己紹介として，普段は都内のベンチャー企業で主に製造業のお客さんを相手にデータ分析の仕事と自社製品の開発を8:2ぐらいの割合で仕事をしています．&lt;&#x2F;p&gt;
&lt;p&gt;実は JTC から転職して今の会社は2社目で，働いて2年弱になります．ちなみに前職の JTC では，マーケティングオートメーションツール導入などの SE 的なことをしていたので，以前からバリバリデータサイエンスをしていたわけではないです😅&lt;&#x2F;p&gt;
&lt;p&gt;Kaggle は転職した時ぐらいから知って，すぐやり始めたいと思っていましたが，色々と仕事プライベート共に余裕が無くて満を辞して半年ほど前から本格的に参加し始めました！&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kaggle-woshi-metede-tamono&quot;&gt;Kaggle を始めて得たもの&lt;&#x2F;h2&gt;
&lt;p&gt;今回はそんな半年ほど前から Kaggle を始めて得たものとして大きく3つあり，それについて書いていきます．&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;データサイエンス関連の知識&lt;&#x2F;li&gt;
&lt;li&gt;実務へのフィードバック&lt;&#x2F;li&gt;
&lt;li&gt;人との繋がり&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;1-detasaiensuguan-lian-nozhi-shi&quot;&gt;1. データサイエンス関連の知識&lt;&#x2F;h3&gt;
&lt;p&gt;よく言われていることですが，Kaggle は宝の山であり世界中のデータサイエンティスト・機械学習エンジニアの知恵や情報が特にコードレベルで共有されているのが魅力の一つです．掘れば掘るほど色々と出て来るので，これを活用しない手はないなという印象を持っています．&lt;&#x2F;p&gt;
&lt;p&gt;その中でも，特に個人的に得て良かった知見としては以下の4つかなと思います．&lt;&#x2F;p&gt;
&lt;p&gt;1つ目は，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;特徴量エンジニアリング&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;ドメイン知識に基づく特徴量エンジニアリングが有効であることはもちろん知っていたが，それを作る発想であったり組み立て方が非常に勉強になっている．&lt;&#x2F;li&gt;
&lt;li&gt;また関連して，どの単位で集約した特徴量を作るか，カテゴリカルデータやカウントデータの扱い，エンコーディングの仕方であったりと特徴量の作り方は非常に参考になっている．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;2つ目は，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;パイプライン設計&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;パイプライン設計は Kaggle を始めてから特に意識させられた部分で，参考になる情報をいくつか上げておく．
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;amalog.hateblo.jp&#x2F;entry&#x2F;kaggle-feature-management&quot;&gt;Kaggleで使えるFeather形式を利用した特徴量管理法&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.takapy.work&#x2F;entry&#x2F;2019&#x2F;12&#x2F;14&#x2F;165119&quot;&gt;データ分析コンペで使っているワイの学習・推論パイプラインを晒します&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;hakubishin3&#x2F;kaggle_ieee&quot;&gt;hakubishin-sanのkaggle_ieeeでの実装コード&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;これを意識して良かったこととしては...&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;特徴量の管理が楽になる&lt;&#x2F;li&gt;
&lt;li&gt;試行錯誤した結果をログという形で後から確認できる&lt;&#x2F;li&gt;
&lt;li&gt;結果の再現性も容易になる&lt;&#x2F;li&gt;
&lt;li&gt;計算回した後は寝てられる笑&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;他にも色々と良いことはあるので，是非オススメしたい！後々の再利用のためにも整理しておくと，一から全てを作り出さなくても良いので有用です．&lt;&#x2F;p&gt;
&lt;p&gt;3つ目は，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;バリデーションの重要性&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;モデルの汎化性能を考える上では大事な要素で，Kaggle では特に pubulic LB で上位に入っていても，バリデーション対策を行わないと private LB で大きく shake down してしまう結果になることがよく？あるのかなという印象．
&lt;ul&gt;
&lt;li&gt;学習データの結果が良くてもテストデータで全然良くないとなると使い物にならないので、この辺りは実務でも活きてきます．運用段階で全然使えないモデルが出来上がるのを回避できる方法の1つです．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;4つ目は，&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NN をテーブルデータで使う方法&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;Neural Network は画像認識の領域で使われているが，それをテーブルデータに使う方法が Kaggle では見かける．
&lt;ul&gt;
&lt;li&gt;テーブルコンペでは，GBDT 系のアルゴリズムの方がまだまだ精度的には良いが，モデルの多様性や特徴量抽出の自動化的な部分で NN モデルも十分に活用できる．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;この辺りはもっと kernel などで理解して自分の武器にしていきたい．ただ，前までは選択肢にもなかった気がするので．様々な手法を見た結果得られた知見かなと．&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;2-shi-wu-henohuidobatuku&quot;&gt;2. 実務へのフィードバック&lt;&#x2F;h3&gt;
&lt;p&gt;Kaggle で実施する内容と実務での内容が必ずしも直結するわけではないが，分析スキルの向上は実務でも大きく活きています．&lt;&#x2F;p&gt;
&lt;p&gt;例えば，実務でデータ受領後，EDA を進める中でデータの勘所を掴むのが以前より早くなったのと，何をどうすれば良いかを掴むのが以前よりスピードが上がったと感じます．それによって，案件を進めていくスピードが上がったので，色々と試行錯誤できる時間を確保できるようになったと思います．&lt;&#x2F;p&gt;
&lt;p&gt;また，Kaggle で有効な手法を製品へフィードバックすることも進めているので，自分自身だけでなく会社へも還元できつつあるのかなと．一方で Kaggle が楽しすぎて，仕事中でもコンペのことが気になって手を動かしたくなったり，休日だいたい費やしてるので出不精になったりしています笑&lt;&#x2F;p&gt;
&lt;p&gt;Twitter でも書いてますが，良くも悪くも世界中の人たちと競い合って評価されるので，負けたくない精神は会社でも発揮されます！&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ren-tonoxi-gari&quot;&gt;人との繋がり&lt;&#x2F;h3&gt;
&lt;p&gt;Kaggle を始めてから，もくもく会や勉強会に参加する頻度が増えました．大体最後には懇親会があるので，コンペの話や仕事の話で盛り上がって色々と情報交換が出来ていて楽しい限りです．&lt;&#x2F;p&gt;
&lt;p&gt;あとは，コンペ終了後の反省会に参加することでコンペでの苦しみなどを共有できるのも良いコミュニティーだなと感じます．そういった場で社内以外のデータサイエンティスト・機械学習エンジニアの方々とお話しできるのは非常に良い刺激になっています．自分が知らないことを知ってる人がめっちゃいるので，勉強になりまくってます．&lt;&#x2F;p&gt;
&lt;p&gt;前々から社外での繋がりを増やしたいと思ってたところで Kaggle という共通の話題があり，比較的話がしやすい環境ができて Kaggle 様様です．もっと Kaggle での繋がりを増やして，お互い切磋琢磨できる環境に持っていきたいです．&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;まだまだ半年しか経っていないですが，濃い経験や知見を Kaggle を通して得られているので，これからも継続していきたいです！人との繋がり的には，もう少し仕事面でも色々と相談できる関係性を作って，どんなことをやっててどうゆう課題や問題意識があるかとか聞いてみたいです．&lt;&#x2F;p&gt;
&lt;p&gt;あとは幸いにも，勉強会で知り合った方とコンペでチームを組んで頂けるようになり，次はチームで参加する楽しみも味わう！&lt;&#x2F;p&gt;
&lt;p&gt;最後に Kaggle では、まさに以下の話を体現できるのではと思ってます！&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;頭で理屈をわかったところで，体感を伴わない知識は活用できない（ハリガネサービス）&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;P.S. DSB コンペでメダルを獲得する！&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ja">
        <title>Excel Binary Workbook を Python で処理する方法</title>
        <published>2019-10-05T00:00:00+00:00</published>
        <updated>2019-10-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Masataka Kashiwagi
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://masatakashiwagi.com/blog/excel-processing-using-python/"/>
        <id>https://masatakashiwagi.com/blog/excel-processing-using-python/</id>
        
        <content type="html" xml:base="https://masatakashiwagi.com/blog/excel-processing-using-python/">&lt;p&gt;今回は，先日初めて経験したファイル形式の Excel Binary Workbook (xlsb) に関して，Python で csv にパースする話になります．&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;.xlsx&lt;&#x2F;code&gt; はよくある Excel ファイル形式だが，それのバイナリー形式である &lt;code&gt;.xlsb&lt;&#x2F;code&gt; はあまり見かけないように思います．Excel の闇や Excel との格闘は色々ありますが，今回はそこをグッと堪えて進めたいと思います笑&lt;&#x2F;p&gt;
&lt;h2 id=&quot;xlsb-toha&quot;&gt;.xlsb とは&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.weblio.jp&#x2F;content&#x2F;.xlsb&quot;&gt;Weblio 辞書&lt;&#x2F;a&gt;によると以下のように記載されています．&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;.xlsbとは，Excel 2007で作成したブックを「XML形式でないバイナリブック」として保存する際に用いられる拡張子である．.xlsbでブックを保存した場合はファイル全体がバイナリ形式で保存され，XMLベースである.xlsxなどのファイル形式で保存した場合と比べて，ファイルサイズを数分の1程度に抑えることができる．&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;受け取ったファイルは &lt;code&gt;.xlsb&lt;&#x2F;code&gt; 形式でも100MBぐらいで，&lt;code&gt;.xlsx&lt;&#x2F;code&gt; 形式だとかなり容量が大きく，ファイルを開くと処理が重たくなることが想像できるので，圧縮したのだと考えられます．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;excelwoxi-erupythonraiburari&quot;&gt;Excelを扱えるpythonライブラリ&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;openpyxl&quot;&gt;openpyxl&lt;&#x2F;h3&gt;
&lt;p&gt;定番の &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;openpyxl.readthedocs.io&#x2F;en&#x2F;stable&#x2F;&quot;&gt;openpyxl&lt;&#x2F;a&gt; を使っていきます．ページにも記載されていますが，Excel ファイルの拡張子である &lt;code&gt;.xlsx&lt;&#x2F;code&gt; を扱うことができるのが特徴です．&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;openpyxl is a Python library to read&#x2F;write Excel 2010 xlsx&#x2F;xlsm&#x2F;xltx&#x2F;xltm files.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;いつものようにこのライブラリで処理しようとしたところ，下記のようなエラーが発生しました．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;openpyxl.utils.exceptions.InvalidFileException:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; openpyxl does not support binary format .xlsb, please convert this file to .xlsx format if you want to open it with openpyxl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;もう一度 openpyxl の説明を見ると，確かに扱える拡張子は &lt;code&gt;xlsx&#x2F;xlsm&#x2F;xltx&#x2F;xltm&lt;&#x2F;code&gt; となっているので，&lt;code&gt;.xlsb&lt;&#x2F;code&gt; は扱えないのが分かります．そこで，&lt;code&gt;.xlsb&lt;&#x2F;code&gt; の拡張子が扱えるライブラリを調べたところ，&lt;code&gt;pyxlsb&lt;&#x2F;code&gt; というのがあるみたいで，それを今回は使うことにしました．&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pyxlsb&quot;&gt;pyxlsb&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;wwwiiilll&#x2F;pyxlsb&quot;&gt;pyxlsb&lt;&#x2F;a&gt; は公式の説明にあるように，xlsb 形式を扱える Python ライブラリになります．&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;pyxlsb is an Excel 2007-2010 Binary Workbook (xlsb) parser for Python.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;pip でインストールすることができます．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pip install pyxlsb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;公式のサンプルコードを記載しておきます．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; csv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; pyxlsb&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; open_workbook&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;with&lt;&#x2F;span&gt;&lt;span&gt; open_workbook(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;Book1.xlsb&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; wb:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; wb.sheets:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        with&lt;&#x2F;span&gt;&lt;span&gt; wb.get_sheet(name)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; sheet,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; open&lt;&#x2F;span&gt;&lt;span&gt;(name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;.csv&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;w&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; f:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            writer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; csv.writer(f)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span&gt; row&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; sheet.rows():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                writer.writerow([c.v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; row])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;もし pandas のデータフレームに変換したい場合は，参考ページのコードで変換可能です．ただし，時刻変換に関して少し注意が必要で公式にもある通り，日付は &lt;strong&gt;float&lt;&#x2F;strong&gt; に変換されてしまうため，&lt;strong&gt;convert_date 関数&lt;&#x2F;strong&gt;を使う必要があります．&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note that dates will appear as floats. You must use the convert_date(date) method from the corresponding Workbook instance to turn them into datetime.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;なので，元のファイルに時刻が入っている場合には，上記変換をコードの中に入れて処理する必要があるのでご注意を！&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(wb.convert_date(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;41235.45578&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; datetime.datetime(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;2012&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 22&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;今回は個人的に嵌ってしまった &lt;code&gt;.xlsb&lt;&#x2F;code&gt; 形式のファイルを扱う方法を紹介しましたが，出来ればデータ分析をするようなデータを Excel ファイルで扱いたくないのが本音です😅&lt;&#x2F;p&gt;
&lt;p&gt;もちろん簡単なデータの可視化とか表計算で Excel が活躍する場面は多々ありますが，自動化してデータを分析することを考えると，複雑だったり独自のデータフォーマットで保存することは危険だと思います．&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-kao&quot;&gt;参考&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;45019778&#x2F;read-xlsb-file-in-pandas-python&quot;&gt;Stack Overflow - Read XLSB File in Pandas Python&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;zhui-ji&quot;&gt;追記&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;2020&#x2F;01&#x2F;05: 更新&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;pandas の「&lt;strong&gt;version=1.0.0&lt;&#x2F;strong&gt;」で &lt;code&gt;.xlsb&lt;&#x2F;code&gt; ファイルをロードできるようになったみたいです．方法は &lt;code&gt;pd.read_excel&lt;&#x2F;code&gt; の引数で &lt;code&gt;engine=&quot;pyxlsb&quot;&lt;&#x2F;code&gt; と指定するだけ．&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;# Returns a DataFrame&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pd.read_excel(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;path_to_file.xlsb&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; engine&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;pyxlsb&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;参考: https:&#x2F;&#x2F;pandas.pydata.org&#x2F;docs&#x2F;user_guide&#x2F;io.html#io-xlsb&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
</feed>
