toshiki-notebook/development/aws/handson-qabot.html

215 lines
126 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en-US" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Hands-on #3: AWS で自動質問回答ボットを走らせる | Toshiki's Note</title>
<meta name="description" content="Toshiki's web notebook served via Vitepress!">
<link rel="preload stylesheet" href="/assets/style.41a6cfc6.css" as="style">
<script type="module" src="/assets/app.11c168a7.js"></script>
<link rel="preload" href="/assets/inter-roman-latin.2ed14f66.woff2" as="font" type="font/woff2" crossorigin="">
<link rel="modulepreload" href="/assets/chunks/framework.b7580407.js">
<link rel="modulepreload" href="/assets/chunks/theme.c3ca1c74.js">
<link rel="modulepreload" href="/assets/chunks/commonjsHelpers.725317a4.js">
<link rel="modulepreload" href="/assets/chunks/PageInfo.vue_vue_type_script_setup_true_lang.250b3e56.js">
<link rel="modulepreload" href="/assets/chunks/ask_many_output.0bb19110.js">
<link rel="modulepreload" href="/assets/development_aws_handson-qabot.md.dc65026a.lean.js">
<link rel="stylesheet" href="https://cdnjs.toshiki.dev/ajax/libs/KaTeX/0.16.0/katex.min.css">
<link rel="stylesheet" href="https://cdnjs.toshiki.dev/ajax/libs/font-awesome/6.3.0/css/all.min.css">
<link rel="icon" href="https://r2.toshiki.dev/cdn/toshiki-notebook-favicon/favicon.ico">
<meta name="author" content="Anda Toshiki">
<meta name="keywords" content="Toshiki, Anda Toshiki, andatoshiki, GitHub, GitHub action, Vitepress, Vite, Notebook, Knowledge base, Programming, Programming Notes, Academic, Personal, Notebook, Productivity, Journal, Note-taking, Markdown, Notepad, Organization, Tutorial">
<meta name="google-site-verification" content="lm7PNJiYSPEx1dMast1Xptc0Vk0cU06o-daZSsIgr2I">
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="theme-color" content="#3c8772">
<meta property="og:type" content="website">
<meta property="og:locale" content="en-US">
<meta property="og:title" content="Toshiki&#39;s Note">
<meta property="og:description" content="Toshiki&#39;s web notebook served via Vitepress!">
<meta property="og:site" content="https://note.toshiki.dev">
<meta property="og:site_name" content="Toshiki&#39;s Note">
<meta property="og:image" content="https://note.toshiki.dev/og-cover.png">
<script>function siteruntime(){window.setTimeout("siteruntime()",1e3),X=new Date("8/24/2021 10:28:00"),Y=new Date,T=Y.getTime()-X.getTime(),M=24*60*60*1e3,a=T/M,A=Math.floor(a),b=(a-A)*24,B=Math.floor(b),c=(b-B)*60,C=Math.floor((b-B)*60),D=Math.floor((c-C)*60),siteruntime_span.innerHTML="This site has been running for: "+A+" day(s) "+B+" hour(s) "+C+" minute(s) "+D+" second(s)"}siteruntime();</script>
<script async defer data-website-id="" src=""></script>
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
</head>
<body>
<div id="app"><div class="Layout" data-v-f6284a77><!--[--><!--]--><!--[--><span tabindex="-1" data-v-315fcc9b></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-315fcc9b> Skip to content </a><!--]--><!----><header class="VPNav" data-v-f6284a77 data-v-ff202323><div class="VPNavBar has-sidebar" data-v-ff202323 data-v-57f83237><div class="container" data-v-57f83237><div class="title" data-v-57f83237><div class="VPNavBarTitle has-sidebar" data-v-57f83237 data-v-87c32abd><a class="title" href="/" data-v-87c32abd><!--[--><!--]--><!--[--><img class="VPImage logo" src="/logos/logo.png" alt data-v-6ebf9bdf><!--]--><!--[-->Toshiki&#39;s Note<!--]--><!--[--><!--]--></a></div></div><div class="content" data-v-57f83237><div class="curtain" data-v-57f83237></div><div class="content-body" data-v-57f83237><!--[--><!--]--><div class="VPNavBarSearch search" data-v-57f83237><!--[--><!----><div id="docsearch"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg class="DocSearch-Search-Icon" width="20" height="20" viewBox="0 0 20 20" aria-label="search icon"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-57f83237 data-v-183ec936><span id="main-nav-aria-label" class="visually-hidden" data-v-183ec936>Main Navigation</span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/development/" tabindex="0" data-v-183ec936 data-v-416f44b0><!--[--><span data-v-416f44b0>Development</span><!--]--></a><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup active" data-v-183ec936 data-v-62bba1f9><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-62bba1f9><span class="text" data-v-62bba1f9><!----><span data-v-62bba1f9>Academic</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-62bba1f9><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-62bba1f9><div class="VPMenu" data-v-62bba1f9 data-v-17c3596a><div class="items" data-v-17c3596a><!--[--><!--[--><div class="VPMenuGroup" data-v-17c3596a data-v-b9d0e57b><p class="title" data-v-b9d0e57b>K-12</p><!--[--><!--[--><div class="VPMenuLink" data-v-b9d0e57b data-v-ec5470f2><a class="VPLink link" href="/academic/chemistry/index" data-v-ec5470f2><!--[-->Chemistry<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-b9d0e57b data-v-ec5470f2><a class="VPLink link" href="/discrete-math/index" data-v-ec5470f2><!--[-->Discrete Math.<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-b9d0e57b data-v-ec5470f2><a class="VPLink link" href="/academic/literature/index" data-v-ec5470f2><!--[-->Literature<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-b9d0e57b data-v-ec5470f2><a class="VPLink link" href="/academic/cis105/index" data-v-ec5470f2><!--[-->CIS105<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-17c3596a data-v-b9d0e57b><p class="title" data-v-b9d0e57b>Tools</p><!--[--><!--[--><div class="VPMenuLink" data-v-b9d0e57b data-v-ec5470f2><a class="VPLink link" href="/academic/physics/ipho-formulas-jpn/1" data-v-ec5470f2><!--[-->Formulas for IPhO JPN.<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuLink" data-v-17c3596a data-v-ec5470f2><span class="VPLink" data-v-ec5470f2><!--[--><!--]--></span></div><!--]--><!--[--><div class="VPMenuLink" data-v-17c3596a data-v-ec5470f2><span class="VPLink" data-v-ec5470f2><!--[--><!--]--></span></div><!--]--><!--[--><div class="VPMenuLink" data-v-17c3596a data-v-ec5470f2><span class="VPLink" data-v-ec5470f2><!--[--><!--]--></span></div><!--]--><!--[--><div class="VPMenuLink" data-v-17c3596a data-v-ec5470f2><span class="VPLink" data-v-ec5470f2><!--[--><!--]--></span></div><!--]--><!--[--><div class="VPMenuLink" data-v-17c3596a data-v-ec5470f2><span class="VPLink" data-v-ec5470f2><!--[--><!--]--></span></div><!--]--><!--[--><div class="VPMenuLink" data-v-17c3596a data-v-ec5470f2><span class="VPLink" data-v-ec5470f2><!--[--><!--]--></span></div><!--]--><!--[--><div class="VPMenuLink" data-v-17c3596a data-v-ec5470f2><span class="VPLink" data-v-ec5470f2><!--[--><!--]--></span></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-183ec936 data-v-62bba1f9><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-62bba1f9><span class="text" data-v-62bba1f9><!----><span data-v-62bba1f9>Application</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-62bba1f9><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-62bba1f9><div class="VPMenu" data-v-62bba1f9 data-v-17c3596a><div class="items" data-v-17c3596a><!--[--><!--[--><div class="VPMenuGroup" data-v-17c3596a data-v-b9d0e57b><p class="title" data-v-b9d0e57b>Personal projects</p><!--[--><!--[--><div class="VPMenuLink" data-v-b9d0e57b data-v-ec5470f2><a class="VPLink link" href="/application/markdown-it-katex/how-to-use" data-v-ec5470f2><!--[-->markdown-it-katex<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-b9d0e57b data-v-ec5470f2><a class="VPLink link" href="/application/vitepress-plugin-shiki-twoslash/index" data-v-ec5470f2><!--[-->vitepress-plugin-shiki-twoslash<!--]--></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-183ec936 data-v-62bba1f9><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-62bba1f9><span class="text" data-v-62bba1f9><!----><span data-v-62bba1f9>Save</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-62bba1f9><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-62bba1f9><div class="VPMenu" data-v-62bba1f9 data-v-17c3596a><div class="items" data-v-17c3596a><!--[--><!--[--><div class="VPMenuLink" data-v-17c3596a data-v-ec5470f2><a class="VPLink link" href="/save/reading/index" data-v-ec5470f2><!--[-->Reading<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-17c3596a data-v-ec5470f2><a class="VPLink link" href="/academic/vocabulary/index" data-v-ec5470f2><!--[-->Vocabulary<!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-57f83237 data-v-dc7cad42><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="toggle dark mode" aria-checked="false" data-v-dc7cad42 data-v-65b67168 data-v-56eb52d1><span class="check" data-v-56eb52d1><span class="icon" data-v-56eb52d1><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-65b67168><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-65b67168><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-57f83237 data-v-aaebde08 data-v-8a65be56><!--[--><a class="VPSocialLink no-icon" href="https://github.com/andatoshiki" aria-label="github" target="_blank" rel="noopener" data-v-8a65be56 data-v-1b61e2c7><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><a class="VPSocialLink no-icon" href="https://twitter.com/andatoshiki" aria-label="twitter" target="_blank" rel="noopener" data-v-8a65be56 data-v-1b61e2c7><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Twitter</title><path d="M21.543 7.104c.015.211.015.423.015.636 0 6.507-4.954 14.01-14.01 14.01v-.003A13.94 13.94 0 0 1 0 19.539a9.88 9.88 0 0 0 7.287-2.041 4.93 4.93 0 0 1-4.6-3.42 4.916 4.916 0 0 0 2.223-.084A4.926 4.926 0 0 1 .96 9.167v-.062a4.887 4.887 0 0 0 2.235.616A4.928 4.928 0 0 1 1.67 3.148 13.98 13.98 0 0 0 11.82 8.292a4.929 4.929 0 0 1 8.39-4.49 9.868 9.868 0 0 0 3.128-1.196 4.941 4.941 0 0 1-2.165 2.724A9.828 9.828 0 0 0 24 4.555a10.019 10.019 0 0 1-2.457 2.549z"/></svg></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-57f83237 data-v-e5c8c6ca data-v-62bba1f9><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-62bba1f9><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="icon" data-v-62bba1f9><circle cx="12" cy="12" r="2"></circle><circle cx="19" cy="12" r="2"></circle><circle cx="5" cy="12" r="2"></circle></svg></button><div class="menu" data-v-62bba1f9><div class="VPMenu" data-v-62bba1f9 data-v-17c3596a><!----><!--[--><!--[--><!----><div class="group" data-v-e5c8c6ca><div class="item appearance" data-v-e5c8c6ca><p class="label" data-v-e5c8c6ca>Appearance</p><div class="appearance-action" data-v-e5c8c6ca><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="toggle dark mode" aria-checked="false" data-v-e5c8c6ca data-v-65b67168 data-v-56eb52d1><span class="check" data-v-56eb52d1><span class="icon" data-v-56eb52d1><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-65b67168><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-65b67168><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div></div></div><div class="group" data-v-e5c8c6ca><div class="item social-links" data-v-e5c8c6ca><div class="VPSocialLinks social-links-list" data-v-e5c8c6ca data-v-8a65be56><!--[--><a class="VPSocialLink no-icon" href="https://github.com/andatoshiki" aria-label="github" target="_blank" rel="noopener" data-v-8a65be56 data-v-1b61e2c7><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><a class="VPSocialLink no-icon" href="https://twitter.com/andatoshiki" aria-label="twitter" target="_blank" rel="noopener" data-v-8a65be56 data-v-1b61e2c7><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Twitter</title><path d="M21.543 7.104c.015.211.015.423.015.636 0 6.507-4.954 14.01-14.01 14.01v-.003A13.94 13.94 0 0 1 0 19.539a9.88 9.88 0 0 0 7.287-2.041 4.93 4.93 0 0 1-4.6-3.42 4.916 4.916 0 0 0 2.223-.084A4.926 4.926 0 0 1 .96 9.167v-.062a4.887 4.887 0 0 0 2.235.616A4.928 4.928 0 0 1 1.67 3.148 13.98 13.98 0 0 0 11.82 8.292a4.929 4.929 0 0 1 8.39-4.49 9.868 9.868 0 0 0 3.128-1.196 4.941 4.941 0 0 1-2.165 2.724A9.828 9.828 0 0 0 24 4.555a10.019 10.019 0 0 1-2.457 2.549z"/></svg></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-57f83237 data-v-f865e4ad><span class="container" data-v-f865e4ad><span class="top" data-v-f865e4ad></span><span class="middle" data-v-f865e4ad></span><span class="bottom" data-v-f865e4ad></span></span></button></div></div></div></div><!----></header><div class="VPLocalNav reached-top" data-v-f6284a77 data-v-a41c4a1c><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-a41c4a1c><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="menu-icon" data-v-a41c4a1c><path d="M17,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,11,17,11z"></path><path d="M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z"></path><path d="M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z"></path><path d="M17,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,19,17,19z"></path></svg><span class="menu-text" data-v-a41c4a1c>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-a41c4a1c data-v-44ae7a43><button data-v-44ae7a43>Return to top</button><!----></div></div><aside class="VPSidebar" data-v-f6284a77 data-v-7ab77f34><div class="curtain" data-v-7ab77f34></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-7ab77f34><span class="visually-hidden" id="sidebar-aria-label" data-v-7ab77f34> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="group" data-v-7ab77f34><section class="VPSidebarItem level-0 collapsible" data-v-7ab77f34 data-v-1b9f5c6f><div class="item" role="button" tabindex="0" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><h2 class="text" data-v-1b9f5c6f>Notes & Issues</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-1b9f5c6f><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-1b9f5c6f><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-1b9f5c6f><!--[--><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/file-naming-convention" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>File Naming Convention</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/rclone-for-r2" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>RClone for R2</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/proxy4shell-terminal" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>Proxies Configuration for Shells & Terminal</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-7ab77f34><section class="VPSidebarItem level-0 collapsible has-active" data-v-7ab77f34 data-v-1b9f5c6f><div class="item" role="button" tabindex="0" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><h2 class="text" data-v-1b9f5c6f>コードで学ぶAWS入門</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-1b9f5c6f><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-1b9f5c6f><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-1b9f5c6f><!--[--><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/index" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>背景</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/main" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>はじめに!</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/cloud" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>クラウド概論</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/aws-get-started" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>AWS 入門</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/handson-ec2" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>Hands-on 1: 初めての EC2 インスタンスを起動する</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/scientific-computing" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>クラウドで行う科学計算・機械学習</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/handson-ec2" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>Hands-on 2: AWS でディープラーニングを実践</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/docker-system" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>Docker 入門</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/handson-qabot" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>Hands-on 3: AWS で自動質問回答ボットを走らせる</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/aws-batch" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>Hands-on 4: AWS Batch を使って機械学習のハイパーパラメータサーチを並列化する</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/webserver" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>Web サービスの作り方</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/serverless" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>Serverless architecture</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/handson-serverless" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>Hands-on 5: サーバーレス入門</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/handson-bashoutter" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>Hands-on 6: Bashoutter</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/closing" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>まとめ</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/appendix" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>ppendix: 環境構築</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1b9f5c6f data-v-1b9f5c6f><div class="item" data-v-1b9f5c6f><div class="indicator" data-v-1b9f5c6f></div><a class="VPLink link link" href="/development/aws/acknowledgement" data-v-1b9f5c6f><!--[--><p class="text" data-v-1b9f5c6f>謝辞</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-f6284a77 data-v-f3ed2c70><div class="VPDoc has-sidebar has-aside" data-v-f3ed2c70 data-v-39e6c32d><!--[--><!--]--><div class="container" data-v-39e6c32d><div class="aside" data-v-39e6c32d><div class="aside-curtain" data-v-39e6c32d></div><div class="aside-container" data-v-39e6c32d><div class="aside-content" data-v-39e6c32d><div class="VPDocAside" data-v-39e6c32d data-v-f5b3965e><!--[--><!--]--><!--[--><!--]--><div class="VPDocAsideOutline" role="navigation" data-v-f5b3965e data-v-99fa007f><div class="content" data-v-99fa007f><div class="outline-marker" data-v-99fa007f></div><div class="outline-title" role="heading" aria-level="2" data-v-99fa007f>TOC</div><nav aria-labelledby="doc-outline-aria-label" data-v-99fa007f><span class="visually-hidden" id="doc-outline-aria-label" data-v-99fa007f> Table of Contents for current page </span><ul class="root" data-v-99fa007f data-v-29e3fa2f><!--[--><!--]--></ul></nav></div></div><!--[--><!--]--><div class="spacer" data-v-f5b3965e></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--[--><!--[--><!--[--><div class="VPDocAsideSponsors"><div class="VPSponsors vp-sponsor aside"><!--[--><section class="vp-sponsor-section"><!----><div class="VPSponsorsGrid vp-sponsor-grid medium"><!--[--><div class="vp-sponsor-grid-item"><a class="vp-sponsor-grid-link" target="_blank" rel="sponsored noopener"><article class="vp-sponsor-grid-box"><h4 class="visually-hidden"></h4><img class="vp-sponsor-grid-image" src="https://jsd.toshiki.dev/gh/andatoshiki/toshiki-notebook@master/assets/logo/sponsor/telegram.png"></article></a></div><!--]--></div></section><!--]--></div></div><!--]--><!--]--><!--]--><!--]--></div></div></div></div><div class="content" data-v-39e6c32d><div class="content-container" data-v-39e6c32d><!--[--><!--]--><!----><main class="main" data-v-39e6c32d><div style="position:relative;" class="vp-doc _development_aws_handson-qabot" data-v-39e6c32d><div><h1 id="hands-on-3-aws-で自動質問回答ボットを走らせる" tabindex="-1">Hands-on #3: AWS で自動質問回答ボットを走らせる <a class="header-anchor" href="#hands-on-3-aws-で自動質問回答ボットを走らせる" aria-label="Permalink to &quot;Hands-on \#3: AWS で自動質問回答ボットを走らせる&quot;"></a></h1><div><section class="border-b-1 border-[var(--vp-c-divider)] w-full border-b-solid mt-[24px] pb-[12px] flex gap-[12px] mb-[12px] flex-wrap max-w-[85%]"><div class="flex gap-[4px] items-center"><svg style="display:inline-block;" viewBox="0 0 16 16" width="1.2em" height="1.2em"><path fill="currentColor" d="M8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16Zm.847-8.145a2.502 2.502 0 1 0-1.694 0C5.471 8.261 4 9.775 4 11c0 .395.145.995 1 .995h6c.855 0 1-.6 1-.995c0-1.224-1.47-2.74-3.153-3.145Z"></path></svg> Author:<span>Anda Toshiki</span></div><!----><div class="flex gap-[4px] items-center"><svg style="display:inline-block;" viewBox="0 0 15 15" width="1.2em" height="1.2em"><path fill="currentColor" fill-rule="evenodd" d="M1.903 7.297c0 3.044 2.207 5.118 4.686 5.547a.521.521 0 1 1-.178 1.027C3.5 13.367.861 10.913.861 7.297c0-1.537.699-2.745 1.515-3.663c.585-.658 1.254-1.193 1.792-1.602H2.532a.5.5 0 0 1 0-1h3a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-1 0V2.686l-.001.002c-.572.43-1.27.957-1.875 1.638c-.715.804-1.253 1.776-1.253 2.97Zm11.108.406c0-3.012-2.16-5.073-4.607-5.533a.521.521 0 1 1 .192-1.024c2.874.54 5.457 2.98 5.457 6.557c0 1.537-.699 2.744-1.515 3.663c-.585.658-1.254 1.193-1.792 1.602h1.636a.5.5 0 1 1 0 1h-3a.5.5 0 0 1-.5-.5v-3a.5.5 0 1 1 1 0v1.845h.002c.571-.432 1.27-.958 1.874-1.64c.715-.803 1.253-1.775 1.253-2.97Z" clip-rule="evenodd"></path></svg> Updated:<span>2 minutes ago</span></div><div class="flex gap-[4px] items-center"><svg style="display:inline-block;" viewBox="0 0 16 16" width="1.2em" height="1.2em"><path fill="currentColor" d="M9.293 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.707A1 1 0 0 0 13.707 4L10 .293A1 1 0 0 0 9.293 0zM9.5 3.5v-2l3 3h-2a1 1 0 0 1-1-1zM5.485 6.879l1.036 4.144l.997-3.655a.5.5 0 0 1 .964 0l.997 3.655l1.036-4.144a.5.5 0 0 1 .97.242l-1.5 6a.5.5 0 0 1-.967.01L8 9.402l-1.018 3.73a.5.5 0 0 1-.967-.01l-1.5-6a.5.5 0 1 1 .97-.242z"></path></svg> Words:<span>2.5k</span></div><div class="flex gap-[4px] items-center"><svg style="display:inline-block;" viewBox="0 0 20 20" width="1.2em" height="1.2em"><path fill="currentColor" d="M10 0a10 10 0 1 0 10 10A10 10 0 0 0 10 0zm2.5 14.5L9 11V4h2v6l3 3z"></path></svg> Reading:<span>11 min</span></div></section></div><p>ハンズオン第三回では, Docker と ECS を駆使した機械学習アプリケーションを実装しよう. 具体的には,深層学習による自然言語処理を行うことで,クライアントから与えられた文章題に対して回答を生成する,自動 Question &amp; Answering ボットを作成しよう. ECS を利用することで,ジョブの数によって動的にインスタンスの数を制御し,並列にタスクを実行するようなシステムを構築しよう.</p><p>通常の機械学習のワークフローでは,モデルの訓練 ⇒ 推論 (データへの適用) が基本的な流れである. しかしながら, GPU 搭載型の EC2 クラスターを使ったモデルの訓練はやや難易度が高いため,次章 ( (#sec_aws_batch)) で取り扱う. 本章は,クラウド上でのクラスターの構築・タスクの管理などの概念に慣れるため,よりシンプルな実装で実現できる Fargate クラスターを用いた推論計算の並列化を紹介する.</p><h2 id="fargate" tabindex="-1">Fargate <a class="header-anchor" href="#fargate" aria-label="Permalink to &quot;Fargate&quot;"></a></h2><p>ハンズオンに入っていく前に, <strong>Fargate</strong> という AWS の機能を知っておく必要がある (<a href="#fig:fargate_logo">figure_title</a>)</p><p><img src="/assets/Fargate.9aa64f1c.png" alt="Fargate のアイコン"></p><p>ECS の概要を示した (#ecs_overview) をもう一度見てみよう. この図で, ECS の管理下にあるクラスターが示されているが,このクラスターの中で計算を行う実体としては二つの選択肢がある. <strong>EC2 あるいは Fargate</strong> のいずれかである. EC2 を用いた場合は,先の章 ( (#sec_first_ec2), (#sec_jupyter_and_deep_learning)) で説明したような流れでインスタンスが起動し,計算が実行される. しかし, EC2 を用いた計算機クラスターの作成・管理は技術的な難易度がやや高いので,次章 ( (#sec_aws_batch)) で説明することにする.</p><p>Fargate とは, <strong>ECS での利用に特化</strong>して設計された,<strong>コンテナを使用した計算タスク</strong>を走らせるための仕組みである. 計算を走らせるという点では EC2 と役割は似ているが, Fargate は EC2 インスタンスのような物理的実体はもたない. 物理的実体をもたないというのは,たとえば SSH でログインすることは基本的に想定されていないし,なにかのソフトウェアをインストールしたりなどの概念も存在しない. Fargate ではすべての計算は Docker コンテナを介して行われる. すなわち, Fargate を利用するには,ユーザーは最初に所望の Docker イメージを指定しておき, Fargate は <code>docker run</code> のコマンドを使用することで計算タスクを実行する. Fargate を用いる利点は, Fargate を ECS のクラスターに指定すると,スケーリングなどの操作が簡単な設定・プログラムで構築できる点である.</p><p>Fargate では, EC2 と同様に CPU とメモリーのサイズを必要な分だけ指定できる. 執筆時点では, CPU は 0.25 - 4 コア, RAM は 0.5 - 30 GB の間で選択することができる (詳しくは <a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/AWS_Fargate.html" target="_blank" rel="noreferrer">公式ドキュメンテーション &quot;Amazon ECS on AWS Fargate&quot;</a> 参照) クラスターのスケーリングが容易な分, Fargate では EC2 ほど大きな CPU コア・ RAM 容量を単一インスタンスに付与することができず,また GPU を利用することもできない.</p><p>以上が Fargate の概要であったが,くどくど言葉で説明してもなかなかピンとこないだろう. ここからは実際に手を動かしながら, ECS と Fargate を使った並列タスクの処理の仕方を学んでいこう.</p><p>厳密には, ECS に付与するクラスターには EC2 と Fargate のハイブリッドを使用することも可能である.</p><h2 id="準備" tabindex="-1">準備 <a class="header-anchor" href="#準備" aria-label="Permalink to &quot;準備&quot;"></a></h2><p>ハンズオンのソースコードは GitHub の <a href="https://github.com/andatoshiki/toshiki-notebooktree/main/handson/qa-bot" target="_blank" rel="noreferrer">handson/qa-bot</a> にある.</p><p>本ハンズオンの実行には,第一回ハンズオンで説明した準備 ( (#handson_01_prep)) が整っていることを前提とする. また, Docker が自身のローカルマシンにインストール済みであることも必要である.</p><p>このハンズオンでは 1CPU/4GB RAM の Fargate インスタンスを使用する. 計算の実行には 0.025 $/hour のコストが発生することに注意.</p><h2 id="transformer-を用いた-question-answering-プログラム" tabindex="-1">Transformer を用いた question-answering プログラム <a class="header-anchor" href="#transformer-を用いた-question-answering-プログラム" aria-label="Permalink to &quot;Transformer を用いた question-answering プログラム&quot;"></a></h2><p>このハンズオンで開発する,自動質問回答システムをより具体的に定義しよう. 次のような文脈 (context) と質問 (question) が与えられた状況を想定する.</p><div class="language-txt vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">txt</span><pre class="shiki github-dark-dimmed vp-code-dark"><code><span class="line"><span style="color:#adbac7;">context: Albert Einstein (14 March 1879 18 April 1955) was a German-born theoretical physicist who developed the theory of relativity, one of the two pillars of modern physics (alongside quantum mechanics). His work is also known for its influence on the philosophy of science. He is best known to the general public for his massenergy equivalence formula E = mc2, which has been dubbed \&quot;the world&#39;s most famous equation\&quot;. He received the 1921 Nobel Prize in Physics \&quot;for his services to theoretical physics, and especially for his discovery of the law of the photoelectric effect\&quot;, a pivotal step in the development of quantum theory.</span></span>
<span class="line"><span style="color:#adbac7;"></span></span>
<span class="line"><span style="color:#adbac7;">question: In what year did Einstein win the Nobel prize?</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;">context: Albert Einstein (14 March 1879 18 April 1955) was a German-born theoretical physicist who developed the theory of relativity, one of the two pillars of modern physics (alongside quantum mechanics). His work is also known for its influence on the philosophy of science. He is best known to the general public for his massenergy equivalence formula E = mc2, which has been dubbed \&quot;the world&#39;s most famous equation\&quot;. He received the 1921 Nobel Prize in Physics \&quot;for his services to theoretical physics, and especially for his discovery of the law of the photoelectric effect\&quot;, a pivotal step in the development of quantum theory.</span></span>
<span class="line"><span style="color:#24292e;"></span></span>
<span class="line"><span style="color:#24292e;">question: In what year did Einstein win the Nobel prize?</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>今回作成する自動回答システムは,このような問題に対して, context に含まれる文字列から正解となる言葉を見つけ出すものとする. 上の問題では,次のような回答を返すべきである.</p><pre><code>answer: 1921
</code></pre><p>人間にとっては,このような文章を理解することは容易であるが,コンピュータにそれを解かせるのは難しいことは容易に想像ができるだろう. しかし,近年の深層学習を使った自然言語処理の進歩は著しく,上で示したような例題などは極めて高い正答率で回答できるモデルを作ることができる.</p><p>今回は, <a href="https://github.com/huggingface/transformers" target="_blank" rel="noreferrer">huggingface/transformers</a> で公開されている学習済みの言語モデルを利用することで,上で定義した問題を解く Q&amp;A ボットを作る. この Q&amp;A ボットは <a href="https://en.wikipedia.org/wiki/Transformer_(machine_learning_model)" target="_blank" rel="noreferrer">Transformer</a> とよばれるモデルを使った自然言語処理に支えられえている (<a href="#transformer_architecture">figure_title</a>) このプログラムを, Docker にパッケージしたものが <a href="https://hub.docker.com/repository/docker/tomomano/qabot" target="_blank" rel="noreferrer">著者の Docker Hub リポジトリ</a> に用意してある. クラウドの設計に入る前に,まずはこのプログラムを単体で動かしてみよう.</p><p><img src="/assets/transformer.e184dd01.png" alt="Transformer モデルアーキテクチャ (画像出典: Vaswani+ 2017)"></p><p>なお,今回は学習済みのモデルを用いているので,私達が行うのは与えられた入力をモデルに投入して予測を行う (推論) のみである. 推論の演算は, CPU だけでも十分高速に行うことができるので,コストの削減と,実装をシンプルにする目的で,このハンズオンでは GPU は利用しない. 一般的に, ニューラルネットは学習のほうが圧倒的に計算コストが大きく,そのような場合に GPU はより威力を発揮する.</p><p>次のコマンドで,今回使う Docker image を ローカルにダウンロード (pull) してこよう.</p><div class="language-sh vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki github-dark-dimmed vp-code-dark"><code><span class="line"><span style="color:#F69D50;">$</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">docker</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">pull</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">tomomano/qabot:latest</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">$</span><span style="color:#24292E;"> </span><span style="color:#032F62;">docker</span><span style="color:#24292E;"> </span><span style="color:#032F62;">pull</span><span style="color:#24292E;"> </span><span style="color:#032F62;">tomomano/qabot:latest</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>pull できたら,早速この Docker に質問を投げかけてみよう. まずは context と question をコマンドラインの変数として定義する.</p><div class="language-sh vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki github-dark-dimmed vp-code-dark"><code><span class="line"><span style="color:#F69D50;">$</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">context=&quot;Albert Einstein (14 March 1879 18 April 1955) was a German-born theoretical physicist who developed the theory of relativity, one of the two pillars of modern physics (alongside quantum mechanics). His work is also known for its influence on the philosophy of science. He is best known to the general public for his massenergy equivalence formula E = mc2, which has been dubbed the world&#39;s most famous equation. He received the 1921 Nobel Prize in Physics for his services to theoretical physics, and especially for his discovery of the law of the photoelectric effect, a pivotal step in the development of quantum theory.&quot;</span></span>
<span class="line"><span style="color:#F69D50;">$</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">question=&quot;In what year did Einstein win the Nobel prize ?&quot;</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">$</span><span style="color:#24292E;"> </span><span style="color:#032F62;">context=&quot;Albert Einstein (14 March 1879 18 April 1955) was a German-born theoretical physicist who developed the theory of relativity, one of the two pillars of modern physics (alongside quantum mechanics). His work is also known for its influence on the philosophy of science. He is best known to the general public for his massenergy equivalence formula E = mc2, which has been dubbed the world&#39;s most famous equation. He received the 1921 Nobel Prize in Physics for his services to theoretical physics, and especially for his discovery of the law of the photoelectric effect, a pivotal step in the development of quantum theory.&quot;</span></span>
<span class="line"><span style="color:#6F42C1;">$</span><span style="color:#24292E;"> </span><span style="color:#032F62;">question=&quot;In what year did Einstein win the Nobel prize ?&quot;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>そうしたら,次のコマンドによってコンテナを実行する.</p><div class="language-sh vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki github-dark-dimmed vp-code-dark"><code><span class="line"><span style="color:#F69D50;">$</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">docker</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">run</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">tomomano/qabot</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;${</span><span style="color:#ADBAC7;">context</span><span style="color:#96D0FF;">}&quot;</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;${</span><span style="color:#ADBAC7;">question</span><span style="color:#96D0FF;">}&quot;</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">foo</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">--no_save</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">$</span><span style="color:#24292E;"> </span><span style="color:#032F62;">docker</span><span style="color:#24292E;"> </span><span style="color:#032F62;">run</span><span style="color:#24292E;"> </span><span style="color:#032F62;">tomomano/qabot</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;${</span><span style="color:#24292E;">context</span><span style="color:#032F62;">}&quot;</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;${</span><span style="color:#24292E;">question</span><span style="color:#032F62;">}&quot;</span><span style="color:#24292E;"> </span><span style="color:#032F62;">foo</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">--no_save</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>今回用意した Docker image は,第一引数に context となる文字列を,第二引数に question に相当する文字列を受けつける. 第三引数,第四引数については,クラウドに展開するときの実装上の都合なので,いまは気にしなくてよい.</p><p>このコマンドを実行すると,次のような出力が得られるはずである.</p><div class="language-json vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki github-dark-dimmed vp-code-dark"><code><span class="line"><span style="color:#ADBAC7;">{ </span><span style="color:#8DDB8C;">&quot;score&quot;</span><span style="color:#ADBAC7;">: </span><span style="color:#6CB6FF;">0.9881729286683587</span><span style="color:#ADBAC7;">, </span><span style="color:#8DDB8C;">&quot;start&quot;</span><span style="color:#ADBAC7;">: </span><span style="color:#6CB6FF;">437</span><span style="color:#ADBAC7;">, </span><span style="color:#8DDB8C;">&quot;end&quot;</span><span style="color:#ADBAC7;">: </span><span style="color:#6CB6FF;">441</span><span style="color:#ADBAC7;">, </span><span style="color:#8DDB8C;">&quot;answer&quot;</span><span style="color:#ADBAC7;">: </span><span style="color:#96D0FF;">&quot;1921&quot;</span><span style="color:#ADBAC7;"> }</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292E;">{ </span><span style="color:#005CC5;">&quot;score&quot;</span><span style="color:#24292E;">: </span><span style="color:#005CC5;">0.9881729286683587</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">&quot;start&quot;</span><span style="color:#24292E;">: </span><span style="color:#005CC5;">437</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">&quot;end&quot;</span><span style="color:#24292E;">: </span><span style="color:#005CC5;">441</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">&quot;answer&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;1921&quot;</span><span style="color:#24292E;"> }</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>&quot;score&quot; は正解の自信度を表す数字で, [0,1] の範囲で与えられる. &quot;start&quot;, &quot;end&quot; は, context 中の何文字目が正解に相当するかを示しており, &quot;answer&quot; が正解と予測された文字列である. 1921 年という,正しい答えが返ってきていることに注目してほしい.</p><p>もう少し難しい質問を投げかけてみよう.</p><div class="language-sh vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki github-dark-dimmed vp-code-dark"><code><span class="line"><span style="color:#F69D50;">$</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">question=&quot;Why did Einstein win the Nobel prize ?&quot;</span></span>
<span class="line"><span style="color:#F69D50;">$</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">docker</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">run</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">tomomano/qabot</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;${</span><span style="color:#ADBAC7;">context</span><span style="color:#96D0FF;">}&quot;</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;${</span><span style="color:#ADBAC7;">question</span><span style="color:#96D0FF;">}&quot;</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">foo</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">--no_save</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">$</span><span style="color:#24292E;"> </span><span style="color:#032F62;">question=&quot;Why did Einstein win the Nobel prize ?&quot;</span></span>
<span class="line"><span style="color:#6F42C1;">$</span><span style="color:#24292E;"> </span><span style="color:#032F62;">docker</span><span style="color:#24292E;"> </span><span style="color:#032F62;">run</span><span style="color:#24292E;"> </span><span style="color:#032F62;">tomomano/qabot</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;${</span><span style="color:#24292E;">context</span><span style="color:#032F62;">}&quot;</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;${</span><span style="color:#24292E;">question</span><span style="color:#032F62;">}&quot;</span><span style="color:#24292E;"> </span><span style="color:#032F62;">foo</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">--no_save</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>出力:</p><div class="language-json vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki github-dark-dimmed vp-code-dark"><code><span class="line"><span style="color:#ADBAC7;">{</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#8DDB8C;">&quot;score&quot;</span><span style="color:#ADBAC7;">: </span><span style="color:#6CB6FF;">0.5235594527494207</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#8DDB8C;">&quot;start&quot;</span><span style="color:#ADBAC7;">: </span><span style="color:#6CB6FF;">470</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#8DDB8C;">&quot;end&quot;</span><span style="color:#ADBAC7;">: </span><span style="color:#6CB6FF;">506</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#8DDB8C;">&quot;answer&quot;</span><span style="color:#ADBAC7;">: </span><span style="color:#96D0FF;">&quot;his services to theoretical physics,&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292E;">{</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">&quot;score&quot;</span><span style="color:#24292E;">: </span><span style="color:#005CC5;">0.5235594527494207</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">&quot;start&quot;</span><span style="color:#24292E;">: </span><span style="color:#005CC5;">470</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">&quot;end&quot;</span><span style="color:#24292E;">: </span><span style="color:#005CC5;">506</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">&quot;answer&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;his services to theoretical physics,&quot;</span></span>
<span class="line"><span style="color:#24292E;">}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>今度は, score が 0.52 と,少し自信がないようだが,それでも正しい答えにたどりつけていることがわかる.</p><p>このように, 深層学習に支えられた言語モデルを用いることで,実用にも役に立ちそうな Q&amp;A ボットを実現できていることがわかる. 以降では,このプログラムをクラウドに展開することで,大量の質問に自動で対応できるようなシステムを設計していく.</p><p>今回使用する Question &amp; Answering システムには, DistilBERT という Transformer を基にした言語モデルが用いられている. 興味のある読者は, <a href="https://arxiv.org/abs/1910.01108" target="_blank" rel="noreferrer">原著論文</a> を参照してもらいたい. また, huggingface/transformers による DistilBert の実装のドキュメンテーションは <a href="https://huggingface.co/transformers/model_doc/distilbert.html" target="_blank" rel="noreferrer">公式ドキュメンテーション</a> を参照のこと.</p><p>今回提供する Q-A ボットの Docker のソースコードは <a href="https://github.com/andatoshiki/toshiki-notebookblob/main/handson/qa-bot/docker/Dockerfile" target="_blank" rel="noreferrer">https://github.com/andatoshiki/toshiki-notebookblob/main/handson/qa-bot/docker/Dockerfile</a> にある.</p><h2 id="アプリケーションの説明" tabindex="-1">アプリケーションの説明 <a class="header-anchor" href="#アプリケーションの説明" aria-label="Permalink to &quot;アプリケーションの説明&quot;"></a></h2><p>このハンズオンで作成するアプリケーションの概要を <a href="#handson_03_architecture">figure_title</a> に示す.</p><p><img src="/assets/handson-03-architecture.f1ebbd6e.png" alt="アプリケーションのアーキテクチャ"></p><p>簡単にまとめると,以下のような設計である.</p><ul><li><p>クライアントは,質問を AWS 上のアプリケーションに送信する.</p></li><li><p>質問のタスクは ECS によって処理される.</p></li><li><p>ECS は, Docker Hub から,イメージをダウンロードする.</p></li><li><p>次にECS はクラスター内に新たな Fargate インスタンスを立ち上げ,ダウンロードされた Docker イメージをこの新規インスタンスに配置する.</p><ul><li>このとき,一つの質問に対し一つの Fargate インスタンスを立ち上げることで,複数の質問を並列的に処理できるようにする.</li></ul></li><li><p>ジョブが実行される.</p></li><li><p>ジョブの実行結果 (質問への回答) は, データベース (DynamoDB) に書き込まれる.</p></li><li><p>最後に,クライアントは DynamoDB から質問への回答を読み取る.</p></li></ul><p>それでは,プログラムのソースコードを見てみよう (<a href="https://github.com/andatoshiki/toshiki-notebookblob/main/handson/qa-bot/app.py" target="_blank" rel="noreferrer">handson/qa-bot/app.py</a>)</p><div class="language-python vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">python</span><pre class="shiki github-dark-dimmed vp-code-dark"><code><span class="line"><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">EcsClusterQaBot</span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">core</span><span style="color:#ADBAC7;">.</span><span style="color:#6CB6FF;">Stack</span><span style="color:#ADBAC7;">):</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">def</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">__init__</span><span style="color:#ADBAC7;">(self, scope: core.App, name: </span><span style="color:#6CB6FF;">str</span><span style="color:#ADBAC7;">, </span><span style="color:#F47067;">**</span><span style="color:#ADBAC7;">kwargs) -&gt; </span><span style="color:#6CB6FF;">None</span><span style="color:#ADBAC7;">:</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">super</span><span style="color:#ADBAC7;">().</span><span style="color:#6CB6FF;">__init__</span><span style="color:#ADBAC7;">(scope, name, </span><span style="color:#F47067;">**</span><span style="color:#ADBAC7;">kwargs)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">#</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;"># dynamoDB table to store questions and answers</span></span>
<span class="line"><span style="color:#ADBAC7;"> table </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> dynamodb.Table(</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">self</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;EcsClusterQaBot-Table&quot;</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">partition_key</span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;">dynamodb.Attribute(</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">name</span><span style="color:#F47067;">=</span><span style="color:#96D0FF;">&quot;item_id&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#F69D50;">type</span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;">dynamodb.AttributeType.</span><span style="color:#6CB6FF;">STRING</span></span>
<span class="line"><span style="color:#ADBAC7;"> ),</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">billing_mode</span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;">dynamodb.BillingMode.</span><span style="color:#6CB6FF;">PAY_PER_REQUEST</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">removal_policy</span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;">core.RemovalPolicy.</span><span style="color:#6CB6FF;">DESTROY</span></span>
<span class="line"><span style="color:#ADBAC7;"> )</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">#</span></span>
<span class="line"><span style="color:#ADBAC7;"> vpc </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> ec2.Vpc(</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">self</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;EcsClusterQaBot-Vpc&quot;</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">max_azs</span><span style="color:#F47067;">=</span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;"> )</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">#</span></span>
<span class="line"><span style="color:#ADBAC7;"> cluster </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> ecs.Cluster(</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">self</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;EcsClusterQaBot-Cluster&quot;</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">vpc</span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;">vpc,</span></span>
<span class="line"><span style="color:#ADBAC7;"> )</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">#</span></span>
<span class="line"><span style="color:#ADBAC7;"> taskdef </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> ecs.FargateTaskDefinition(</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">self</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;EcsClusterQaBot-TaskDef&quot;</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">cpu</span><span style="color:#F47067;">=</span><span style="color:#6CB6FF;">1024</span><span style="color:#ADBAC7;">, </span><span style="color:#768390;"># 1 CPU</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">memory_limit_mib</span><span style="color:#F47067;">=</span><span style="color:#6CB6FF;">4096</span><span style="color:#ADBAC7;">, </span><span style="color:#768390;"># 4GB RAM</span></span>
<span class="line"><span style="color:#ADBAC7;"> )</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;"># grant permissions</span></span>
<span class="line"><span style="color:#ADBAC7;"> table.grant_read_write_data(taskdef.task_role)</span></span>
<span class="line"><span style="color:#ADBAC7;"> taskdef.add_to_task_role_policy(</span></span>
<span class="line"><span style="color:#ADBAC7;"> iam.PolicyStatement(</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">effect</span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;">iam.Effect.</span><span style="color:#6CB6FF;">ALLOW</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">resources</span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;">[</span><span style="color:#96D0FF;">&quot;*&quot;</span><span style="color:#ADBAC7;">],</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">actions</span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;">[</span><span style="color:#96D0FF;">&quot;ssm:GetParameter&quot;</span><span style="color:#ADBAC7;">]</span></span>
<span class="line"><span style="color:#ADBAC7;"> )</span></span>
<span class="line"><span style="color:#ADBAC7;"> )</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">#</span></span>
<span class="line"><span style="color:#ADBAC7;"> container </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> taskdef.add_container(</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;EcsClusterQaBot-Container&quot;</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">image</span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;">ecs.ContainerImage.from_registry(</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;tomomano/qabot:latest&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> ),</span></span>
<span class="line"><span style="color:#ADBAC7;"> )</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">EcsClusterQaBot</span><span style="color:#24292E;">(</span><span style="color:#6F42C1;">core</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">Stack</span><span style="color:#24292E;">):</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#D73A49;">def</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">__init__</span><span style="color:#24292E;">(self, scope: core.App, name: </span><span style="color:#005CC5;">str</span><span style="color:#24292E;">, </span><span style="color:#D73A49;">**</span><span style="color:#24292E;">kwargs) -&gt; </span><span style="color:#005CC5;">None</span><span style="color:#24292E;">:</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">super</span><span style="color:#24292E;">().</span><span style="color:#005CC5;">__init__</span><span style="color:#24292E;">(scope, name, </span><span style="color:#D73A49;">**</span><span style="color:#24292E;">kwargs)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6A737D;">#</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6A737D;"># dynamoDB table to store questions and answers</span></span>
<span class="line"><span style="color:#24292E;"> table </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> dynamodb.Table(</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">self</span><span style="color:#24292E;">, </span><span style="color:#032F62;">&quot;EcsClusterQaBot-Table&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#E36209;">partition_key</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">dynamodb.Attribute(</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#E36209;">name</span><span style="color:#D73A49;">=</span><span style="color:#032F62;">&quot;item_id&quot;</span><span style="color:#24292E;">, </span><span style="color:#E36209;">type</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">dynamodb.AttributeType.</span><span style="color:#005CC5;">STRING</span></span>
<span class="line"><span style="color:#24292E;"> ),</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#E36209;">billing_mode</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">dynamodb.BillingMode.</span><span style="color:#005CC5;">PAY_PER_REQUEST</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#E36209;">removal_policy</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">core.RemovalPolicy.</span><span style="color:#005CC5;">DESTROY</span></span>
<span class="line"><span style="color:#24292E;"> )</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6A737D;">#</span></span>
<span class="line"><span style="color:#24292E;"> vpc </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> ec2.Vpc(</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">self</span><span style="color:#24292E;">, </span><span style="color:#032F62;">&quot;EcsClusterQaBot-Vpc&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#E36209;">max_azs</span><span style="color:#D73A49;">=</span><span style="color:#005CC5;">1</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;"> )</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6A737D;">#</span></span>
<span class="line"><span style="color:#24292E;"> cluster </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> ecs.Cluster(</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">self</span><span style="color:#24292E;">, </span><span style="color:#032F62;">&quot;EcsClusterQaBot-Cluster&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#E36209;">vpc</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">vpc,</span></span>
<span class="line"><span style="color:#24292E;"> )</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6A737D;">#</span></span>
<span class="line"><span style="color:#24292E;"> taskdef </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> ecs.FargateTaskDefinition(</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">self</span><span style="color:#24292E;">, </span><span style="color:#032F62;">&quot;EcsClusterQaBot-TaskDef&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#E36209;">cpu</span><span style="color:#D73A49;">=</span><span style="color:#005CC5;">1024</span><span style="color:#24292E;">, </span><span style="color:#6A737D;"># 1 CPU</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#E36209;">memory_limit_mib</span><span style="color:#D73A49;">=</span><span style="color:#005CC5;">4096</span><span style="color:#24292E;">, </span><span style="color:#6A737D;"># 4GB RAM</span></span>
<span class="line"><span style="color:#24292E;"> )</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6A737D;"># grant permissions</span></span>
<span class="line"><span style="color:#24292E;"> table.grant_read_write_data(taskdef.task_role)</span></span>
<span class="line"><span style="color:#24292E;"> taskdef.add_to_task_role_policy(</span></span>
<span class="line"><span style="color:#24292E;"> iam.PolicyStatement(</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#E36209;">effect</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">iam.Effect.</span><span style="color:#005CC5;">ALLOW</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#E36209;">resources</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">[</span><span style="color:#032F62;">&quot;*&quot;</span><span style="color:#24292E;">],</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#E36209;">actions</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">[</span><span style="color:#032F62;">&quot;ssm:GetParameter&quot;</span><span style="color:#24292E;">]</span></span>
<span class="line"><span style="color:#24292E;"> )</span></span>
<span class="line"><span style="color:#24292E;"> )</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#6A737D;">#</span></span>
<span class="line"><span style="color:#24292E;"> container </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> taskdef.add_container(</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;EcsClusterQaBot-Container&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#E36209;">image</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">ecs.ContainerImage.from_registry(</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;tomomano/qabot:latest&quot;</span></span>
<span class="line"><span style="color:#24292E;"> ),</span></span>
<span class="line"><span style="color:#24292E;"> )</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br></div></div><ul><li><p>ここでは,回答の結果を書き込むためのデータベースを用意している. DynamoDB については,サーバーレスアーキテクチャの章で扱うので,今は気にしなくてよい.</p></li><li><p>ここでは,ハンズオン #1, #2 で行ったのと同様に, VPC を定義している.</p></li><li><p>ここで, ECS のクラスター (cluster) を定義している. クラスターとは,仮想サーバーのプールのことであり,クラスターの中に複数の仮想インスタンスを配置する.</p></li><li><p>ここで,実行するタスクを定義している (task definition)</p></li><li><p>ここで, タスクの実行で使用する Docker イメージを定義している.</p></li></ul><h3 id="ecs-と-fargate" tabindex="-1">ECS と Fargate <a class="header-anchor" href="#ecs-と-fargate" aria-label="Permalink to &quot;ECS と Fargate&quot;"></a></h3><p>ECS と Fargate の部分について,コードをくわしく見てみよう.</p><div class="language-python vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">python</span><pre class="shiki github-dark-dimmed vp-code-dark"><code><span class="line"><span style="color:#ADBAC7;">cluster </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> ecs.Cluster(</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">self</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;EcsClusterQaBot-Cluster&quot;</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">vpc</span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;">vpc,</span></span>
<span class="line"><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;">taskdef </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> ecs.FargateTaskDefinition(</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">self</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;EcsClusterQaBot-TaskDef&quot;</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">cpu</span><span style="color:#F47067;">=</span><span style="color:#6CB6FF;">1024</span><span style="color:#ADBAC7;">, </span><span style="color:#768390;"># 1 CPU</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">memory_limit_mib</span><span style="color:#F47067;">=</span><span style="color:#6CB6FF;">4096</span><span style="color:#ADBAC7;">, </span><span style="color:#768390;"># 4GB RAM</span></span>
<span class="line"><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;">container </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> taskdef.add_container(</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;EcsClusterQaBot-Container&quot;</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">image</span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;">ecs.ContainerImage.from_registry(</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;tomomano/qabot:latest&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> ),</span></span>
<span class="line"><span style="color:#ADBAC7;">)</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292E;">cluster </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> ecs.Cluster(</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">self</span><span style="color:#24292E;">, </span><span style="color:#032F62;">&quot;EcsClusterQaBot-Cluster&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#E36209;">vpc</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">vpc,</span></span>
<span class="line"><span style="color:#24292E;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;">taskdef </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> ecs.FargateTaskDefinition(</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#005CC5;">self</span><span style="color:#24292E;">, </span><span style="color:#032F62;">&quot;EcsClusterQaBot-TaskDef&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#E36209;">cpu</span><span style="color:#D73A49;">=</span><span style="color:#005CC5;">1024</span><span style="color:#24292E;">, </span><span style="color:#6A737D;"># 1 CPU</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#E36209;">memory_limit_mib</span><span style="color:#D73A49;">=</span><span style="color:#005CC5;">4096</span><span style="color:#24292E;">, </span><span style="color:#6A737D;"># 4GB RAM</span></span>
<span class="line"><span style="color:#24292E;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;">container </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> taskdef.add_container(</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;EcsClusterQaBot-Container&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#E36209;">image</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">ecs.ContainerImage.from_registry(</span></span>
<span class="line"><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;tomomano/qabot:latest&quot;</span></span>
<span class="line"><span style="color:#24292E;"> ),</span></span>
<span class="line"><span style="color:#24292E;">)</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><p><code>cluster =</code> の箇所で,空の ECS クラスターを定義している.</p><p>次に, <code>taskdef=ecs.FargateTaskDefinition</code> の箇所で, Fargate インスタンスを使ったタスクを定義しており,とくにここでは 1 CPU, 4GB RAM というマシンスペックを指定している. また,このようにして定義されたタスクは,デフォルトで 1 タスクにつき 1 インスタンスが使用される.</p><p>最後に, <code>container =</code> の箇所で,タスクの実行で使用する Docker image を定義している. ここでは, Docker Hub に置いてある image をダウンロードしてくるよう指定している.</p><p>このようにわずか数行のコードであるが,これだけで前述したような,タスクのスケジューリングなどが自動で実行される.</p><p>このコードで <code>cpu=1024</code> と指定されているのに注目してほしい. これは CPU ユニットと呼ばれる数で, 以下の換算表に従って仮想 CPU (virtual CPU; vCPU) が割り当てられる. 1024 が 1 CPU に相当する. 0.25 や 0.5 vCPU などの数字は,それぞれ実効的に 1/4, 1/2 の CPU 時間が割り当てられることを意味する. また, CPU ユニットによって使用できるメモリー量も変わってくる. たとえば, 1024 CPU ユニットを選択した場合は, 2 から 8 GB の範囲でのみメモリー量を指定することができる. 最新の情報は <a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/AWS_Fargate.html" target="_blank" rel="noreferrer">公式ドキュメンテーション &quot;Amazon ECS on AWS Fargate&quot;</a> を参照のこと.</p><table><caption>CPU ユニットと 指定可能なメモリー量の換算表</caption><colgroup><col style="width:50%;"><col style="width:50%;"></colgroup><tbody><tr class="odd"><td><p>CPU ユニット</p></td><td><p>メモリーの値</p></td></tr><tr class="even"><td><p>256 (.25 vCPU)</p></td><td><p>0.5 GB, 1 GB, 2 GB</p></td></tr><tr class="odd"><td><p>512 (.5 vCPU)</p></td><td><p>1 GB, 2 GB, 3 GB, 4 GB</p></td></tr><tr class="even"><td><p>1024 (1 vCPU)</p></td><td><p>2 GB, 3 GB, 4 GB, 5 GB, 6 GB, 7 GB, 8 GB</p></td></tr><tr class="odd"><td><p>2048 (2 vCPU)</p></td><td><p>Between 4 GB and 16 GB in 1-GB increments</p></td></tr><tr class="even"><td><p>4096 (4 vCPU)</p></td><td><p>Between 8 GB and 30 GB in 1-GB increments</p></td></tr></tbody></table><h2 id="スタックのデプロイ" tabindex="-1">スタックのデプロイ <a class="header-anchor" href="#スタックのデプロイ" aria-label="Permalink to &quot;スタックのデプロイ&quot;"></a></h2><p>スタックの中身が理解できたところで,早速スタックをデプロイしてみよう.</p><p>デプロイの手順は,これまでのハンズオンとほとんど共通である. SSH によるログインの必要がないので,むしろ単純なくらいである. ここでは,コマンドのみ列挙する (<code>#</code> で始まる行はコメントである) それぞれの意味を忘れてしまった場合は,ハンズオン 1, 2 に戻って復習していただきたい. シークレットキーの設定も忘れずに ( (#aws_cli_install))</p><div class="language-sh vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki github-dark-dimmed vp-code-dark"><code><span class="line"><span style="color:#768390;"># プロジェクトのディレクトリに移動</span></span>
<span class="line"><span style="color:#F69D50;">$</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">cd</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">handson/qa-bot</span></span>
<span class="line"></span>
<span class="line"><span style="color:#768390;"># venv を作成し,依存ライブラリのインストールを行う</span></span>
<span class="line"><span style="color:#F69D50;">$</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">python3</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">-m</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">venv</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">.env</span></span>
<span class="line"><span style="color:#F69D50;">$</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">source</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">.env/bin/activate</span></span>
<span class="line"><span style="color:#F69D50;">$</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">pip</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">install</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">-r</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">requirements.txt</span></span>
<span class="line"></span>
<span class="line"><span style="color:#768390;"># デプロイを実行</span></span>
<span class="line"><span style="color:#F69D50;">$</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">cdk</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">deploy</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;"># プロジェクトのディレクトリに移動</span></span>
<span class="line"><span style="color:#6F42C1;">$</span><span style="color:#24292E;"> </span><span style="color:#032F62;">cd</span><span style="color:#24292E;"> </span><span style="color:#032F62;">handson/qa-bot</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D;"># venv を作成し,依存ライブラリのインストールを行う</span></span>
<span class="line"><span style="color:#6F42C1;">$</span><span style="color:#24292E;"> </span><span style="color:#032F62;">python3</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">-m</span><span style="color:#24292E;"> </span><span style="color:#032F62;">venv</span><span style="color:#24292E;"> </span><span style="color:#032F62;">.env</span></span>
<span class="line"><span style="color:#6F42C1;">$</span><span style="color:#24292E;"> </span><span style="color:#032F62;">source</span><span style="color:#24292E;"> </span><span style="color:#032F62;">.env/bin/activate</span></span>
<span class="line"><span style="color:#6F42C1;">$</span><span style="color:#24292E;"> </span><span style="color:#032F62;">pip</span><span style="color:#24292E;"> </span><span style="color:#032F62;">install</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">-r</span><span style="color:#24292E;"> </span><span style="color:#032F62;">requirements.txt</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D;"># デプロイを実行</span></span>
<span class="line"><span style="color:#6F42C1;">$</span><span style="color:#24292E;"> </span><span style="color:#032F62;">cdk</span><span style="color:#24292E;"> </span><span style="color:#032F62;">deploy</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>デプロイのコマンドが無事に実行されれば, <a href="#handson_03_cdk_output">figure_title</a> のような出力が得られるはずである.</p><p><img src="/assets/cdk_output.9daf7c9d.png" alt="CDKデプロイ実行後の出力"></p><p>AWS コンソールにログインして,デプロイされたスタックの中身を確認してみよう. コンソールからECS のページに行くと <a href="#handson_03_ecs_console">figure_title</a> のような画面が表示されるはずである. <code>EcsClusterQaBot-XXXX</code> という名前ついたクラスターを見つけよう.</p><p>Cluster というのが,先ほど説明したとおり,複数の仮想インスタンスを束ねる一つの単位である. <a href="#handson_03_ecs_console">figure_title</a> で, FARGATE という文字の下に <code>0 Running tasks</code>, <code>0 Pending tasks</code> と表示されていることを確認しよう. この時点では一つもタスクが走っていないので,数字はすべて 0 になっている.</p><p><img src="/assets/ecs_console.b76b2a4f.png" alt="ECS コンソール画面"></p><p>続いて,この画面の左のメニューバーから <code>Task Definitions</code> という項目を見つけ,クリックしよう. 移動した先のページで <code>EcsClusterQaBotEcsClusterQaBotTaskDefXXXX</code> という項目が見つかるので,開く. 開いた先のページをスクロールすると <a href="#handson_03_ecs_task_definition">figure_title</a> に示したような情報が見つかるだろう. 使用する CPU ・メモリーの量や, Docker container の実行に関する設定などが,この Task Definition の画面から確認することができる.</p><p><img src="/assets/ecs_task_definition.4f9a65fb.png" alt="Task definition の確認"></p><h2 id="タスクの実行" tabindex="-1">タスクの実行 <a class="header-anchor" href="#タスクの実行" aria-label="Permalink to &quot;タスクの実行&quot;"></a></h2><p>それでは,質問をデプロイしたクラウドに提出してみよう.</p><p>ECS にタスクを投入するのはやや複雑なので,タスクの投入を簡単にするプログラム (<code>run_task.py</code>) を用意した (<a href="https://github.com/andatoshiki/toshiki-notebookblob/main/handson/qa-bot/run_task.py" target="_blank" rel="noreferrer">handson/qa-bot/run_task.py</a>)</p><p>次のようなコマンドでECS クラスターに新しい質問を投入することができる.</p><div class="language-sh vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki github-dark-dimmed vp-code-dark"><code><span class="line"><span style="color:#F69D50;">$</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">python</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">run_task.py</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">ask</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;A giant peach was flowing in the river. She picked it up and brought it home. Later, a healthy baby was born from the peach. She named the baby Momotaro.&quot;</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;What is the name of the baby?&quot;</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">$</span><span style="color:#24292E;"> </span><span style="color:#032F62;">python</span><span style="color:#24292E;"> </span><span style="color:#032F62;">run_task.py</span><span style="color:#24292E;"> </span><span style="color:#032F62;">ask</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;A giant peach was flowing in the river. She picked it up and brought it home. Later, a healthy baby was born from the peach. She named the baby Momotaro.&quot;</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;What is the name of the baby?&quot;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p><code>run_task.py</code> を実行するには, コマンドラインで AWS の認証情報が設定されていることが前提である.</p><p>&quot;ask&quot; の引数に続き,文脈 (context) と質問 (question) を引数として渡している.</p><p>このコマンドを実行すると, &quot;Waiting for the task to finish…&quot; と出力が表示され,回答を得るまでしばらく待たされる. この間, AWS では ECS がタスクを受理し,新しい Fargate のインスタンスを起動し, Docker イメージをそのインスタンスに配置する,という一連の処理がなされている. AWS コンソールから,この一連の様子をモニタリングしてみよう.</p><p>先ほどの ECS コンソール画面にもどり,クラスターの名前をクリックすることで,クラスターの詳細画面を開く. 次に, &quot;Tasks&quot; という名前のタブがあるので,それを開く (<a href="#ecs_task_monitoring">figure_title</a>) すると,実行中のタスクの一覧が表示されるだろう.</p><p><img src="/assets/ecs_task_monitoring.11682009.png" alt="ECS のタスクの実行状況をモニタリング"></p><p><a href="#ecs_task_monitoring">figure_title</a> で見て取れるように, &quot;Last status = Pending&quot; となっていることから,この時点では,タスクを実行する準備をしている段階である,ということがわかる. Fargate のインスタンスを起動し, Docker image を配置するまでおよそ 1-2 分の時間がかかる.</p><p>しばらく待つうちに, Status が &quot;RUNNING&quot; に遷移し,計算が始まる. 計算が終わると, Status は &quot;STOPPED&quot; に遷移し, ECS によって Fargate インスタンスは自動的にシャットダウンされる.</p><p><a href="#ecs_task_monitoring">figure_title</a> の画面から, &quot;Task&quot; の列にあるタスク ID クリックすることで,タスクの詳細画面を開いてみよう (<a href="#ecs_task_detail">figure_title</a>) &quot;Last status&quot;, &quot;Platform version&quot; など,タスクの情報が表示されている. また, &quot;Logs&quot; のタブを開くことで,コンテナの吐き出した実行ログを閲覧することができる.</p><p><img src="/assets/ecs_task_detail.ec5c1d9f.png" alt="質問タスクの実行結果"></p><p>さて, <code>run_task.py</code> を実行したコマンドラインに戻ってきてみると, <a href="#ask_question_output">figure_title</a> のような出力が得られているはずである. &quot;Momotaro&quot; という正しい回答が返ってきている!</p><p><img src="/assets/ask_question_output.7fe69f85.png" alt="質問タスクの実行結果"></p><h2 id="タスクの同時実行" tabindex="-1">タスクの同時実行 <a class="header-anchor" href="#タスクの同時実行" aria-label="Permalink to &quot;タスクの同時実行&quot;"></a></h2><p>さて,先ほどはたった一つの質問を投入したわけだが,今回設計したアプリケーションは, ECS と Fargate を使うことで同時にたくさんの質問を処理することができる. 実際に,たくさんの質問を一度に投入してみよう. <code>run_task.py</code><code>ask_many</code> というオプションを付けることで,複数の質問を一度に送信できる. 質問の内容は <a href="https://github.com/andatoshiki/toshiki-notebookblob/main/handson/qa-bot/problems.json" target="_blank" rel="noreferrer">handson/qa-bot/problems.json</a> に定義されている.</p><p>次のようなコマンドを実行しよう.</p><div class="language-sh vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki github-dark-dimmed vp-code-dark"><code><span class="line"><span style="color:#F69D50;">$</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">python</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">run_task.py</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">ask_many</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">$</span><span style="color:#24292E;"> </span><span style="color:#032F62;">python</span><span style="color:#24292E;"> </span><span style="color:#032F62;">run_task.py</span><span style="color:#24292E;"> </span><span style="color:#032F62;">ask_many</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>このコマンドを実行した後で,先ほどの ECS コンソールに行き,タスクの一覧を見てみよう (<a href="#ecs_many_tasks">figure_title</a>) 複数の Fargate インスタンスが起動され,タスクが並列に実行されているのがわかる.</p><p><img src="/assets/ecs_many_tasks.ad809e16.png" alt="複数の質問タスクを同時に投入する"></p><p>すべてのタスクのステータスが &quot;STOPPED&quot; になったことを確認した上で,質問への回答を取得しよう. それには,次のコマンドを実行する.</p><div class="language-sh vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki github-dark-dimmed vp-code-dark"><code><span class="line"><span style="color:#F69D50;">$</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">python</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">run_task.py</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">list_answers</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">$</span><span style="color:#24292E;"> </span><span style="color:#032F62;">python</span><span style="color:#24292E;"> </span><span style="color:#032F62;">run_task.py</span><span style="color:#24292E;"> </span><span style="color:#032F62;">list_answers</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>結果として, <a href="#ask_many_output">figure_title</a> のような出力が得られるだろう. 複雑な文章問題に対し,高い正答率で回答できていることがわかるだろう.</p><p><img src="/assets/ask_many_output.ee31d9f8.png" alt=" の実行結果"></p><p>おめでとう! ここまでついてこれた読者はとても初歩的ながらも,深層学習による言語モデルを使って自動で質問への回答を生成するシステムを創り上げることができた! それも,数百の質問にも同時に対応できるような,とても高いスケーラビリティーをもったシステムである! 今回は GUI (Graphical User Interface) を用意することはしなかったが,このシステムに簡単な GUI を追加すればなかなか立派なウェブサービスとして運用できるだろう.</p><p><code>run_task.py</code> で質問を投入し続けると,回答を記録しているデータベースにどんどんエントリーが溜まっていく. これらのエントリーをすべて消去するには,次のコマンドを使う.</p><div class="language-sh vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki github-dark-dimmed vp-code-dark"><code><span class="line"><span style="color:#F69D50;">$</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">python</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">run_task.py</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">clear</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">$</span><span style="color:#24292E;"> </span><span style="color:#032F62;">python</span><span style="color:#24292E;"> </span><span style="color:#032F62;">run_task.py</span><span style="color:#24292E;"> </span><span style="color:#032F62;">clear</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><h2 id="スタックの削除" tabindex="-1">スタックの削除 <a class="header-anchor" href="#スタックの削除" aria-label="Permalink to &quot;スタックの削除&quot;"></a></h2><p>これにて,今回のハンズオンは終了である. 最後にスタックを削除しよう.</p><p>スタックを削除するには,前回までと同様に, AWS コンソールにログインし CloudFormation の画面から DELETE ボタンをクリックするか,コマンドラインからコマンドを実行する. コマンドラインから行う場合は,次のコマンドを使用する.</p><div class="language-sh vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki github-dark-dimmed vp-code-dark"><code><span class="line"><span style="color:#F69D50;">$</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">cdk</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">destroy</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">$</span><span style="color:#24292E;"> </span><span style="color:#032F62;">cdk</span><span style="color:#24292E;"> </span><span style="color:#032F62;">destroy</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div></div></div></main><footer class="VPDocFooter" data-v-39e6c32d data-v-bae355c8><!--[--><!--[--><!--[--><!--[--><!----><!--]--><!--]--><!--]--><!--]--><div class="edit-info" data-v-bae355c8><div class="edit-link" data-v-bae355c8><a class="VPLink link vp-external-link-icon no-icon edit-link-button" href="https://github.com/andatoshiki/toshiki-notebook/edit/master/docs/development/aws/handson-qabot.md" target="_blank" rel="noreferrer" data-v-bae355c8><!--[--><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="edit-link-icon" aria-label="edit icon" data-v-bae355c8><path d="M18,23H4c-1.7,0-3-1.3-3-3V6c0-1.7,1.3-3,3-3h7c0.6,0,1,0.4,1,1s-0.4,1-1,1H4C3.4,5,3,5.4,3,6v14c0,0.6,0.4,1,1,1h14c0.6,0,1-0.4,1-1v-7c0-0.6,0.4-1,1-1s1,0.4,1,1v7C21,21.7,19.7,23,18,23z"></path><path d="M8,17c-0.3,0-0.5-0.1-0.7-0.3C7,16.5,6.9,16.1,7,15.8l1-4c0-0.2,0.1-0.3,0.3-0.5l9.5-9.5c1.2-1.2,3.2-1.2,4.4,0c1.2,1.2,1.2,3.2,0,4.4l-9.5,9.5c-0.1,0.1-0.3,0.2-0.5,0.3l-4,1C8.2,17,8.1,17,8,17zM9.9,12.5l-0.5,2.1l2.1-0.5l9.3-9.3c0.4-0.4,0.4-1.1,0-1.6c-0.4-0.4-1.2-0.4-1.6,0l0,0L9.9,12.5z M18.5,2.5L18.5,2.5L18.5,2.5z"></path></svg> Edit this page on GitHub<!--]--></a></div><div class="last-updated" data-v-bae355c8><p class="VPLastUpdated" data-v-bae355c8 data-v-ec8405ef>Last updated: <time datetime="2024-02-02T05:01:47.000Z" data-v-ec8405ef></time></p></div></div><nav class="prev-next" data-v-bae355c8><div class="pager" data-v-bae355c8><a class="pager-link prev" href="/development/aws/docker-system" data-v-bae355c8><span class="desc" data-v-bae355c8>Previous page</span><span class="title" data-v-bae355c8>Docker 入門</span></a></div><div class="pager" data-v-bae355c8><a class="pager-link next" href="/development/aws/aws-batch" data-v-bae355c8><span class="desc" data-v-bae355c8>Next page</span><span class="title" data-v-bae355c8>Hands-on 4: AWS Batch を使って機械学習のハイパーパラメータサーチを並列化する</span></a></div></nav></footer><!--[--><!--[--><!--[--><div id="comment-container"></div><!--]--><!--]--><!--]--></div></div></div><!--[--><!--]--></div></div><footer class="VPFooter has-sidebar" data-v-f6284a77 data-v-b69a1592><div class="container" data-v-b69a1592><p class="message" data-v-b69a1592>Wrote with <i class="heart fa fa-heart fa-xs fa-beat"></i> and <i class="coffee fa fa-coffee fa-xs" aria-hidden="true"></i> by <a href="https://toshiki.dev">Anda Toshiki</a> at <code>root@andatoshiki:/~</code></p><p class="copyright" data-v-b69a1592>Copyright © 2023-2024 <a href="https://github.com/andatoshiki">Anda Toshiki</a>, <a href="https://github.com/lolilab">LoliLab</a> and <a href="https://github.com/toshikidev">Toshiki Dev</a> present <br /><span id="siteruntime_span"></span></p></div></footer><!--[--><!--]--></div></div>
<script>window.__VP_HASH_MAP__=JSON.parse("{\"academic_chemistry_index.md\":\"63186a5e\",\"academic_physics_index.md\":\"23e879b6\",\"academic_cis105_cis105-l1-lecture-note.md\":\"5480f968\",\"academic_chemistry_problems_03-02-3.md\":\"1503736c\",\"academic_cis105_cis105-l2-lecture-note.md\":\"b151f0c8\",\"application_vitepress-plugin-shiki-twoslash_api_includes.md\":\"a0e96d29\",\"academic_chemistry_problems_03-02-1.md\":\"b62845b4\",\"development_aws_closing.md\":\"ea855892\",\"development_aws_cloud.md\":\"f6bca2c0\",\"academic_cis105_cis105-l4-lecture-note.md\":\"e3cd6813\",\"application_vitepress-plugin-shiki-twoslash_guide_markdown-extensions.md\":\"4c8c57b7\",\"development_aws_index.md\":\"dc27f750\",\"development_aws_handson-qabot.md\":\"dc65026a\",\"development_aws_license.md\":\"829a8be3\",\"academic_literature_writing_methods-of-development.md\":\"90ac96af\",\"academic_physics_ipho-formulas-jpn_12.md\":\"42391252\",\"academic_cis105_cis105-l3-lecture-note.md\":\"5d7f6527\",\"application_vitepress-plugin-shiki-twoslash_guide_custom-theme.md\":\"487b6369\",\"development_aws_handson-serverless.md\":\"1cbf04b1\",\"application_vitepress-plugin-shiki-twoslash_index.md\":\"6850b047\",\"development_aws_handson-ec2.md\":\"53b66d2a\",\"application_vitepress-plugin-shiki-twoslash_api_queries.md\":\"5050595a\",\"development_aws_assignments.md\":\"caf7ac5b\",\"development_aws_acknowledgement.md\":\"e6e0e814\",\"development_aws_author.md\":\"2c01c7fe\",\"development_aws_appendix.md\":\"32360ecb\",\"academic_physics_ipho-formulas-jpn_6.md\":\"ea3a2627\",\"academic_literature_index.md\":\"ba7a556e\",\"academic_cis105_index.md\":\"5ae7321f\",\"academic_chemistry_problems_03-02-2.md\":\"cc6fca40\",\"development_aws_aws-get-started.md\":\"bc31cf93\",\"academic_physics_ipho-formulas-jpn_5.md\":\"09670c1a\",\"academic_physics_ipho-formulas-jpn_7.md\":\"757038a3\",\"development_aws_handson-bashoutter.md\":\"c54804e9\",\"academic_physics_ipho-formulas-jpn_8.md\":\"7c51f0eb\",\"application_vitepress-plugin-shiki-twoslash_api_emit.md\":\"66d3b3f7\",\"application_vitepress-plugin-shiki-twoslash_api_cutting.md\":\"b77bdb31\",\"application_vitepress-plugin-shiki-twoslash_api_annotations.md\":\"19113a54\",\"application_vitepress-plugin-shiki-twoslash_api_multi-file.md\":\"7ddffbf4\",\"application_markdown-it-katex_tips.md\":\"980dbf08\",\"academic_physics_ipho-formulas-jpn_11.md\":\"ec167aa8\",\"academic_vocabulary_2023_02_2023-02-27.md\":\"afd7c504\",\"academic_vocabulary_index.md\":\"872edd00\",\"application_markdown-it-katex_how-to-use.md\":\"e3b1f0e4\",\"academic_physics_ipho-formulas-jpn_9.md\":\"d50c8b08\",\"development_aws_docker-system.md\":\"f4ea8ba1\",\"academic_physics_ipho-formulas-jpn_4.md\":\"62acf8d3\",\"application_vitepress-plugin-shiki-twoslash_api_types.md\":\"7583257e\",\"jp_index.md\":\"efa2aade\",\"roadmap.md\":\"e1936b0f\",\"academic_physics_ipho-formulas-jpn_13.md\":\"95c8dd1b\",\"academic_physics_ipho-formulas-jpn_3.md\":\"e5f94e4e\",\"index.md\":\"de9ebc77\",\"save_reading_index.md\":\"9ada49fa\",\"save_reading_outliers_1.md\":\"017b61aa\",\"save_reading_outliers_2.md\":\"89602cff\",\"save_reading_outliers_4.md\":\"8dae3031\",\"save_reading_outliers_3.md\":\"45fb1ebd\",\"development_aws_scientific-computing.md\":\"cd6db567\",\"academic_chemistry_notes_12-5.md\":\"1326ac56\",\"academic_chemistry_problems_02-20.md\":\"2925a744\",\"application_vitepress-plugin-shiki-twoslash_api_logging.md\":\"623f0d01\",\"development_aws_serverless.md\":\"595c00f0\",\"application_vitepress-plugin-shiki-twoslash_api_errors.md\":\"1f522dad\",\"application_vitepress-plugin-shiki-twoslash_config_flags.md\":\"b5dac286\",\"academic_physics_ipho-formulas-jpn_2.md\":\"3233a614\",\"javascript_notes_1_1-1.md\":\"d7c13320\",\"development_aws_webserver.md\":\"8b8c94ce\",\"development_aws_aws-batch.md\":\"87b41e3f\",\"javascript_notes_1_1-2.md\":\"a97c2f72\",\"application_vitepress-plugin-shiki-twoslash_config_reference.md\":\"8b316a87\",\"development_aws_handson-jupyter.md\":\"4f0883ab\",\"academic_physics_ipho-formulas-jpn_1.md\":\"29bcc50e\",\"development_file-naming-convention.md\":\"01d6740e\",\"development_rclone-for-r2.md\":\"817f00b5\",\"development_aws_main.md\":\"8ceb5f74\",\"development_proxy4shell-terminal.md\":\"ba3135a9\",\"academic_physics_ipho-formulas-jpn_10.md\":\"30e20394\",\"getting-started.md\":\"6de51a0d\",\"application_markdown-it-katex_support-function.md\":\"ec1dde8a\",\"application_markdown-it-katex_support-table.md\":\"1a3f80f8\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Toshiki's Note\",\"description\":\"Toshiki's web notebook served via Vitepress!\",\"base\":\"/\",\"head\":[],\"appearance\":true,\"themeConfig\":{\"nav\":[{\"text\":\"Development\",\"link\":\"/development/\"},{\"text\":\"Academic\",\"items\":[{\"text\":\"K-12\",\"items\":[{\"text\":\"Chemistry\",\"link\":\"/academic/chemistry/index\",\"activeMatch\":\"/academic/chemistry/\"},{\"text\":\"Discrete Math.\",\"link\":\"/discrete-math/index\",\"activeMatch\":\"/categories/fragments/\"},{\"text\":\"Literature\",\"link\":\"/academic/literature/index\",\"activeMatch\":\"/academic/literature/\"},{\"text\":\"CIS105\",\"link\":\"/academic/cis105/index\",\"activeMatch\":\"/academic/cis105/\"}]},{\"text\":\"Tools\",\"items\":[{\"text\":\"Formulas for IPhO JPN.\",\"link\":\"/academic/physics/ipho-formulas-jpn/1\",\"activeMatch\":\"/academic/physics/ipho-formulas-jpn/\"}]},{\"text\":\"\",\"link\":\"\",\"activeMatch\":\"\"},{\"text\":\"\",\"link\":\"\",\"activeMatch\":\"\"},{\"text\":\"\",\"link\":\"\",\"activeMatch\":\"\"},{\"text\":\"\",\"link\":\"\",\"activeMatch\":\"\"},{\"text\":\"\",\"link\":\"\",\"activeMatch\":\"\"},{\"text\":\"\",\"link\":\"\",\"activeMatch\":\"\"},{\"text\":\"\",\"link\":\"\",\"activeMatch\":\"\"}],\"activeMatch\":\"/academic/\"},{\"text\":\"Application\",\"items\":[{\"text\":\"Personal projects\",\"items\":[{\"text\":\"markdown-it-katex\",\"link\":\"/application/markdown-it-katex/how-to-use\",\"activeMatch\":\"/application/markdown-it-katex/\"},{\"text\":\"vitepress-plugin-shiki-twoslash\",\"link\":\"/application/vitepress-plugin-shiki-twoslash/index\",\"activeMatch\":\"/application/vitepress-plugin-shiki-twoslash/index\"}]}],\"activeMatch\":\"/save/\"},{\"text\":\"Save\",\"items\":[{\"text\":\"Reading\",\"link\":\"/save/reading/index\",\"activeMatch\":\"/save/reading/\"},{\"text\":\"Vocabulary\",\"link\":\"/academic/vocabulary/index\",\"activeMatch\":\"/academic/vocabulary/\"}],\"activeMatch\":\"/save/\"}],\"sidebar\":{\"/development/\":[{\"text\":\"Notes & Issues\",\"collapsed\":false,\"items\":[{\"text\":\"File Naming Convention\",\"link\":\"/development/file-naming-convention\"},{\"text\":\"RClone for R2\",\"link\":\"/development/rclone-for-r2\"},{\"text\":\"Proxies Configuration for Shells & Terminal\",\"link\":\"/development/proxy4shell-terminal\"}]},{\"text\":\"コードで学ぶAWS入門\",\"collapsed\":false,\"items\":[{\"text\":\"背景\",\"link\":\"/development/aws/index\"},{\"text\":\"はじめに!\",\"link\":\"/development/aws/main\"},{\"text\":\"クラウド概論\",\"link\":\"/development/aws/cloud.md\"},{\"text\":\"AWS 入門\",\"link\":\"/development/aws/aws-get-started\"},{\"text\":\"Hands-on 1: 初めての EC2 インスタンスを起動する\",\"link\":\"/development/aws/handson-ec2.md\"},{\"text\":\"クラウドで行う科学計算・機械学習\",\"link\":\"/development/aws/scientific-computing.md\"},{\"text\":\"Hands-on 2: AWS でディープラーニングを実践\",\"link\":\"/development/aws/handson-ec2.md\"},{\"text\":\"Docker 入門\",\"link\":\"/development/aws/docker-system\"},{\"text\":\"Hands-on 3: AWS で自動質問回答ボットを走らせる\",\"link\":\"/development/aws/handson-qabot\"},{\"text\":\"Hands-on 4: AWS Batch を使って機械学習のハイパーパラメータサーチを並列化する\",\"link\":\"/development/aws/aws-batch\"},{\"text\":\"Web サービスの作り方\",\"link\":\"/development/aws/webserver\"},{\"text\":\"Serverless architecture\",\"link\":\"/development/aws/serverless\"},{\"text\":\"Hands-on 5: サーバーレス入門\",\"link\":\"/development/aws/handson-serverless\"},{\"text\":\"Hands-on 6: Bashoutter\",\"link\":\"/development/aws/handson-bashoutter\"},{\"text\":\"まとめ\",\"link\":\"/development/aws/closing\"},{\"text\":\"ppendix: 環境構築\",\"link\":\"/development/aws/appendix\"},{\"text\":\"謝辞\",\"link\":\"/development/aws/acknowledgement\"}]}],\"/academic/chemistry/\":[{\"text\":\"Textbook\",\"collapsed\":true,\"items\":[{\"text\":\"12-5: Reaction Mechanism\",\"link\":\"/academic/chemistry/notes/12-5\"},{\"text\":\"\",\"link\":\"\"},{\"text\":\"\",\"link\":\"\"},{\"text\":\"\",\"link\":\"\"},{\"text\":\"\",\"link\":\"\"},{\"text\":\"\",\"link\":\"\"},{\"text\":\"\",\"link\":\"\"},{\"text\":\"\",\"link\":\"\"}]},{\"text\":\"Kinetics\",\"collapsed\":false,\"items\":[{\"text\":\"Rate determining steps\",\"link\":\"/academic/chemistry/notes/kinetics/rate-determining-step\"},{\"text\":\"\",\"link\":\"\"},{\"text\":\"\",\"link\":\"\"},{\"text\":\"\",\"link\":\"\"}]},{\"text\":\"Problems & Solutions\",\"collapsed\":true,\"items\":[{\"text\":\"Problem: 02-20\",\"link\":\"/academic/chemistry/problems/02-20\"},{\"text\":\"Problem: 03-02-1\",\"link\":\"/academic/chemistry/problems/03-02-1\"},{\"text\":\"Problem: 03-02-2\",\"link\":\"/academic/chemistry/problems/03-02-2\"},{\"text\":\"Problem: 03-02-3\",\"link\":\"/academic/chemistry/problems/03-02-3\"}]}],\"/academic/physics\":[{\"text\":\"IPhO Formulas: JP Ver.\",\"collapsed\":false,\"items\":[{\"text\":\"1: 数学\",\"link\":\"/academic/physics/ipho-formulas-jpn/1\"},{\"text\":\"2: 一般的な推奨事\",\"link\":\"/academic/physics/ipho-formulas-jpn/2\"},{\"text\":\"3: 運動学\",\"link\":\"/academic/physics/ipho-formulas-jpn/3\"},{\"text\":\"4: 力学\",\"link\":\"/academic/physics/ipho-formulas-jpn/4\"},{\"text\":\"5: 振動と波\",\"link\":\"/academic/physics/ipho-formulas-jpn/5\"},{\"text\":\"6: 幾何光学,測光\",\"link\":\"/academic/physics/ipho-formulas-jpn/6\"},{\"text\":\"7: 波動光学\",\"link\":\"/academic/physics/ipho-formulas-jpn/7\"},{\"text\":\"8: 電気回路\",\"link\":\"/academic/physics/ipho-formulas-jpn/8\"},{\"text\":\"9: 電磁気学\",\"link\":\"/academic/physics/ipho-formulas-jpn/9\"},{\"text\":\"10: 熱力\",\"link\":\"/academic/physics/ipho-formulas-jpn/10\"},{\"text\":\"11: 量子力学\",\"link\":\"/academic/physics/ipho-formulas-jpn/11\"},{\"text\":\"12: Keplerの法則\",\"link\":\"/academic/physics/ipho-formulas-jpn/12\"},{\"text\":\"13: 相対性理論\",\"link\":\"/academic/physics/ipho-formulas-jpn/13\"}]}],\"/academic/cis105/\":[{\"text\":\"CIS 105: Computer Applications and Information Technology\",\"collapsed\":false,\"items\":[{\"text\":\"Course Overview & Schedule\",\"link\":\"/academic/cis105/index\"},{\"text\":\"Lect 1: Everything Changes\",\"link\":\"/academic/cis105/cis105-l1-lecture-note\"},{\"text\":\"Lect 2: Application Software\",\"link\":\"/academic/cis105/cis105-l2-lecture-note\"},{\"text\":\"Lect 3: Computer Hardware\",\"link\":\"/academic/cis105/cis105-l3-lecture-note\"},{\"text\":\"Lect 4: Formulas and Functions\",\"link\":\"/academic/cis105/cis105-l4-lecture-note\"}]}],\"/academic/vocabulary/\":[{\"text\":\"Vocabulary\",\"collapsed\":true,\"items\":[{\"text\":\"2023-02-27\",\"link\":\"/academic/vocabulary/2023/02/2023-02-27\"}]}],\"/academic/literature/\":[{\"text\":\"Writing Resources\",\"collapsed\":true,\"items\":[{\"text\":\"Patterns of Organization and Methods of Development\",\"link\":\"/academic/literature/writing/methods-of-development\"}]}],\"/javascript/\":[{\"text\":\"1: Basic JavaScript-Value, Variables, and Control Flow\",\"collapsed\":true,\"items\":[{\"text\":\"1-1: Numbers\",\"link\":\"/javascript/notes/1/1-1\"},{\"text\":\"\",\"link\":\"\"},{\"text\":\"\",\"link\":\"\"},{\"text\":\"\",\"link\":\"\"},{\"text\":\"\",\"link\":\"\"}]}],\"/save/reading/\":[{\"text\":\"Outliers\",\"collapsed\":true,\"items\":[{\"text\":\"Introduction & Chapter 1: The Roseto Mystery\",\"link\":\"/save/reading/outliers/1\"},{\"text\":\"Chapter 2: The 10,000-Hour Rule\",\"link\":\"/save/reading/outliers/2\"},{\"text\":\"Chapter 3: The Trouble with Geniuses, Part 1\",\"link\":\"/save/reading/outliers/3\"},{\"text\":\"Chapter 4: The Trouble with Geniuses, Part 2\",\"link\":\"/save/reading/outliers/4\"}]}],\"/application/markdown-it-katex/\":[{\"text\":\"markdown-it-katex\",\"collapsed\":false,\"items\":[{\"text\":\"1: How to use?\",\"link\":\"/application/markdown-it-katex/how-to-use\"},{\"text\":\"2: KaTeX supported functions\",\"link\":\"/application/markdown-it-katex/support-function\"},{\"text\":\"3: KaTeX support tables\",\"link\":\"/application/markdown-it-katex/support-table\"},{\"text\":\"4: Tips\",\"link\":\"/application/markdown-it-katex/tips\"}]}],\"/application/vitepress-plugin-shiki-twoslash/\":[{\"text\":\"Guide\",\"collapsed\":false,\"items\":[{\"text\":\"Getting Started\",\"link\":\"/application/vitepress-plugin-shiki-twoslash/\"},{\"text\":\"Markdown Extensions\",\"link\":\"/application/vitepress-plugin-shiki-twoslash/guide/markdown-extensions\"},{\"text\":\"Using a Custom Theme\",\"link\":\"/application/vitepress-plugin-shiki-twoslash/guide/custom-theme\"}]},{\"text\":\"Features\",\"collapsed\":false,\"items\":[{\"text\":\"Queries\",\"link\":\"/application/vitepress-plugin-shiki-twoslash/api/queries\"},{\"text\":\"Errors\",\"link\":\"/application/vitepress-plugin-shiki-twoslash/api/errors\"},{\"text\":\"Emit\",\"link\":\"/application/vitepress-plugin-shiki-twoslash/api/emit\"},{\"text\":\"Cutting\",\"link\":\"/application/vitepress-plugin-shiki-twoslash/api/cutting\"},{\"text\":\"Multi-file\",\"link\":\"/application/vitepress-plugin-shiki-twoslash/api/multi-file\"},{\"text\":\"@types\",\"link\":\"/application/vitepress-plugin-shiki-twoslash/api/types\"},{\"text\":\"Meta Annotations\",\"link\":\"/application/vitepress-plugin-shiki-twoslash/api/annotations\"},{\"text\":\"Logging\",\"link\":\"/application/vitepress-plugin-shiki-twoslash/api/logging\"},{\"text\":\"Includes\",\"link\":\"/application/vitepress-plugin-shiki-twoslash/api/includes\"}]},{\"text\":\"Config\",\"collapsed\":false,\"items\":[{\"text\":\"Reference\",\"link\":\"/application/vitepress-plugin-shiki-twoslash/config/reference\"},{\"text\":\"Compiler Flags\",\"link\":\"/application/vitepress-plugin-shiki-twoslash/config/flags\"}]}]},\"footer\":{\"copyright\":\"Copyright © 2023-2024 <a href=\\\"https://github.com/andatoshiki\\\">Anda Toshiki</a>, <a href=\\\"https://github.com/lolilab\\\">LoliLab</a> and <a href=\\\"https://github.com/toshikidev\\\">Toshiki Dev</a> present <br /><span id=\\\"siteruntime_span\\\"></span>\",\"message\":\"Wrote with <i class=\\\"heart fa fa-heart fa-xs fa-beat\\\"></i> and <i class=\\\"coffee fa fa-coffee fa-xs\\\" aria-hidden=\\\"true\\\"></i> by <a href=\\\"https://toshiki.dev\\\">Anda Toshiki</a> at <code>root@andatoshiki:/~</code>\"},\"logo\":\"/logos/logo.png\",\"outline\":\"deep\",\"outlineTitle\":\"TOC\",\"outlineBadges\":false,\"lastUpdatedText\":\"Last updated\",\"algolia\":{\"appId\":\"G9IUR45K98\",\"apiKey\":\"8528cc91281d8112b28f508317a96dd3\",\"indexName\":\"toshiki-notebook\"},\"editLink\":{\"pattern\":\"https://github.com/andatoshiki/toshiki-notebook/edit/master/docs/:path\",\"text\":\"Edit this page on GitHub\"},\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/andatoshiki\"},{\"icon\":\"twitter\",\"link\":\"https://twitter.com/andatoshiki\"}]},\"locales\":{\"/\":{\"label\":\"English\",\"lang\":\"en-US\"},\"/jp/\":{\"label\":\"Japanese\",\"title\":\"Vue Test Utils\",\"lang\":\"jp-JP\",\"description\":\"La documentation officielle de Vue Test Utils\"}},\"scrollOffset\":90,\"cleanUrls\":true}");</script>
</body>
</html>