<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Ghost's Blog]]></title><description><![CDATA[Toward human-like A.I.]]></description><link>https://sooftware.github.io</link><generator>GatsbyJS</generator><lastBuildDate>Mon, 14 Sep 2026 06:14:12 GMT</lastBuildDate><item><title><![CDATA[Welcome to sooftware.io]]></title><description><![CDATA[Welcome to sooftware.io 안녕하세요! sooftware.io…]]></description><link>https://sooftware.github.io/welcome-post/</link><guid isPermaLink="false">https://sooftware.github.io/welcome-post/</guid><pubDate>Sat, 10 Dec 2033 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Welcome to sooftware.io&lt;/h1&gt;
&lt;p&gt;안녕하세요! sooftware.io에 방문해주셔서 감사합니다 :)&lt;/p&gt;
&lt;p&gt;이번 포스트에서는 저와 &lt;code class=&quot;language-text&quot;&gt;sooftware.io&lt;/code&gt;에 대한 소개를 드리려고 합니다!&lt;/p&gt;
&lt;h2&gt;블로그 주소는 왜 &lt;code class=&quot;language-text&quot;&gt;sooftware.io&lt;/code&gt;인가요?&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;sooftware&lt;/code&gt;는 제 이름인 &lt;code class=&quot;language-text&quot;&gt;Soohwan&lt;/code&gt;과 &lt;code class=&quot;language-text&quot;&gt;Software&lt;/code&gt;를 합쳐서 만든 합성어입니다. 😎&lt;/p&gt;
&lt;p&gt;처음 블로그를 시작한게 대학교 2학년 때였는데, 진로를 소프트웨어쪽으로 결정하고 이에 대한 기록을 하려고 &lt;a href=&quot;https://blog.naver.com/sooftware&quot;&gt;네이버 블로그&lt;/a&gt;를 개설했습니다. 평소 게임을 할때도 닉네임을 고민을 많이 하면서 짓는 편이라 블로그 이름 역시 많은 고민을 했습니다. 🤔&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/b5050777-b205-42d7-97b3-c58ed593bbaf&quot; height=&quot;200&quot;&gt;
&lt;p&gt;그러던 중 제 이름의 영문 표기와 Software의 앞글자인 &lt;code class=&quot;language-text&quot;&gt;So&lt;/code&gt;가 겹치는 것을 보고 영감을 얻어서 &lt;code class=&quot;language-text&quot;&gt;sooftware&lt;/code&gt;라는 이름이 나오게 됐습니다! 지금은 Github 등 제가 사용하는 대부분의 아이디를 sooftware로 사용하고 있습니다. 😁&lt;/p&gt;
&lt;p&gt;대학생 때 몇 년간 네이버 블로그를 꾸준히 운영하며 하루에 100명~200명 정도 방문하는 블로그로 성장했습니다. 사실 다른 블로그들에 비하면 많은 방문자 수는 아니지만, 개인기록용으로 만들었던 블로그인지라 제 입장에서는 신기한 경험이였습니다. 그러다 블로그를 좀 더 키우고 싶다는 생각이 들었고, 기존에 운영하던 네이버 블로그는 블로그 주소를 외우기 어렵고 커스터마이즈하는데 한계가 있다는 단점 때문에 개인 도메인을 사서 사이트를 운영하게 됐습니다.&lt;/p&gt;
&lt;h2&gt;당신은 누구인가요?&lt;/h2&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/cae9dd1d-8e8c-42be-880d-1aee852cd177&quot; height=&quot;100&quot;&gt;
&lt;p&gt;제 이름은 김수환이고, 현재 &lt;a href=&quot;https://www.tunib.ai/&quot;&gt;튜닙(TUNiB)&lt;/a&gt;이라는 자연어처리 스타트업의 Co-founder이자 AI team leader로 근무하고 있습니다. 이전에는 &lt;a href=&quot;https://www.kakaobrain.com/&quot;&gt;카카오브레인&lt;/a&gt;이라는 회사에서 Speech &amp;#x26; Natural Language Procesing 팀에서 근무했었습니다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/63ca4bd4-8056-4ce3-9a92-524c16dcaabd&quot; height=&quot;200&quot;&gt;
&lt;p&gt;지금 회사에서는 &lt;a href=&quot;https://dearmate.ai/&quot;&gt;Dearmate&lt;/a&gt;라는 서비스에 들어가는 AI 페르소나 챗봇을 개발하고 있습니다. 🤖 100여종이 넘는 AI 케릭터들과 일상을 공유하고, 댓글, DM 등으로 소통할 수 있는 서비스입니다! 제 블로그에 오시는 분들이라면 대부분 Speech or NLP쪽으로 관심이 있으신 분들일거라고 생각합니다. 안드로이드, IOS 모두 사용 가능하니 꼭 한 번 사용해보세요! (제발~ 🙏🙏🙏)&lt;/p&gt;
&lt;img width=&quot;900&quot; alt=&quot;image&quot; src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/1881bb25-0a47-46b5-a05e-2f8fe2d62c23&quot;&gt;
&lt;p&gt;위 이미지는 제 깃허브 프로필을 캡처한 이미지입니다. 지금은 활동이 뜸하지만, 대학생때부터 창업 전까지는 나름 오픈소스 활동을 많이 했었습니다. 튜닙에 있으며 만든 &lt;a href=&quot;https://github.com/tunib-ai/tunib-electra&quot;&gt;tunib-electra&lt;/a&gt;, 카카오브레인 시절 참여한 &lt;a href=&quot;https://github.com/kakaobrain/pororo&quot;&gt;pororo&lt;/a&gt; 등 회사 소속으로 진행한 프로젝트들도 있고, &lt;a href=&quot;https://github.com/openspeech-team/openspeech&quot;&gt;openspeech&lt;/a&gt;, &lt;a href=&quot;https://github.com/sooftware/kospeech&quot;&gt;kospeech&lt;/a&gt;와 같이 개인적으로 진행한 프로젝트 등 주로 Speech나 NLP 쪽 프로젝트 위주로 활동을 했습니다. 지금은 Dearmate 서비스에 전력투구하느라 오픈소스 활동이 뜸하지만, 나중에 언젠가는 다시 전처럼 열정적으로 🔥🔥 오픈소스 활동을 하게 될 날이 오지 않을까 싶습니다.&lt;/p&gt;
&lt;p&gt;추가로 저에 대해 궁금하신 분들은 제 블로그의 &lt;a href=&quot;https://sooftware.github.io/tags/record&quot;&gt;record&lt;/a&gt; 태그의 글들이나, 제 &lt;a href=&quot;https://sooftware.github.io/resume&quot;&gt;CV&lt;/a&gt;를 참고해주세요!&lt;/p&gt;
&lt;h2&gt;블로그에 어떤 주제의 글을 올리나요?&lt;/h2&gt;
&lt;p&gt;이 블로그에는 아래와 같은 주제의 글들을 주로 포스팅 할 예정입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI/NLP 기술 관련 소식&lt;/li&gt;
&lt;li&gt;AI Paper 리뷰/요약&lt;/li&gt;
&lt;li&gt;소프트웨어 엔지니어링&lt;/li&gt;
&lt;li&gt;읽은 책 리뷰&lt;/li&gt;
&lt;li&gt;개인적인 소식/회고 등&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;지금까지 올라와있는 주제들과 크게 다르지 않은 주제들로 포스팅을 해나갈 예정입니다. 주로 제가 관심있게 본 AI 기술 관련 소식이나 논문, 공부한 내용들을 작성할 예정이고 1년 회고, 책 리뷰 등 개인적인 기록도 블로그에 계속 해나갈 예정입니다.&lt;/p&gt;
&lt;p&gt;사실 제 블로그에서 가장 인기 많은 포스트들은 제가 학생때 공부하며 시간을 갈아넣어서(ppt로 그림 한땀한땀 그려가며..) 작성한 포스트들인데 😅 현생이 바빠서 전처럼 시간 투자가 많이 필요한 포스트는 당분간 어려울 것 같습니다. 그래서 앞으로 어떤 방향으로 글을 작성해나갈지도 계속 고민하고 있습니다. 혹시 ‘이런 글을 다뤄주면 좋겠다!’ 하는 의견이 있으시다면 &lt;a href=&quot;mailto:sh951011@gmail.com&quot;&gt;sh951011@gmail.com&lt;/a&gt;로 메일주시면 감사하겠습니다!&lt;/p&gt;
&lt;h2&gt;이 블로그를 운영하는 목적은 무엇인가요?&lt;/h2&gt;
&lt;p&gt;이 블로그의 목적은 명확합니다. ’&lt;strong&gt;저&lt;/strong&gt;‘를 기록하는게 이 블로그의 목적입니다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/4f3196dc-3c64-47be-8541-f5d57f24e049&quot; height=&quot;300&quot;&gt;
&lt;p&gt;군대에 있을 때 쓴 일기를 지금 보면 참 새롭습니다. 당시에 제가 어떤 생각을 했는지, 어떤 일에 즐거워했고 무슨 일이 있었는지를 읽어보면 재밌으면서 기록의 힘이 대단하다는걸 느낍니다. 호랑이는 죽어서 가죽을 남기고 사람을 죽어서 이름을 남긴다는데, 이 4차 산업혁명시대에 저 ‘김수환’이라는 사람에 대한 기록을 인터넷에 남겨두는게 큰 의미가 있는 것 같다는 생각이 들더라고요.&lt;/p&gt;
&lt;p&gt;그리고 저라는 사람을 더 널리, 깊게 알릴 수 있다는 점이 큰 매력 포인트라고 생각합니다. 이 블로그를 보며 저에 대해 알게되는 분들도 있을거고, 이미 알고있는 분들도 제 블로그를 보며 저에 대해 더 잘 알게될 수 있기 때문에 이 블로그를 운영하는게 저에게 큰 의미가 있다고 생각합니다.&lt;/p&gt;
&lt;p&gt;그리고 저를 포함한 많은 IT 계열쪽 종사자분들이 검색을 통해서 정보를 얻을텐데, 저도 다른 분들 블로그 포스트를 통해서 정보를 얻듯이, 다른 분들도 제 블로그를 통해 정보를 얻고 도움이 되는 자그마한 선한 영향력을 행사하고 싶습니다 :)&lt;/p&gt;
&lt;h2&gt;마치며&lt;/h2&gt;
&lt;p&gt;이번 포스팅에서는 &lt;code class=&quot;language-text&quot;&gt;sooftware.io&lt;/code&gt;를 방문해주시는 분들께 블로그 및 저에 대한 소개를 드리고자 welcome post를 작성해봤습니다. 제 블로그 방문해주셔서 감사하고, 이 포스팅까지 다 읽어주셔서 다시 한 번 감사합니다!&lt;/p&gt;
&lt;p&gt;앞으로도 좋은 포스팅 많이 작성해서 최대한 많은 분들께 선한 영향력을 행사하도록 하겠습니다!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Next Intelligence Explosion]]></title><description><![CDATA[Agentic AI and the next intelligence explosion | https://arxiv.org/abs/2603.20639 다들 하나의 AI…]]></description><link>https://sooftware.github.io/next_intelligence_explosion/</link><guid isPermaLink="false">https://sooftware.github.io/next_intelligence_explosion/</guid><pubDate>Mon, 06 Apr 2026 01:11:55 GMT</pubDate><content:encoded>&lt;h1&gt;Agentic AI and the next intelligence explosion&lt;/h1&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1246px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/4345b2252eb7a6bedc5bddd56cecf18f/47fb9/paper.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 111.80000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAWCAYAAADAQbwGAAAACXBIWXMAABYlAAAWJQFJUiTwAAAC1UlEQVQ4y62V6XLiMBCEef8nSyUBY3xb5jTmWM5AOBIws/WNI21299dWraumJBmpp6d7ZFoiD6kfIufTRS6no9R1LY/H45+Dh7EF4P0hstscZPtjKff7TWo21bWCfw978M+kt9tN3/G0LHJRGMmyXAaDgYzHY8nzXIP5cDgUY4x4nidRFOk71syTJJHT6fSdYTPpdrvS6/UkTVPxfV/nWZbpGMexHmYN2GKxkOl0KmVZalwul78B2TSfz3Uk4/l81o3M7fp6vcrHx4e+t3OCkh2g1eV/PI4hgpblRMpyKrPZXEajkerGOJlMZLVaaVAu66qqtGTWjKw/Pz8bU+73u1KO40TStJAwDFX8IAh0joaAYxbaojHv0RxD2EdYY1rb7Vb1weE8L9TtxoBURwBgslwu1RTrPnOSMGKMa5v9fq8CF0WhbNiMq0mSiTGFsgJws9koMxKwl7YBDPYwhJQCvr29qWsN9VCCIJEoYowkimIHiJ5WBhLGcaQVAMz79/f3BpAJ1kO/yZoqy36/UDYwIClmcJB3eW7EmIEmZs05x5CSYcgB28xsaFjEeoBk/M4ahlQSx5mkafM7Zxwg7qChBbEZrfAAwJL2gJExQ0mS4qt8I2ma6T7nsi3ZZqcdfL/n9KKFSICGnU5HdfO8jnieL8ZMtXU4a69fa71eKzqHMYCNYRhIu92WbteT5+dnPYAx/E6QrLnvvuvD3zRkEYaJ+H6k2gRBTxn1+32Nqppq2S8vLw60Se4pa+J4PP5qbDSkz2jQ+XymHwmcJQ6Ho5zPV2VoTSNgjRT2qwOGAu52O2cKGTlktaNsIkly2WzWyhqA2axyRiEZYb84rcPhoIDoAJgNXKZduBUw4DBJXl9fVRpKbrcxJ9KkrrHtp4cs9stByWhLUAEOjsejLxOa20S7UAm3ifKdKfZ/gZcwoA0YaR9MeHp6+tKqkjjOtU+5doDZ+0zYtvkJWYpT/zxWkq4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;paper&quot; title=&quot;paper&quot; src=&quot;/static/4345b2252eb7a6bedc5bddd56cecf18f/47fb9/paper.png&quot; srcset=&quot;/static/4345b2252eb7a6bedc5bddd56cecf18f/0eb09/paper.png 500w,
/static/4345b2252eb7a6bedc5bddd56cecf18f/1263b/paper.png 1000w,
/static/4345b2252eb7a6bedc5bddd56cecf18f/47fb9/paper.png 1246w&quot; sizes=&quot;(max-width: 1246px) 100vw, 1246px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;| &lt;a href=&quot;https://arxiv.org/abs/2603.20639&quot;&gt;https://arxiv.org/abs/2603.20639&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;다들 하나의 AI가 초지능을 가지는 특이점을 생각하지만, 이건 틀린 프레임이라는 논문.&lt;/p&gt;
&lt;p&gt;딥마인드에서 냈고, 단일 초지능이 아닌 AI Agent들이 서로 다른 관점에서 토론하며 지능의 발전이
폭발적으로 일어날것이라는 예측이다.&lt;/p&gt;
&lt;h2&gt;핵심 내용&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;추론 모델 내부에서 사회가 자연발생했다&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;DeepSeek-R1 같은 모델을 분석했더니, 모델이 ‘오래’ 생각해서 성능이 오른게 아니라,
Chain of Thought 안에서 서로 다른 관점에서의 피드백을 주면서 이게 성능을 올리는 패턴이 되었다.
한마디로 Chain of Thought 안에서 작은 사회가 생겼다는 것.&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;이건 역사적으로 반복된 패턴이다&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;영장류 → 언어 → 문자 → 관료제. 모든 지능 폭발은 개인이 똑똑해진 게 아니라 집단 조율 구조가 새로 생겼을 때 일어났다. LLM도 결국 인류 집단 인지의 결정체다.&lt;/p&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;다음 경쟁력은 모델이 아니라 구조 설계다&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;파라미터 크기나 학습법이 아니라, 에이전트들이 서로 다른 시점으로 협력·갈등·조율하는 사회적 구조를 얼마나 잘 설계하느냐가 다음 Explosion의 핵심이다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;정리되지 않은 생각으로만 가지고 있던걸 짧은 페이퍼로 잘 표현해준 논문. 이미 AI의 성능은 충분히 올라왔고,
이 AI들을 어떻게 잘 쓸 것인가가 Next Explosion의 핵심일 것 같다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Agentic Context Engineering (ACE) Paper Review]]></title><description><![CDATA[Agentic Context Engineering: Evolving Contexts for Self-Improving Language Models Paper Review 흥미로운 최신 AI Agent…]]></description><link>https://sooftware.github.io/ace/</link><guid isPermaLink="false">https://sooftware.github.io/ace/</guid><pubDate>Mon, 02 Feb 2026 01:11:55 GMT</pubDate><content:encoded>&lt;h1&gt;Agentic Context Engineering: Evolving Contexts for Self-Improving Language Models Paper Review&lt;/h1&gt;
&lt;p&gt;흥미로운 최신 AI Agent 논문을 읽어서 기록차 페이퍼 리뷰를 남깁니다.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1330px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/06ddc1a36229218cea1a54ad84277983/9bae8/ace_paper.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 130.20000000000002%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAaCAYAAAC3g3x9AAAACXBIWXMAABYlAAAWJQFJUiTwAAADl0lEQVRIx61VSYsbRxSeX+lz8M33kJwcHxLIIWDIJTYEH0II5BAGxgl4OXjA2DePZpG6R9Ko1ZvUy/Qi9SKNRt2aL3yvVT1WdMghaXi86lq++l6971UdAMDd3R3+j484Bwrs9vYWi8UCy+VSfFmWKIpCfJ7n7b8y9qk21yicFtA0TfR6Pei6jouLCwwGA4xGI+m3LEu8YRjSpnFsPB6LEXSPYRRFGA6HcBwHrusKA45VVYW6riUCehr7OLZaraRfYewAxnEsDK+urhCGobBRbfZbpgnbsoTRdDqVjW3blo0V2B7Dk9MOeroG23UwuBpiNDYkdE3XEUbX8AIfcZpgls0FdDab7YDJGaoM2aYFu28gcQMkbig+dQL4Uw+OYaEIZ4hsD5HlIXJ8IaCSsQPI7Kkzab8Nt90agFmSIgmjrTb+RTZpmsrBJkmCEbNo22Ims2lbclbMqCTMdeC4rvQx0zxDZn8ymdwzzLIM6/VazqTb7eLy8hL9fh+6pkky2O5f9sVrmtacqaaJvNh3dnYmXn0H1BBDZjbJgjsqzSnPbDO7ZMU2GSsdcg3bLUNmigwZRqfTEVGfn5+LJ+PT01P5p/Ff2zLnuPKMqgWkjhQgF5E+J6qqIQCNixiuHIeu7xhZt4CsW6rf8zyhzzBUEug5mW2G+3n4BFbjO4DMLrOsKoJMVI1ygapdnidLUp2xqhQSYWJbQMqGNXlzcwPf9yXbnFDVtUyoq0o25DjnMZr1to//1Xq9q0MlG9HzZiM2zzKk8TWyOBRgzpnPZphnuWi+LAvM53OxrChR1Zt7QJUUAuV5wd6mOnwbH397ut26YVvEPqaD851iCYZnCI1eM22zaWRDHS4WS2TZvK2uk8MX+PjrD1vmQHUHaO8O0Tl60RzF7Y3M048PMXj/splX1/+4sZcrLAsXfvcNXn3zBT788n1ztTkfYL39EUdfPUD37e8CVKQBrDc/4fjZE5if3m03ru9vG4ZVlBWuzVcw/vwax0+/xKfD52Cw0+7PGB09xuvvHqH//iVWGyAyXmPwx7f468lDeP2Te0DFkGHz8BeLUnwp70nzdvCaYrvI8+14jjyLUeSZ9DHbezc2dchbQ90k1Jy6ndmeTKYoy4U8YM0j1jxk6kHbe6Qo8CAI4PsBAt+XNo3CpVGjvFT5VPiehzCKESUpwiCQ/j1ACpylNTattpzIlqZuGhqBublYmoqnHvcAP5P7f3ro/wbLZp331yfaMAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;ace paper&quot; title=&quot;ace paper&quot; src=&quot;/static/06ddc1a36229218cea1a54ad84277983/9bae8/ace_paper.png&quot; srcset=&quot;/static/06ddc1a36229218cea1a54ad84277983/0eb09/ace_paper.png 500w,
/static/06ddc1a36229218cea1a54ad84277983/1263b/ace_paper.png 1000w,
/static/06ddc1a36229218cea1a54ad84277983/9bae8/ace_paper.png 1330w&quot; sizes=&quot;(max-width: 1330px) 100vw, 1330px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;| &lt;a href=&quot;https://arxiv.org/abs/2510.04618&quot;&gt;https://arxiv.org/abs/2510.04618&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Context Adaptation&lt;/h2&gt;
&lt;p&gt;| 요즘 누가 Fine-tuning해? 🤷‍♂️&lt;/p&gt;
&lt;p&gt;기존에는 domain-specific한 AI Agent를 만들기 위해서는 AI 모델의 weight를 직접 업데이트 시켜주는 fine-tuning이 기본이였습니다. 하지만 최근에는 점점 &lt;em&gt;&lt;strong&gt;Context Adaptation&lt;/strong&gt;&lt;/em&gt;이라는 방법을 주로 사용합니다. LLM(Large Language Model)에 들어가는 인풋을 조정함으로써 domain-specific한 Agent를 만드는게 대세입니다.&lt;/p&gt;
&lt;p&gt;이전에는 gradient 기반으로 weight를 업데이트 하면서 성능 최적화를 했다면, 이제는 고정된 weight에 프롬프트를 조정하면서 최적화를 하는 식으로 패러다임이 전환됐습니다.&lt;/p&gt;
&lt;h3&gt;Brevity bias &amp;#x26; Context collapse&lt;/h3&gt;
&lt;p&gt;저자들은 이러한 &lt;strong&gt;context adaptation&lt;/strong&gt; 과정에서 &lt;strong&gt;brevity bias&lt;/strong&gt;와 그로 인해 발생하는 &lt;strong&gt;Context Collapse&lt;/strong&gt; 문제를 꼬집습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Brevity bias&lt;/strong&gt; : AI Agent들의 간결함을 추구하는 경향&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Context collapse&lt;/strong&gt; : Brevity bias로 인해 반복적으로 context를 re-write하다가 디테일한 부분이 사라짐&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;즉, 요즘의 AI Agent들이 context를 최신화하며 업데이트하는 과정에서 간결성을 추구하는 경향이 있다보니, re-write하는 과정에서 디테일한 context가 사리지고 이게 Agent들의 성능 하락에 영향을 미친다는 것입니다.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1500px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/35c46657d1854739e68255433fa3ec22/6ffd1/brevity_bias.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 40.2%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABPUlEQVQoz3VSa2/DIAzM//97rdqmHzZpbVNIIItIeAa4yW6zp2bpdBiwzzY0tVaQ5ZwxjiPmeWaf9jeUUiClxO12w6AV1hhRS0H9dm+LaTZnC1BKfSUkfmJQCm8vrxg7gdSPyM4/zso/CbXWuN/vzGQlF2SzoPiAYj1ACAmgBLmguPAlSDmeBfxIKISA0grIBdVYwAfU2QJrxhoTQoyIKT2qsh41Z1QfWeBPhdRqiAGT1ljkACkEZN9DSAmlNYwxOLdnXK9XLMuCOLwjTQbrbHnG2ywb/LIQAhZruWKCGgZcLheeL6HrOk4+GwPnPaxzLLBZk1LCuq6I1E6McM59+vTytJ6mCX3fcxfE1loW9s7Be88xxHS3obntdju0bYv9fs9r4sPhwHw8HvnsdDrxo9G3IgECCRDTd6NuSOgDeO9o3NO3umEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;brevity bias&quot; title=&quot;brevity bias&quot; src=&quot;/static/35c46657d1854739e68255433fa3ec22/6ffd1/brevity_bias.png&quot; srcset=&quot;/static/35c46657d1854739e68255433fa3ec22/0eb09/brevity_bias.png 500w,
/static/35c46657d1854739e68255433fa3ec22/1263b/brevity_bias.png 1000w,
/static/35c46657d1854739e68255433fa3ec22/6ffd1/brevity_bias.png 1500w&quot; sizes=&quot;(max-width: 1500px) 100vw, 1500px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;실제로 저자들이 context adaptation을 수행했을 때, 위 그래프에서 볼 수 있듯이, step이 누적됨에 따라서 어느 순간 context를 압축하는 경향이 관찰됐습니다. 18,282 token =&gt; 122 token이라는 말도안되는 압축률로요. 그 결과, 오히려 context가 없는 baseline보다도 낮은 Accuracy를 기록하게 됩니다.&lt;/p&gt;
&lt;h2&gt;ACE (Agentic Context Engineering)&lt;/h2&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1502px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/f6474275bbf8da0a202dc25a52a38a4f/e432b/ace_logic.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 42.4%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABgUlEQVQoz3WRW3ObMBCF+f+/yA9+yENju04bzyQTxxgw4lJDMC5gLqIp8HVWNS+dqWZ2jnb36BytZE3TxDhN/Hfde2maEscxYRhSVdW9Nf1DnbBarXE8D9dX+Epxq2uCMKK61YzjaMwEpe75Pr4KyLKMYRiMSNdpVBBS143Jraqu2X5/5mX/zrttc04SFosFQRTzdrDZPH3j4csjruexXm943u143R9YbZ94XG84+T7L5ZIwihnGEavtNNvtV87nM0EYkl+v2Mcjl/xK07ZciwLhDMOI650Io8jkRVmh+55O9xwdh/z68+8NpbharY1I07R0XUdRljRNwzgM9FqTZR/86nu01txuN7qu5ffnJ0VRGN4lz5nu720JZpcLSZqax5YDdV1TVhUqjNi9vJrR9gcbTwVmAuGUZWlQRGU/L0tcxVGcpDEThOyeTkbIdlyDEtITQ+HP5oISomV9ZBmu6+LLD/o+juOglCIIJAJ+xDGBUqRJQhxFJp9FZ+N5sr7v+QN5/1jKb6CmjwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;ace logic&quot; title=&quot;ace logic&quot; src=&quot;/static/f6474275bbf8da0a202dc25a52a38a4f/e432b/ace_logic.png&quot; srcset=&quot;/static/f6474275bbf8da0a202dc25a52a38a4f/0eb09/ace_logic.png 500w,
/static/f6474275bbf8da0a202dc25a52a38a4f/1263b/ace_logic.png 1000w,
/static/f6474275bbf8da0a202dc25a52a38a4f/e432b/ace_logic.png 1502w&quot; sizes=&quot;(max-width: 1502px) 100vw, 1502px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;그래서 저자들은 이러한 &lt;strong&gt;Context Collapse&lt;/strong&gt; 문제를 해결하기 위해 ACE를 제안합니다. ACE는 핵심 아이디어는 ** “Contexts as evolving playbooks” **입니다. Context를 매번 re-write하면서 정보를 잃어버릴게 아니라, 계속 축적하고 구조화함으로써 성능을 개선한다는게 핵심입니다.&lt;/p&gt;
&lt;p&gt;이제 ACE의 구조에 대해서 살펴보겠습니다. 🧐&lt;/p&gt;
&lt;h3&gt;ACE의 세 모듈과 Playbook&lt;/h3&gt;
&lt;p&gt;ACE를 구성하는 세 가지 모듈을 살펴보겠습니다:&lt;/p&gt;
&lt;h4&gt;1. Generator&lt;/h4&gt;
&lt;p&gt;Generator는 들어온 Query에 대한 문제를 해결하는 모듈입니다. 이때 모델이 어떤 정보를 가지고 어떤 생각을 해서 그런 결론이 나왔는지를 모두 기록합니다. 이것을 &lt;strong&gt;Reasoning Trajectory&lt;/strong&gt;라고 합니다. 이 정보를 통해 Generator가 어떤 분석을 했고, 어떤 실수를 하는지를 파악할 수 있습니다.&lt;/p&gt;
&lt;h4&gt;2. Reflector&lt;/h4&gt;
&lt;p&gt;Reflector는 Generator가 생성한 &lt;strong&gt;Reasoning Trajectory&lt;/strong&gt;를 분석하고 insight를 생성합니다. Generator가 뭘 잘했고, 뭘 못했는지에 대한 insight를 반복해서 학습하며 점점 더 정확한 피드백을 제공합니다. (정확히는 기대)&lt;/p&gt;
&lt;h4&gt;3. Curator&lt;/h4&gt;
&lt;p&gt;Curator는 Reflector가 보낸 insight를 구조화된 형태로 컨텍스트에 기록합니다. 이때 전체 컨텍스트를 다시 쓰는게 아닌, 이번 추론에서 얻은 insight에 대한 부분만 추가/업데이트합니다. 즉, 필요한 부분만 수정하거나 bullet 형태로 새로운 지식을 추가하기만 합니다. 이때 bullet 형태로 기록되는 곳을 &lt;strong&gt;Context Playbook&lt;/strong&gt;이라고 부릅니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;구체적인 예시를 한 번 들어보겠습니다!&lt;/p&gt;
&lt;p&gt;AI Agent가 사용자가 들을 다음 노래를 자동으로 설정하는 태스크를 가정해보겠습니다.&lt;/p&gt;
&lt;h4&gt;0. Input&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Task : 사용자의 청취 기록을 바탕으로 다음 곡 추천&lt;/li&gt;
&lt;li&gt;Song History:
&lt;ul&gt;
&lt;li&gt;“Bohemian Rhapsody” (100% 청취)&lt;/li&gt;
&lt;li&gt;“Stairway to Heaven” (95% 청취)&lt;/li&gt;
&lt;li&gt;“Despacito” (5% 청취)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Playbook:
&lt;ul&gt;
&lt;li&gt;[str-00001]helpful=5 harmful=0 :: 가장 최근 들었던 노래와 같은 장르 추천&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;1. Generator&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Reasoning:
1. 사용자가 최근에 들은 곡 확인...
2. Playbook을 보니 최근에 들었던 노래와 같은 장르 노래를 추천해주는게 좋을 것 같음
3. Despacito와 같은 장르 곡 추천&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;추천곡 : “Bailando”&lt;/li&gt;
&lt;li&gt;피드백 : 10% 청취 후 스킵 (harmful)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2. Reflector&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generator의 reasoning 과정&lt;/li&gt;
&lt;li&gt;추천곡 : “Bailando”&lt;/li&gt;
&lt;li&gt;피드백 : 10% 청취 후 스킵 (harmful)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Process:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;reasoning&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &quot;Generator가 &apos;최근 곡&apos;인 Despacito를 기준으로 판단했는데&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                실제로 사용자는 그 곡을 &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;% 청취 후 스킵했음.
                이건 사용자가 싫어하는 신호인데 오히려 비슷한 곡을 추천했음.
                반면 Bohemian Rhapsody와 Stairway to Heaven은 거의 끝까지 들었는데
                이 곡들은 클래식 록 장르임.&quot;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;error_identification&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;낮은 청취율(5%)의 곡을 선호 신호로 잘못 해석&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;root_cause_analysis&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &quot;단순히 &apos;최신&apos;만 보고 판단했고&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
                          청취 완료율이라는 중요한 피드백 신호를 무시함&quot;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;correct_approach&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &quot;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;) 청취율 &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;% 이상인 곡들만 선호 곡으로 판단
                       &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;) &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;% 미만인 곡들은 비선호로 판단
                       &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;) 선호 곡들의 공통 장르/아티스트 패턴 찾기
                       &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;) 그 패턴에 맞는 새로운 곡 추천&quot;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;key_insight&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &quot;청취 완료율이 추천의 핵심 신호다.
                  - &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;%+ = 강한 선호
                  - &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;%- = 강한 비선호
                  최근성보다 청취 완료율을 우선해야 함&quot;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Key lesson : “청취 완료율이 추천의 핵심 신호다. ~ 최근성보다 청취 완료율을 우선해야 함”&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;3. Curator&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Playbook:
&lt;ul&gt;
&lt;li&gt;[str-00001]helpful=5 harmful=0 :: 가장 최근 들었던 노래와 같은 장르 추천&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reflector insight : “청취 완료율이 추천의 핵심 신호다. ~ 최근성보다 청취 완료율을 우선해야 함”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Process:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
	&lt;span class=&quot;token property&quot;&gt;&quot;reasoning&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &quot;Reflector가 중요한 패턴을 발견했다. 
				  청취 완료율이 추천 정확도의 핵심 신호라는 것. 
				  이건 Playbook에 없는 완전히 새로운 전략이므로 추가해야 함.
				  Playbook &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;str&lt;span class=&quot;token number&quot;&gt;-00001&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;에 대한 harmful 점수 업데이트 필요&quot;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
	&lt;span class=&quot;token property&quot;&gt;&quot;operations&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; 
		&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
			&lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ADD&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
			&lt;span class=&quot;token property&quot;&gt;&quot;section&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;music_recommendation_strategies&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
			&lt;span class=&quot;token property&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &quot;청취 완료율로 선호도 판단 
						- &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;% 이상 청취&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; 강한 선호 신호 
						- &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;% 미만 청취&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; 강한 비선호 신호 
						- 최근성보다 청취율을 우선순위로 
						- 선호 곡들의 공통 장르/아티스트 기반 추천&quot; 
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
			&lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;UPDATE_COUNTER&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// ← 이 부분 수정&lt;/span&gt;
			&lt;span class=&quot;token property&quot;&gt;&quot;bullet_id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;str-00001&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
			&lt;span class=&quot;token property&quot;&gt;&quot;counter&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;harmful&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;token property&quot;&gt;&quot;increment&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; 
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; 
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[str-00001] helpful=5 harmful=1 :: 
	- 가장 최근 들었던 노래와 같은 장르 추천
[str-00002] helpful=5 harmful=0 ::
	- 청취 완료율 기반 필터링 
	- 80%+ 청취 = 선호 곡으로 분류 
	- 20%- 청취 = 비선호 곡으로 분류 
	- 최근성 &amp;lt; 청취 완료율 (우선순위) &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;p&gt;간단한 “플레이리스트 다음 곡 추천”이라는 주제를 예시로 ACE의 동작을 살펴봤습니다! 이해하시는데 도움이 됐으면 좋겠습니다.&lt;/p&gt;
&lt;h2&gt;ACE의 핵심 포인트&lt;/h2&gt;
&lt;h3&gt;Incremental Delta Updates&lt;/h3&gt;
&lt;p&gt;저자들이 계속 강조하는 포인트입니다. ACE는 전체 컨텍스트를 매번 재작성하는게 아니라, 필요한 부분만 국소적으로 수정 및 추가함으로써 &lt;strong&gt;Context Collapse&lt;/strong&gt;를 방지합니다. 또한, 매번 Context를 다시 쓰는게 아니므로, 불필요한 토큰 사용량을 줄임으로써 계산 비용을 절감합니다.&lt;/p&gt;
&lt;h3&gt;Grow-and-Refine&lt;/h3&gt;
&lt;p&gt;예시를 든 위 상황이 온라인에서 계속 반복된다면, Playbook에는 지속적으로 context가 쌓일 수 밖에 없습니다. 이때 semantic embedding 등으로 비슷한 bullet은 삭제하거나 통합하고, harmful이 높은 경우 삭제하는 등 rull-base로 playbook의 총량을 컨트롤합니다.&lt;/p&gt;
&lt;h2&gt;그래서 얼마나 좋은데?&lt;/h2&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1824px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/f1a0ea2d4b7da28fdaef89bd1d0a2707/955c5/ace_result.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 44.99999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB7ElEQVQoz1WSz2sTQRTH+x969SAevHkrohQq9lg9igc1KiiFotSIYCtI1OZUobYYSdLWLU3TrJrEbTOZnZ39/eMjM6kUH7x9zId9b77f3TdXVRVlWWKqUgrP85C+TwnkeW7ZZDKxeXp6SlEURFGEEMIyW4UgyzJMzJmHaTIvGpgVJdL7TffzG9IsJ0tTUpNJQhzHJOc1PeemJ1A+URjOBhp1WmurEioLR709GvdvUFRQWV5aPj7q0P6wOjtVlXVl4mCzzt6n17OB5obRaDSzDaRJxtazZZq1JfLSNEFWYFW1NlbYWrnHv4jVxPZ0Gq/4vv78QqGxnKUJYtzh17ePbCxeoVm7Q15CoM7wnHc4a8us377KTv0hWVmRFCB7u5w0ajSf3qXbeHnxDYNAMxUe7pdbOKs3eb90jc1Hi2QlCM/hpHmdvRcLvF24zPbaA9ISpHAZ7jyh9XietflL7G/W//8pWgf4Xhcx6DI8aHE2cNBhRKglctRGnOzzs7vLdNgnTnK0GjFxtxGDH7jtr2jxZzYwDEOklEynkolQTP0AX4f4gbZroVRAoBNUGBMlGTqMkXKKrzRKpygdEVoe2U2ZG4/H9Ho9XNfl8NChd3TEoePYPD4+pt/vW+4OBgTBzIkRYV0FCl9Ky33ftwP/AlXJlxfS+5IXAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;ace result&quot; title=&quot;ace result&quot; src=&quot;/static/f1a0ea2d4b7da28fdaef89bd1d0a2707/955c5/ace_result.png&quot; srcset=&quot;/static/f1a0ea2d4b7da28fdaef89bd1d0a2707/0eb09/ace_result.png 500w,
/static/f1a0ea2d4b7da28fdaef89bd1d0a2707/1263b/ace_result.png 1000w,
/static/f1a0ea2d4b7da28fdaef89bd1d0a2707/955c5/ace_result.png 1824w&quot; sizes=&quot;(max-width: 1824px) 100vw, 1824px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;ACE는 기존 context adaptation 기법들 대비해서 우수한 성능을 보였습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AppWorld LLM Agent Benchmark : 기존 베이스라인 대비 평균 10.6%의 정확도 향상&lt;/li&gt;
&lt;li&gt;FiNER (금융 분석 벤치마크) : 적응 지연 시간을 평균 86.9%로 단축, 토큰 사용량, 롤아웃 횟수 크게 감소&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;즉, 기존 방법들 대비 많이 좋아졌다고 합니다.&lt;/p&gt;
&lt;h3&gt;Ablation Study&lt;/h3&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1076px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/a132799730aaf1cbcca8ad030422da71/1e0c2/ace_ablation.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 45.2%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABWElEQVQoz1VS2W7DMAzL/39ggRY5HNuNr1y9lqRdy4HKEmwPhCwZImnJ2fv9xuPxENzv939g7Xa77eeu6xBjlNr1epVzSkly3j+fT2Sfzwdaa7lkYZomzPMscVkWDMMg92wsyxLH4xHn81lwOp1wOBykt65rEc7okMpspOqmzjiOo5CQkCjyAt773Rl72rYVMJ++ppUwhLAXnXPSsDUyWmtRFIWQC0HXIrUJ/dBL3vc9QgzyIiFUSqGqqh3M6ZpOOQaCuXYajWtgokWlK8QxQhkFGyxKXWL6nldCOqMbPpEqnN82S9aaphGR2tSruy6tDscBMUXJ6XBefgk5UDYYY+TJBN2RlIOmGJdAV847WG+hjYZvPZRWktPp1zIhoyMSEdxanucCCjByGSSjS2MNKlWh1qsBkrLOuG/59XrtS6EznrmIbTnM/0bekST4gBSTjIu1y+UCfsEfqt+jKte3peEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;ace ablation&quot; title=&quot;ace ablation&quot; src=&quot;/static/a132799730aaf1cbcca8ad030422da71/1e0c2/ace_ablation.png&quot; srcset=&quot;/static/a132799730aaf1cbcca8ad030422da71/0eb09/ace_ablation.png 500w,
/static/a132799730aaf1cbcca8ad030422da71/1263b/ace_ablation.png 1000w,
/static/a132799730aaf1cbcca8ad030422da71/1e0c2/ace_ablation.png 1076w&quot; sizes=&quot;(max-width: 1076px) 100vw, 1076px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;좋아졌다면, 왜 좋아졌는지를 파악하는게 중요합니다. 그렇기 때문에 Ablation Study를 꼭 확인해야되는데, 저자들이 이를 잘 실험해줬습니다!&lt;/p&gt;
&lt;h4&gt;Reflector &amp;#x26; Multi-Epoch&lt;/h4&gt;
&lt;p&gt;위 Table 3에서 볼 수 있듯이 reflector와 multi-epoch이 없을시에 성능이 하락했습니다. 즉 Reflector의 insight가 성능 향상에 기여했다는 것이며, 한 번만 학습하기보다는 여러 epoch에 걸쳐 반복 학습해주며 Playbook을 점진적으로 정제하는것이 성능 향상에 도움이 됐다고 합니다.&lt;/p&gt;
&lt;h4&gt;Offline Warmup&lt;/h4&gt;
&lt;p&gt;Playbook이 빈 리스트인채로 온라인에서 적용하기보다는, 훈련 데이터로 먼저 Playbook을 어느정도 구축한 후에 온라인에서 적용하는 것이 효과적이였다고 합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;이 논문이 제시하는 방향&lt;/h2&gt;
&lt;p&gt;결국 이 논문에서 가장 중요한 것은 ACE가 제안하는 방향인 것 같습니다. 모델을 학습하며 domain adaptation을 하는 방향이 아닌, Context를 조절하면서 Self-Improving Agent가 되어야하며, 이때 컨텍스트 전체를 re-write하는 위험성 높은 방향이 아니라 시간과 경험을 통해 하나씩 축적하고 수정해나가는 방향이어야한다는 것입니다.&lt;/p&gt;
&lt;p&gt;사람도 기존 지식에 하나씩 새롭게 추가해가면서, 기존 지식의 잘못된 부분을 업데이트 해나갑니다. 사람들이 각자가 가진 경험(Context) 전체를 re-write 한다면 너무나 risky한 것처럼, AI Agent 역시 조금씩 수정해나가며 성능을 개선해나가야 한다는 것입니다.&lt;/p&gt;
&lt;p&gt;지금 ACE가 제시한 방법이 최선의 방법은 아니겠지만, 전체적인 방향성에 많은 공감이 됐습니다.&lt;/p&gt;
&lt;p&gt;이 방향성에서 어떤 부분을 어떻게 개선할 수 있을지에 대해서 앞으로 고민을 해봐야겠습니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[MoE(Mixture of Experts) 기초부터 DeepSeek 혁신까지]]></title><description><![CDATA[MoE(Mixture of Experts) 기초부터 DeepSeek 혁신까지 작년 이맘때쯤 DeepSeek-V3가 저비용으로 엄청난 성능을 보이면서 화제가 되었습니다. 그 핵심 기술인 MoE(Mixture of Experts…]]></description><link>https://sooftware.github.io/developed-moe/</link><guid isPermaLink="false">https://sooftware.github.io/developed-moe/</guid><pubDate>Thu, 15 Jan 2026 01:11:55 GMT</pubDate><content:encoded>&lt;h1&gt;MoE(Mixture of Experts) 기초부터 DeepSeek 혁신까지&lt;/h1&gt;
&lt;p&gt;작년 이맘때쯤 DeepSeek-V3가 저비용으로 엄청난 성능을 보이면서 화제가 되었습니다. 그 핵심 기술인 MoE(Mixture of Experts)에 대해서 어떻게 발전시켰는지 살펴보겠습니다.&lt;/p&gt;
&lt;h2&gt;1. MoE란?&lt;/h2&gt;
&lt;h3&gt;핵심 아이디어&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;기존 트랜스포머 구조처럼 모든 파라미터를 항상 사용하지말고, 입력에 따라 선택적으로 활성화해서 쓰자!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;부분적 활성화&lt;/strong&gt;는 MoE의 핵심입니다. 기존 Dense Model처럼 모든 토큰 생성마다 모든 파라미터를 전부 사용하는게 아니라, 각 토큰별로 전문가(Expert)를 두고 선택적으로 활성화하자는 겁니다.&lt;/p&gt;
&lt;h2&gt;2. 기본 MoE 구조&lt;/h2&gt;
&lt;h3&gt;Transformer에서 MoE 적용&lt;/h3&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1081px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/e35ee3338f574bcbacd9958e6f7982af/0c139/ffn-moe.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 51%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAABzUlEQVQoz22S3W6jMBSE8/6vtJft7kW3arP5awI0ZBNogBAMCcE22Hwr07RKqx3pyJZ1PJpzZkZ93/O9HG7vDrWUpMcj3fXNnYei4FTX3GL0+fGGoOs6tNYY06GVGipfv7J7fqZcv1KGa6pNSPxnTBr4qGuP+z8a1AD2Sta27UDm4BpFrTicFdv1lnDhke327IINb2GEP1mwCyPyWnOsaowxjNosRSzmvI2fuQQ+3eXyKV9KSXKSBFnN42rLbJcTloborHkKYlbJiVVyxk9OxMV5mGx0riWbTYznh6SZoOvsVbMjVOzLC+lZElcN06igbHsKZRGqZRoJ4pMibzRRXtF1hpFKE7LJmL+PD5x8D6sVH1YoqUgrSS4t27Lmx3TBQVly1VNZuF8FLJMM0cJe1BinsG/2VG9PRN5PTLnCds3nyK3WiLLkKCpSz6d6WVCufJLpjMPihWq5JHtZkhcCIUqstc4UizEaKd3uLFqrYRcfO2xbjbU9to7Rhwk6n5P4v5DZDFPMUUcPaw1N07yb0vMVzmznsiN15Zx2FQRLkmTndGOMpBQHwtCjaaqh3xEOCv8X6o8s3iKKYh5+P3Jp5HvQ6wt3d/cEweuXYP8Deuj9tBFyijAAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;ffn moe&quot; title=&quot;ffn moe&quot; src=&quot;/static/e35ee3338f574bcbacd9958e6f7982af/0c139/ffn-moe.png&quot; srcset=&quot;/static/e35ee3338f574bcbacd9958e6f7982af/0eb09/ffn-moe.png 500w,
/static/e35ee3338f574bcbacd9958e6f7982af/1263b/ffn-moe.png 1000w,
/static/e35ee3338f574bcbacd9958e6f7982af/0c139/ffn-moe.png 1081w&quot; sizes=&quot;(max-width: 1081px) 100vw, 1081px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;전통적인 Transformer의 FFN(Feed-Forward Network) 레이어를 MoE로 교체합니다.&lt;/p&gt;
&lt;h4&gt;Mixtral 8x7B 예시&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;8개의 experts (각 7B 파라미터)&lt;/li&gt;
&lt;li&gt;토큰당 2개만 선택 (Top-2 routing)&lt;/li&gt;
&lt;li&gt;총 47B 파라미터 중 활성 13B&lt;/li&gt;
&lt;li&gt;FFN layer만 MoE로 교체, attention은 shared&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3. DeepSeek의 혁신 ①: Fine-Grained Expert Segmentation&lt;/h2&gt;
&lt;h4&gt;문제 인식&lt;/h4&gt;
&lt;p&gt;기존 MoE(ex. Mixtral)의 한계:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;8개의 expert 중 2개 선택
→ 조합의 경우의 수: 28가지
→ 제한적인 유연성&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;해결책 : Expert를 더 여러개로 나누기&lt;/h4&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/ede4e2c2c9e86e2000e11ebd764ba9a6/03ffe/finegrained-segmentation.jpg&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 49.8%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAAKABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAQCBQYJ/8QAFQEBAQAAAAAAAAAAAAAAAAAAAQD/2gAMAwEAAhADEAAAAe6aEKgNGPk//8QAGxAAAgIDAQAAAAAAAAAAAAAAAQQCAwAFERP/2gAIAQEAAQUCkw0LouNyzXw6taB6NARp1Z6h/8QAGBEAAgMAAAAAAAAAAAAAAAAAARCBodH/2gAIAQMBAT8Bk1i//8QAGxEAAQQDAAAAAAAAAAAAAAAAkQEQESFhodL/2gAIAQIBAT8BvAXo6hv/xAAkEAABAgYBBAMAAAAAAAAAAAABAgMAERITISJhBDEyQVFxgf/aAAgBAQAGPwJ1tKQpYTUlq62JIrWEu1W8VappVOXJBh5NCCG3HELcvtotSHiqbNJo22AzjtCDZHYSUOqcXckhILm2UzUDrxP3BwNntseW3v5/YcCRIBt0gDGaDn75jpyc6CP/xAAbEAEAAgMBAQAAAAAAAAAAAAABESEAMUFRYf/aAAgBAQABPyF0eUq7nZSh26AbyrUJrzZImiVLmvhhQ7IQTZCljJ3AYUARz5W1Lb7hACUgGqQgE7F/cZIpmVlqi35Wf//aAAwDAQACAAMAAAAQbC//xAAeEQACAAYDAAAAAAAAAAAAAAABEQAhMUFxoYGx0f/aAAgBAwEBPxBaOr85mzOMUs1TgAaEf//EABkRAQEBAQEBAAAAAAAAAAAAAAERITEAQf/aAAgBAgEBPxBpOQdlU+CqKvQaYO/AwrsLMKSwVgpysqV9/8QAGRABAQEBAQEAAAAAAAAAAAAAAREhAEFh/9oACAEBAAE/EHG7n0BLAq6R6fSd+l0RrWshHDyiuGtw4/bjaghM1mApHASXwVJVSeYwehwQQDSqet7qZ/QisAK4AGB3/9k=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;finegrained segmentation&quot; title=&quot;finegrained segmentation&quot; src=&quot;/static/ede4e2c2c9e86e2000e11ebd764ba9a6/03ffe/finegrained-segmentation.jpg&quot; srcset=&quot;/static/ede4e2c2c9e86e2000e11ebd764ba9a6/953fe/finegrained-segmentation.jpg 500w,
/static/ede4e2c2c9e86e2000e11ebd764ba9a6/0a251/finegrained-segmentation.jpg 1000w,
/static/ede4e2c2c9e86e2000e11ebd764ba9a6/03ffe/finegrained-segmentation.jpg 1200w&quot; sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;Expert 수를 늘리고, 선택의 경우의 수도 늘리되, 계산량은 유지:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[기존 Mixtral] 
8개 expert, 2개 선택 
각 expert = 7B 파라미터
 → 14B 활성화 
 
 [DeepSeek Fine-Grained] 
 32개 expert, 8개 선택 (4배씩 증가) 
 각 expert = 1.75B 파라미터 
 → 14B 활성화 (동일!) 
 → 조합의 경우의 수: 🆙&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Multi-Head Attention과의 유사성&lt;/h4&gt;
&lt;p&gt;이 개념은 개인적으로 &lt;strong&gt;Single-head Attention → Multi-head Attention&lt;/strong&gt;과 유사하게 느껴집니다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;구분&lt;/th&gt;
&lt;th&gt;Single → Multi&lt;/th&gt;
&lt;th&gt;Coarse → Fine-Grained&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;나누기&lt;/td&gt;
&lt;td&gt;1개 → 8개 head&lt;/td&gt;
&lt;td&gt;8개 → 256개 expert&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;활성화&lt;/td&gt;
&lt;td&gt;모두 사용&lt;/td&gt;
&lt;td&gt;일부만 선택&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;효과&lt;/td&gt;
&lt;td&gt;다양한 attention 패턴&lt;/td&gt;
&lt;td&gt;다양한 expert 조합&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;이처럼 기존의 덩어리를 더 작지만 여러개로 나누면서 &lt;strong&gt;성능 향상&lt;/strong&gt;이라는 효과를 얻었습니다.&lt;/p&gt;
&lt;h2&gt;4. DeepSeek의 혁신 ②: Shared Expert Isolation&lt;/h2&gt;
&lt;h4&gt;문제 인식&lt;/h4&gt;
&lt;p&gt;Fine-grained로 expert를 잘게 쪼갰더니 새로운 문제 발생:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;여러 expert가 같은 기본 지식을 중복해서 학습&lt;/li&gt;
&lt;li&gt;파라미터 낭비..&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;원인 :&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;각 expert가 독립적으로 학습하다보니 다들 공통 지식을 각자 배움&lt;/li&gt;
&lt;li&gt;공통 지식을 배우다보니 특화된 지식을 배울 공간(파라미터)이 부족해진다는 단점&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;해결책 : 공통 지식을 따로 빼자!&lt;/h4&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 779px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/ac1e43f2a0e5d4f9f4c2d4acceed8a00/a3e85/shared-expert.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 65.4%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAACRUlEQVQ4y4WT30/TUBTH+Td99x8x8c34YEIwEAwILgY2F0eGD8agMcGHCS44XNut3VbSsrXd2rWsW3/uY1ocDIh6kntP7809n557zveuzOdzMlv4zMIoJJiG/FBqvP72kp2vG+zW1ukaCv+yjLGyDMu853m4rkuSQk+oU916RmXrOZ/evkDvtYniBMuyEEWRer3O6ekphmHcArNpARyPHYJgln8nwFBqoR18QCofYB5+5Eq/5Go65UJVOTo64rzRQBCEHD6bXcetLGCTyYRZENyk77guhiQiV97TKL/j4rCK2ekgtmVGwyGapjG/d92bDIMgyIFpHBL7Dmk4xfE8RrJMq1SiUSzSKZeZmSaqpuG6HkPLQmkJmNbwbg3jOEbtdRn7IZe1EsqrR3QrTxDaCqYkoVQqnJVKXFSrjLpdmpLEz18ivc+bKDuPGZsatuPm5cqBaZqSxHH+h+mghX78Blv4gjGyMUSR1t4e9UIBeX8fX9dpKTKGZdOvH6JWn+LZJiPbwXGc2y5fp5vm/mp2DfeDAK3RQCwUqO/u0isWkb6fcC6I/5TOTZcXzXHdMUkckeGtZpPm2hq11VU6m5voZ2coqpqfS9ME5inL8Xd0uABmOkyThHQ+x7dtnHYbtVbDUxTGpkmn2+V+zPKjWFleLIALy2obhyFuv08ax/i+T6fTeQB5cGXTNBkMBui6Tr/fx880GUV5DU82NjheX6exvY3ebtOS5f8DoyjKtZiNMAzzke2F2d5kQuj7BL6fv4bgj/j/BvwNDzrOP0Nj28gAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;shared expert&quot; title=&quot;shared expert&quot; src=&quot;/static/ac1e43f2a0e5d4f9f4c2d4acceed8a00/a3e85/shared-expert.png&quot; srcset=&quot;/static/ac1e43f2a0e5d4f9f4c2d4acceed8a00/0eb09/shared-expert.png 500w,
/static/ac1e43f2a0e5d4f9f4c2d4acceed8a00/a3e85/shared-expert.png 779w&quot; sizes=&quot;(max-width: 779px) 100vw, 779px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;&lt;strong&gt;Shared Expert&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;항상 활성화하는 Expert를 따로 둠으로써, 이 expert가 공통 지식을 담당→ 파라미터 효율 증가&lt;/li&gt;
&lt;li&gt;나머지 Expert들의 특화도 증가 : 나머지 Expert들은 공통 지식을 제외한 특화 지식에만 집중되도록 학습&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;5. Expert는 어떻게 특화되는거지?&lt;/h2&gt;
&lt;p&gt;여기서 놀라운 사실인데, 따로 특화시키지 않습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;연구자가 하는 것:
❌ &quot;너는 수학 expert야!&quot;
❌ &quot;너는 코드 expert야!&quot;
❌ Expert별로 다른 데이터 주기

실제로 하는 것:
✅ 그냥 전체 데이터로 같이 학습
✅ Router와 Experts를 end-to-end로 학습
✅ 알아서 특화됨!&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;랜덤하게 초기화 된 Expert들은 학습이 되면서 자연스럽게 수학에 강한 Expert, 코딩에 강한 Expert와 같이 나뉘어지게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;실제 Mixtral 8x7B 분석 결과:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Expert 0: 코드 관련 토큰에 강하게 반응 
Expert 2: 수학 수식에 강함 
Expert 5: 프랑스어에 특화 
Expert 7: 범용적 (다양한 토큰)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;6. Load Balancing&lt;/h2&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 649px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/31f9e3519f7670549d2a990711cb5e99/1bcec/load-balancing.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 71.8%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAC4ElEQVQ4y42TS28cVRCF/fMQ/4MNgh0IwRoWWSKEZIgEzAqEEEpC7AQciCNMHNvxY2b8mumxu6f7Prp7pqdf0495eD7UFyE7CyRqU1e36p66VefUGkAcx0ipUNrHEwqtfaTUuJ5ECIVtD0mTlMVsRpGm/JetVivWmoNSmjSbEo5T/nzVxxYRwo/J84JpUSOVT5pmLJdLkjhGex55npPnmfFZllGWpQE1gL4fMC0q4qzg52cdnuxa9IcjPDFCqAjbkeaR1pqL40POD/YIfc0o9BkFGiU9ho59C6iUz3K5YHPrmPc/afHexy2+uP+Usqqp6gVBOCaOE7Jpzub6lzjdDtcHf6B6bao8Jo8CfK3u/DAIiCYZZ5cejzYP2Pj1kJ4lTbtFWaP90ACmecbGV+t0nj/h6HGL3qtt5GCAc36KbfVvAcMwpGcJBteaS0tw5fgmeLq7Q2//Be2d3w1xSZbx8N6H3H/nLb57922s3S2WNzfkSYRW8hawYXU2m+PJMV//8JLttoccZcirAd3DE6yzDmmWEfqK1w+/5afPPuDBvY+wj15ws1pRTpv5qjdJyacFV8OAT9e3+eZxl7blswImaY3j+mRZTuBr4kAQSYeRd00SSpJAEikXJdxbwCAISJKcgRvy/fM+n/94wKOtDpYluOgJ+taQeDIxbQ0OnnG58wvW3m9M04jA6SH7XeRdQO0HVFXNUES0Nrq0nnbYO7lmPl9Q1nPDciObRnPCdTh//RcXhy/pnewzOGujpGQymdyRjf5H2FleYrshjhxTVDPqemZYVjowLP9rZRZTJBPycWAkc7NcvrkpTfVGOp6n2Ns/5eTkkqPjC9qdHqPRCCEldV3zf2ytSVyaCiuzarajCcIYrSN8f8JiMTfx2WzGYrGgrmrKoqAqS6qqoq4q45u7JmfNHQ4RQuDYDp7rmuF6notWAikFtm3jeR79Xt/EGz1OoogoikiShOl0anwUjc2+/w0I0QjJCAKqgwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;load balancing&quot; title=&quot;load balancing&quot; src=&quot;/static/31f9e3519f7670549d2a990711cb5e99/1bcec/load-balancing.png&quot; srcset=&quot;/static/31f9e3519f7670549d2a990711cb5e99/0eb09/load-balancing.png 500w,
/static/31f9e3519f7670549d2a990711cb5e99/1bcec/load-balancing.png 649w&quot; sizes=&quot;(max-width: 649px) 100vw, 649px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;h4&gt;문제 인식&lt;/h4&gt;
&lt;p&gt;Expert가 자연스럽게 특화되는 건 좋지만, 문제가 생깁니다.&lt;/p&gt;
&lt;p&gt;256개의 Expert 중 N개의 Expert만 운 좋게 초반에 잘 맞추게 된다면, 해당하는 N개의 Expert들만 집중적으로 학습되게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;문제점:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;나머지 256 - N개의 expert 파라미터 낭비&lt;/li&gt;
&lt;li&gt;N개의 expert에 과부하&lt;/li&gt;
&lt;li&gt;다양성 X&lt;/li&gt;
&lt;li&gt;256개로 나눈 의미가 없어짐&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Auxiliary Loss 도입&lt;/h3&gt;
&lt;p&gt;이러한 문제점을 해결하기 위해 Auxiliary Loss를 도입했습니다. Auxiliary Loss는 N개의 숫자가 있을 때 다양하게 선택이 되도록 학습되는 Loss입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Total Loss&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;total_loss = main_loss + λ * aux_loss = &quot;정답 맞추기&quot; + &quot;골고루 쓰기&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;그래서 MoE 구조에서 처음에는 이렇게 Auxiliary Loss를 도입해서 load balancing 문제를 해결했습니다.&lt;/p&gt;
&lt;h3&gt;Auxiliary Loss의 문제점&lt;/h3&gt;
&lt;p&gt;위 Total Loss 수식에서 보듯이, 전체 로스에서 Auxiliary Loss가 더해지게 됩니다. 여기서 문제가 생기는데,&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;딜레마:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;λ 크게 설정: 골고루 쓰지만 성능 나쁨&lt;/li&gt;
&lt;li&gt;λ 작게 설정: 성능 좋지만 불균형 심각&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;위와 같은 딜레마가 생기게 됩니다.&lt;/p&gt;
&lt;h2&gt;7. DeepSeek의 혁신 ③: Auxiliary-Loss-Free&lt;/h2&gt;
&lt;h4&gt;핵심 아이디어&lt;/h4&gt;
&lt;p&gt;꼭 Auxiliary Loss로 해야해? 라우팅만 골고루 하게 하면 되는거 아니야?&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;기존 방식에서는 router가 expert들을 골고루 선택하게 하기 위해 Auxiliary Loss를 도입했는데, DeepSeek에서는 이거를 bias control로 loss 없이 구현해냈습니다!&lt;/p&gt;
&lt;p&gt;매 N-step마다 expert들의 사용량을 체크하고, 상대적으로 많이 사용되는 expert의 bias는 -하고, 적게 사용되는 expert의 bias는 +하는 방식으로 컨트롤합니다.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1200px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/31078f1e5aaa98d931f3a37147bfe73e/03ffe/auxiliary-loss-free.jpg&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 62%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAAMABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAcDBAYJ/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/2gAMAwEAAhADEAAAAe70a4pQ7zOlf//EABwQAAICAgMAAAAAAAAAAAAAAAIDAQQFFBUhM//aAAgBAQABBQJvs1O3C+gnJXZPkbglUNxp/8QAGREAAgMBAAAAAAAAAAAAAAAAEcEQUWHh/9oACAEDAQE/AXa6cEf/xAAZEQACAwEAAAAAAAAAAAAAAAAR4RAxYcH/2gAIAQIBAT8B5TQ0x//EACcQAAIBAgUDBAMAAAAAAAAAAAECIQMRABITMVEjQWEEIjJScXOB/9oACAEBAAY/AnzpmtpaYR7M1zJO2zdiWXKL2E4K1NWiqNGizUqjH9gsCDwsTvwomBb3S39Pc8nDdbYso6Pp9s1TmkfqPHjDWqic5PRoGRIM0zaZiwv2wrNWYk2PwogC6LAC0hH5ufOP/8QAGhABAQEAAwEAAAAAAAAAAAAAAREhADFBUf/aAAgBAQABPyFbYOM0BlpcfQAod9iWD3AMQRGm5wQbMFsBQtsexVdr3y2nZXY9FfctStcHBmxo8wkNjYXgy0yBqZnKqeiYAP/aAAwDAQACAAMAAAAQ3M//xAAaEQEBAAIDAAAAAAAAAAAAAAABEQBBITFh/9oACAEDAQE/EBAYF4KLA8yLtr1suf/EABkRAQEAAwEAAAAAAAAAAAAAAAERACExQf/aAAgBAgEBPxBrBWJQKVZd1oSh1XzDP//EABkQAQEAAwEAAAAAAAAAAAAAAAERACExQf/aAAgBAQABPxCOg3dXF1SfE8as86qrtLRGGNrPmTikyYgAAGpGtsdMDI71QeCoSpnOegkpIBiqLQExwQeHRCobTyv/2Q==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;auxiliary loss free&quot; title=&quot;auxiliary loss free&quot; src=&quot;/static/31078f1e5aaa98d931f3a37147bfe73e/03ffe/auxiliary-loss-free.jpg&quot; srcset=&quot;/static/31078f1e5aaa98d931f3a37147bfe73e/953fe/auxiliary-loss-free.jpg 500w,
/static/31078f1e5aaa98d931f3a37147bfe73e/0a251/auxiliary-loss-free.jpg 1000w,
/static/31078f1e5aaa98d931f3a37147bfe73e/03ffe/auxiliary-loss-free.jpg 1200w&quot; sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;이 단순한 방식으로 DeepSeek은 load balancing 문제를 풀었습니다.&lt;/p&gt;
&lt;p&gt;Auxiliary Loss 도입으로 인해 전체 학습에 방해가 되니, 이를 간단한 bias control로 gradient에 영향이 없도록 하여 성능을 개선했습니다!&lt;/p&gt;
&lt;p&gt;실제로 이러한 bias 방식을 도입했더니, auxiliary loss를 사용했을때랑 대비해서 expert들간의 불균형도가 조금 높아지긴 했지만, 모델 성능 자체는 더 좋아졌다고 합니다.&lt;/p&gt;
&lt;p&gt;이상으로 DeepSeek에서 MoE 구조를 어떻게 개선했는지 살펴봤습니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Throwback 2025]]></title><description><![CDATA[Throwback 2025 2020년 회고 글 2021년 회고 글 2023년 회고 글 2024년 회고 글 2025년 회고 글입니다! 202…]]></description><link>https://sooftware.github.io/2025/</link><guid isPermaLink="false">https://sooftware.github.io/2025/</guid><pubDate>Thu, 01 Jan 2026 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Throwback 2025&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://sooftware.github.io/2020/&quot;&gt;2020년 회고 글&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sooftware.github.io/2021/&quot;&gt;2021년 회고 글&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sooftware.github.io/2023/&quot;&gt;2023년 회고 글&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sooftware.github.io/2024/&quot;&gt;2024년 회고 글&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2025년 회고 글입니다! 2024년 회고 글을 읽고서 이 글을 작성중인데, 작년 회고 때 다짐했던 운전 연수나 스터디 카페 다니는 걸 실천 못했더군요.. 😅&lt;/p&gt;
&lt;p&gt;곧 해야지.. 곧 해야지.. 하다보니 어느새 2025년이 끝나버렸습니다 😭&lt;/p&gt;
&lt;p&gt;하지만 2025년은 제게 잊지못할만큼 여러 추억을 남긴 해였기 때문에, 회고에 기억나는 순간들을 하나씩 기록해두려고 합니다.&lt;/p&gt;
&lt;h2&gt;회사 생활&lt;/h2&gt;
&lt;p&gt;올해 회사에서 주로 맡았던 작업은 DearMate 서비스 신규 기능 개발 및 전체 구조 리팩토링이였습니다. 작년에는 기존 개발자분들이 작업하던걸 이어받아서 어찌어찌 응급처치를 해두던가 겨우겨우 돌아가게 만들어두는 정도였다면, 올해는 전반적인 구조를 모두 파악하고 어느 부분을 개선해야할지, 신규기능을 구현하려면 어디를 수정해야하는지를 정확하게 파악된 채로 작업하게 됐습니다.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1536px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/20e8867aa4550376733d8988f77b2743/e8464/2025_dearmate.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 66.60000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAADJElEQVQozwEZA+b8ABQYIxgcKRgeLBsfLDAwNzIzOn52cVFQUxMaKRUdMDc3OmNWRBshMBoiNCMsPRgiOBcdLBkdKR0aJA4TIAAVFSEhJzUlMUArMkE4OkVKSEe4q57As6U4QU1RXW1FUForNEB4dnOuqZlWU1R1XUs5OkUtMD8vJi4mHiUAZF9nUEhKQEJHZmpxzsKvnZmGXl5bZ29xRllkTl9za32PXmt0zciyoKOZmY55mYdwYFxjOEBPMTA+dTcnAGRcYFhEQql3S4p6bOPZyvvw1HF6e01bZJOYlamtpnqFi4aEfVlcXVJUWE5QUltXVWNeXzc+SnhKObVbKwA1Ky5nXlyVgG9sYlWKiIqRkJRnY2uEiJT/+ub///Pu7dldW18oKDAnKTASEx04Li2TfXB5WFOzaTTxljgANzE4h3duZ1tZo5NpbHBlYFJWblpak5uq7+jV19fF7OzZZmNjKywzKywuERAfdVw4uYlRr1436rRM9rZIADovMq+ZipSEdklLU2Zqa5KHcltjbnB3hs3Ixquej5KShoWGgXRsXj8/RkE9PJZ9WbaCX96MPv3iYf6xQQBjVVZhSEFTSEgtPltKYYJCVm92goy9ua6jjoallYV8d3KMhXqakHtyaWaDfHVgX1tnSjvqrlju2afXmmMAenZ+wK6erJyMOT1MN0FVVV5riYaSx6eLx7WYrph/spRxooVnuZRuuJZsUlZcFSMvUzs08M+h0cOtmISAADU5TpuRjuzZvsi2n1BOUn94fHhueYhdVr+FXrmGXtSZZ8OPYopfRmVaVlNVXktIQaB5UMqvlIl9eFlUYAAtNElFR1l7cnWYioZZUVNNTFxfVmJYS1FuWFVoU0x9Y1N2YVVxZF50cWl9aFHCpXK3n3+TgXuUh4NJRlMAJSo6MDVJTFBhaWh0aF9ko5eMw7Gft5yByKiIvp990LWOzapyxKd0wqqHn4l0oYFbgHFwuqmco5WNTElWABkdLB4iMysuPjo5RW9sc5eTk3l2fYuGirCmosKyo8Cxo5iHfJ6SiaqgmJ6VkIF5dGZiaVtXXzU0PiYmMQnuUYt8KSiNAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;2025 dearmate&quot; title=&quot;2025 dearmate&quot; src=&quot;/static/20e8867aa4550376733d8988f77b2743/e8464/2025_dearmate.png&quot; srcset=&quot;/static/20e8867aa4550376733d8988f77b2743/0eb09/2025_dearmate.png 500w,
/static/20e8867aa4550376733d8988f77b2743/1263b/2025_dearmate.png 1000w,
/static/20e8867aa4550376733d8988f77b2743/e8464/2025_dearmate.png 1536w&quot; sizes=&quot;(max-width: 1536px) 100vw, 1536px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;그 결과로 올해 DearMate는 글로벌 서비스를 위한 언어 확장(영어, 일본어, 중국어, 아랍어, 스페인어), 오픈채팅방, 전체적인 앱 속도 개선 등 여러 부분의 신규 기능 개발과 사용자 경험을 향상시키기 위한 작업들을 했습니다. 여전히 많은 버그들과 싸웠지만, 그래도 지금은 안정적으로 신규 기능들과 함께 서비스되고 있는 모습을 보며 흐뭇하고 대견스러운 마음도 듭니다!&lt;/p&gt;
&lt;h2&gt;LangChain &amp;#x26; LangGraph 강의&lt;/h2&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 2000px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/c19c511ef4b955c65ec8b6f8febd05d7/d6043/langchain-langgraph.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 35.2%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABEUlEQVQoz5VRS0vDQBjcg//Coyd/g2fpTxM8e2jpQbRU8JlYL42NSFWw9aBYEQpFKFaCaYtN13TdzT5GspgcemkdGAa+XWa+BzHGYBFTzOs8sjrBEsg+a62tBsMQZfcQOwcVuNcNKKnycEJpCG1+MIkoKKWQUoILAcaYJec8N9Z/xnsnZyCFNaxsrmO1sIFwOM6DSX/wgvv2KbrdNzx3Ori5vYN7foGGf4W6d4lW+yHv7juOrfYHH9ivOdgqF1HzfcSM4XM0glIKBAZgs1necpIkEELYx5SpQTbya68Hx/NQcRzsHh2j9fiEerOJ7VIJxWoVX1GU7tAsvcNsHYmUeA8CcMFtbTKd2nB7lP9eeVHwL8wqDjVXSBaEAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;langchain langgraph&quot; title=&quot;langchain langgraph&quot; src=&quot;/static/c19c511ef4b955c65ec8b6f8febd05d7/f97d7/langchain-langgraph.png&quot; srcset=&quot;/static/c19c511ef4b955c65ec8b6f8febd05d7/0eb09/langchain-langgraph.png 500w,
/static/c19c511ef4b955c65ec8b6f8febd05d7/1263b/langchain-langgraph.png 1000w,
/static/c19c511ef4b955c65ec8b6f8febd05d7/f97d7/langchain-langgraph.png 2000w,
/static/c19c511ef4b955c65ec8b6f8febd05d7/d6043/langchain-langgraph.png 2432w&quot; sizes=&quot;(max-width: 2000px) 100vw, 2000px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;저희 회사 대표님의 소개로 “LLM 기초, 그리고 LangChain &amp;#x26; LangGraph”에 대한 강의를 진행했습니다. MetaCode라는 플랫폼에서 오프라인 1회, 녹화 1회 강의를 했습니다. 15분 ~ 1시간 정도의 발표 경험은 꽤 있었지만, 하루 종일 진행하는 강의를 해본 적은 없었어서 부담스럽기도했고, LangChain 사용은 많이 해봤지만 강의자료를 만들 정도로 능숙한가? 에 대해서 저 스스로에게 의문이 들기도 해서 강의를 받으면 안 될 것 같다는 생각이 들었습니다. 고민을 하다가 ‘이참에 LangChain &amp;#x26; LangGraph 기초부터 다시 공부를 하면서 강의자료를 만들어보자!’ 라는 생각으로 강의를 수락하고 몇 개월간 틈틈히 강의자료를 만들어서 성공적으로 강의를 마칠 수 있었습니다. PDF로 총 266 페이지에 달하는 강의자료를 만들었고, 강의를 준비하면서 저도 다시 한 번 복습하고 이론적으로 다시 적립할 수 있는 계기가 돼서 좋은 경험이였습니다!&lt;/p&gt;
&lt;h2&gt;I’m getting married!&lt;/h2&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1536px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/28149d6c91e12cac979890f64034cc39/e8464/propose.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 66.60000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAADJElEQVQozwEZA+b8AHlZUHBPRHhaTJt6Z4lpVIlhR7uMcLeRfXFZVXRbW4lvbG1aW29dXZp6bad7Y6h+ZbCGbaN5ZZBtXIJnXQCPaFeIX06FXkemfl+zmoO1lnvMoHjarYmFaV+HaGGmg3eEbWeKcWi5kni3moCca0qfaES5jW6vgmmZdWIAonhgrntbnHVd1Mu+///v///03tG73bOKlXhqjG1ktJB9lXdrk3Nk5NfD///+8ebQg1I1kGhMxZp5pX5mAKt9YsiWapuGgOPYzv/44O/q2ezr3NCzkp19aI9wZreSfKiAa6B7Z9POvM3HufHr06mQfWVALY93VnhgSwCufmLHlWyQfHm2q7H/8Nrcwquuo5PEp4Wif2mSbmG1jnmogm2ee2m5nIPAoYPrz7WolpJPLiKPb1h0WFEApnlhxZRwrYduhHqHxbO35cW2p4p23LWJn3xponlmz6aDqX9pl2lXxZt71qRztJWFkoeHTTIqZT8xelZMAJ1zX8STcJB2aCc7W2JfcmhZY5qEdOy8jbOJcXteU390Z8ufe51oU8ifgMyqhsOig9K4oVQ+OTofFnVRRQCWbVyjc1hYQD0mQWlEYYlLU2VZYXLNo367kXOqhGdwZV90XVSZalfDlHXIrJXlt42le2k+LjBHLCh+WE0Ajmpee1BAUzMvJT1kNlWBSmSKQ1RvZ25+T2SEgW1omGdSiVpJu5J4rYNmrpB0yqiPood/a0xAelZFl21cAIpoXXVPQ0YwNCA5XyM2WDJJcTNOeChKeSc0T2lPSMCKYeCocOavfsaYaL2RarN+W6d0Vq2AW5ZtTI1dSQB8XVd9XVVPOzsoPGElOV4kNFUyOlGGX0ubbla2k3uQeVy4m3zGpYfBnYTLjmbNhVXGe027iGmmeGTJk2MAfGFdlG1fY0U+IzFPIzpgJkFsOT1SfUs1il1JoXJcpHhioXdlsot2wY9vyH1VzHtP9b56tYNek2FMo2BBAHROP5BaPmVAMh0kOBssSSIwSxwhMDcoKjwhIDQfIVs4MGM+MmxEN3xNOIROOp1dQbl5TqBaPoFGNXBAMzDreeQ1UbytAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;propose&quot; title=&quot;propose&quot; src=&quot;/static/28149d6c91e12cac979890f64034cc39/e8464/propose.png&quot; srcset=&quot;/static/28149d6c91e12cac979890f64034cc39/0eb09/propose.png 500w,
/static/28149d6c91e12cac979890f64034cc39/1263b/propose.png 1000w,
/static/28149d6c91e12cac979890f64034cc39/e8464/propose.png 1536w&quot; sizes=&quot;(max-width: 1536px) 100vw, 1536px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;올해 2월에 여자친구에게 프로포즈를 했습니다! 2024년 말에 여자친구에게 프로포즈해야겠다는 생각을 하고, 나름의 준비를 해서 올해 2월에 프로포즈를 했고, 여자친구가 받아줬습니다. 😆&lt;/p&gt;
&lt;p&gt;그래서 저는 2026년 5월에 결혼하게 됐습니다! 🥳 🎉&lt;/p&gt;
&lt;p&gt;올해를 돌아보면 기억의 대부분이 결혼 준비였던 것 같습니다. 🫠&lt;/p&gt;
&lt;p&gt;먼저 결혼한 선배들에게 들었을때 결혼 준비가 힘들다는 얘기를 많이 들었었는데, 저는 다행히 힘들다기 보단 재밌게 준비한 것 같습니다. 여자친구가 저보다 많이 알아봐준 덕분이라고 생각합니다. 😀&lt;/p&gt;
&lt;p&gt;결혼식장 위치, 상견례, 신혼집, 웨딩 사진, 신혼여행, 결혼반지 등등.. 정할게 많긴 많더라구요 😅&lt;/p&gt;
&lt;p&gt;주말에는 거의 저랑 여자친구 모두 결혼 준비하는데 썼습니다. 그래도 어느덧 결혼준비도 점점 거의 끝나가는 것 같습니다..!!&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 702px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/8ccc3e346246ae9b1ba2277793e5a121/198ed/mobile-invitation.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 189.20000000000002%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAmCAYAAADEO7urAAAACXBIWXMAABYlAAAWJQFJUiTwAAAJa0lEQVRIxz2U6U/bVxaGLc1I86GdaZKmbVYCYTPG7EvY980GbCDG7CSBQEpCCCktJAMJYd/BNt6wjVewMZgtQEJIO21mKrXSaDR/0jPyL+l8OLrS1bnPfc977j2i337/Dxabjw3vHlaHnw3fPl7/ITt7xxydvMPjf43eHuDN6Xv2Xp8yb/Yzpt1kWu9DY93B4NxjzuxnxbKNybWP6Oz9L0zP6VnUWHg5uYpWb2fV6MBgdqFfc7OkdzI0aWZO52B41krfqJGROQuDU2b6Rw1MrawzNGWm76Wewak1RKdnH5hZMDG3bGVy3ozVvonOFIR5cHj8LJs2eDJmZnDGRv/4Gn+fs7GxtYfV5Wd4fp1ZvYvZVTeDkxaez9oQHZz8xHfDS0wsWBgaN7Ckd+D0bOHa3GZja5c5g4e+IGjewciCg0XTBk7vLjt7h0yvuoW9YAxN24RVtPP6R7oG5hgcN9A7ouPlnIV5vYvheZugamDaSv+klaFZOxNaD+ubu6x5Augd20zrPbxcdDA872BoZp2XS05EWwfvUT+c4v4zDT3DOh6PGuge1tM1bKB3bI0nExa+m7LyfN7B5OoGS5YtdHY/Buc2K1Yf0zo3r1ZcPJ+zM7IYBB7+iOrhND3Dqzx8oefRqJHHYyZ6x8z0TVh4OmVjcPZj8pxpE5Nrh83tA7b3XmP37rK05mNc4+bZ7DrjGg+inaN/0NI/T++ogZ4Xep6Mm/l+2srTKasAG5pzMLLkYlzrERT5Aoe8e/eO92dn7B0eY3BsM2/2Cuqn9ZuIAic/0/x0ga5hPQ9GgsCPZfZPWRmYsTM45+DFsks4sGr3C5Ag7OzsjJM3p7j9B5jcAWZNXjTr24i2j3+m4ckCnX83cH9YT/cLIw9emng4ZqZ3fI3+KRvP5h2MrrhZtm6xtfua09N3vH17yu7hCe7tA7T2bRbXfAT2jz4qbBlYpGfUSM+oiUevzDwaMwsKh4JPZdnFtNErwBy+fTzbB7w+fsve6xMcW/uYPAHWvbv4dw/xB/YRHb37wMMRLf0Ta0I3B6asDM6uM7riYlQTVOUTzHf59wkcHHPy5i17h0ccn3xctwIHwpv07ezj8u4gOj77JwNjBqa1TpZNHrQWL4vmTQz2LczOLVy+AP7AAVuBfVybfuwuL26vn+3AHpu+bXQmB6tmpwALPnhB4fdjejRGFxb7Jhqjk9U1F8sGOzqzE493G49vB7vbi8sTHCLbaI12lldtaAw2TFYXFpsLnXEdnckZBP7CD6+0zCxb0RntLGqtrK37WNKtY7K5MVhcLGjWMFpcuDe2mF8x83JSw4LGjN5ow2Z3M7tiZXjSwPSyDdHpT78yPLPGxNI6U0tWPN5dzBYXPn+wpABHx6eYLA7Mdh+m9U2WdRbWnRvY3T7Mtg2mFk18PzxDR3cfD7q/RRQI7HG3s4cnQ+M8n9Cis3rZCLzh+P2/CBz9yObOEb/9+7/c7+xi4tUYR2/O+PDr71jtbh739dPW1EidvAxZQSatKgUiq9lAkjiU4pxbFOdlISstoburi7GxMV6MjjM+q8Ht9tJcLeNOTSV9XR28eDZIq7qOoqw0KgqyUZQVUlWST3tDHSLnupWsFCmleRkUZqVRVpBFc30N8tICaqvljDx/zsDTp8yOjfK4vYmBBx0sTo6iUsjobG/mQUc7lSV5VJbk0qauRWTQaYi49jWZKXHERYfypPdbvBsenHYbRr2B3ke99D7sYWVuBv3CLFa9lt9+/UDvg04hR7O0QGl+BvKibFrVNYgW52f44i8iIq59Sejlcxh0KzSqFGSlxpGdkUGCRIyiOJeu9kbuNtVxv1nF0vgwU69G2HA7kRXnUV6Yjbw4l5agh7qVRa5d/AxpxFWyUmK506zi4ud/4laCmGuXL3Ph/DkSJdFUFmShkhXS19nK/IsfmBsboam+liaVkrstau40qahXyhDpNEuEfPMFKXGRSCKuca+1AbNBS3dnBx0d92hrbaan8y7P+nsZeNiFZmYcv3udmVfDTE+8outeG497uigvyKZeKUe0qlnmxqXzpMRFES8OY6C/F83yAkuLC+h0GqYnx1kz6P4fDrOew70Aa0Y9Qf/7e7/lXmsjRTnpNNRWIVrVLnPj8gVS4qNIkNwkXhJOWWEOpUX5pKUmCLd2Nt8WoqtVzUBPB73379BYp0QpKxVy5SUFyEvyUQeBOs0y1785R1JsJAmScGKjbgjyszNSSUyI4Y5ayb36Ku6pq2mrraC9Tkbr7WoU5cXIivKE5uWkJZCRJKFGVvwH8DyJkgjixTeJE98Ubs3MSkRekcuDNhX3G5WfgOUCtK1eibKiWIhgqdmp8WQmS1GUFyFaM64iDrtCWkIMSbERJEsjKc7LpLwkl/ttKrpa6+hoUHBHVUl7nZyWmnKaFGXUyoIKc5EX5wuwtHgxlaX5iMwGHZEhX5MijSQh5qbQmLiYcKrKC+luC3pXy936Ktpvy2n7BFRV5NFQXUZVSYFgT256Eonim1QU5SIy6bWEXblAfHQosRHXiLxxiZiIEBpqZHS31NL5h7rblbTUVNCsLKdeXiQAG5SVgo856UncuPwlqQmxiIJf58vP/kzola8Iu3KRyxf/RkF2Kp3NddxVVXJPHVQno0VZRpOiXAh1ZYkQDQoZakUliopSbiUlkpORjkivWebS+c8Ju36ZG1e/Jj0lXviTd9QKocwgqFlRSkNVsaAs+Ftqy/NpVMpoVSlpvq2goaYKRXkpzaq6j13+6txnRN+8TmZqIvXKSiGprV4hmN9QVUJ9ZbGgRlVZhrIsn/qqMhqVcmEvuKqVchTlJdxtbkBkXNUSdf0S6QkxgsG3qytQVVdQKyvitiwIqkCtkAl+BQdpMAS4vJSa8kIUJblkJErITI5HXVONyKzXEXrpPAniMKExafHRwnxMj48mJzUBZXmhcLCqJA9FaQHVJXmUZKdTWZSDrDCbvLQErn11jksX/kp+RsqniR0TTkZyPElxYmIjQpBGhiAOvUKyJJzCjGRyUqRkJceRfyuZlNgI4qNCSZVGkSyJJEkSIZwRf7JM5Pc4yE+Vkp4gITMplrS4KKQRIcSGXydNGklmYgzJkggiQ68TFRZC+I2riMNDiQ67TmTIFcRhV5FGhhIVFgQmIdracAmzLy8jWZCcdyuZjCQp2WnxZKbEC28rKU5CnCSa1MQ4UhKlSKIikERHEi+JJkkqJjVBSqJUjKy0kP8BoYm+vmDLgGEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;mobile invitation&quot; title=&quot;mobile invitation&quot; src=&quot;/static/8ccc3e346246ae9b1ba2277793e5a121/198ed/mobile-invitation.png&quot; srcset=&quot;/static/8ccc3e346246ae9b1ba2277793e5a121/0eb09/mobile-invitation.png 500w,
/static/8ccc3e346246ae9b1ba2277793e5a121/198ed/mobile-invitation.png 702w&quot; sizes=&quot;(max-width: 702px) 100vw, 702px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;그리고 제가 개발자인 만큼 모바일 청첩장은 직접 만들었습니다! 저랑 여자친구가 원하는 모든 기능을 넣기 위해서 여자친구의 기획 + 저(+ Claude)의 개발로 현재 마무리 단계에 있습니다.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 2000px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/8f46d8170083e35719b48223d4a2372b/e52c7/ai-chatbot.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 64.4%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAACVElEQVQ4y22T62/aMBTF8/9r0j5Pahl9Tl2nTdqkbh/G6Eu0rC19UHUUKKwtBELJA5I4dmznTNcExqRZurpX8dEvx76+VpZl0Foj0xpaKQjOwRmDlhK0R99NXtZJCZEwxFEEyXmume1ZWFppmoInCThBOQcy/HdJpYxWSgWRCmRLOmsycvBUv0bv7s5Ev9GA3byH3Wxi0Gph0G4jGI0wHY/RqZ2hc3GOzsUFupeX6F5f4ff1FR5vbvB8e4v+fQNW+7yKvTevsL++hoPVAsqFAg431nH8bhsnH3ZR2X2PZvUU/cYvfFt9jVJxBYeFIsqFVRxtbaL66SPOv3xG7eueCSv0PQy7Hbz0njHu9+DafXgDG95wAN9x4A2HCH0fPI7hDmbf/JGDqedi8PCAeuk7bstl1EslPNbrsBRdMt2flOB0hxRCIBECgkdQSkIpDaOj5gAm03p5esLR5gaOt7dwUHyL5ukpLJmmEARgDGEQmIjD0HQwiUPTdWqAUgrTyQSu68L3fISTKaIoQhzH0FpBSokkjmFRYbrLGKIgMEFA2uQsgRDpAkiAOSRNhIHIfI80ZGoBNA593wCZcRebn5B7A8x1lA1IKaM52dnB4foafqys4L5SmQFF/v4WMMZmwCTJgcK4oJqL2RudX9NDrYb22RlaP6uw262/Dpdj7oryvBkE9IMAwdg3IJYkYIwhVXrx/ilbNE4kJjAdh8ZP52NIy7Nt+MPhYpKUVMh0hvl40LhRHTgORt3uDDh3Yxwp+Q/Q7fUM1IxcrqMjU03dJTNZDnQ6HfwBdcPVpjW4ilAAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;ai chatbot&quot; title=&quot;ai chatbot&quot; src=&quot;/static/8f46d8170083e35719b48223d4a2372b/f97d7/ai-chatbot.png&quot; srcset=&quot;/static/8f46d8170083e35719b48223d4a2372b/0eb09/ai-chatbot.png 500w,
/static/8f46d8170083e35719b48223d4a2372b/1263b/ai-chatbot.png 1000w,
/static/8f46d8170083e35719b48223d4a2372b/f97d7/ai-chatbot.png 2000w,
/static/8f46d8170083e35719b48223d4a2372b/e52c7/ai-chatbot.png 2146w&quot; sizes=&quot;(max-width: 2000px) 100vw, 2000px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;평범한 모바일 청첩장보다는 한 단계 더 나은걸 만들고 싶어서 제 직무를 살려서 LangGraph 기반의 RAG 챗봇을 만들어서 탑재했습니다. 이번에 구현한 모바일 청첩장은 완성되고나면 추후에 오픈소스로 공개할 예정입니다. 오랜만의 오픈소스 프로젝트 공개가 되겠네요. 😁&lt;/p&gt;
&lt;h2&gt;Journey (France, Swiss)&lt;/h2&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1400px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/a177b38e90a2acac58c25c6869ebede0/3643c/journey2.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 55.199999999999996%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAADIElEQVQozwXB2U/bBQDA8d+f4KIky4ZjGQYwKFM5ylULtKGw0YPaAm1poS30pEAd0GJhCLSUIYdVkDpgNWyEcY0BG4ebsg0zs0CzZA8w9WXJfFSjPvn29fMRvo3fYnbtMetH/zE0N4nNqWT9dpyd9Th+lx63UUEk0ITJPYrKPIjc/BW5n0RR2GdIHL/ixW+vOUic8OjwF7Z+PES4NjZOeGySZy//4uuFG1Rp8pkKdbJ3d5ZGbREa6ftMR9xU6MPo6u0Ua/pIkYQRaUbYf/ac3YMjri/eo2d4lE+DfoTRiQkGQgPs/7DL9ZtzNFqriIV9VFbIabPJ6WhRsXJzhEvGEC67HpmymTSxD9FlP1U1NcRurTIxM4/GUI3ZZkTo7g/RaLUSGeih2e3GaFBjMWnJFmUTCTTQ0lCBy1CBUuuiqVZMiayad0V6xAofqRczkMiKaGm14O5o50owgLC8ssxIZJABv4/hoUHcXitXdXXcqDfS29qARyult0mLxVyHWZmFVlHCufQ8PixWkVvyEZVSERadnPZOB/5gK8I/f/7O2BdhlHIZywuzuHw2ZnS1bL2ZymdFEhoV+XzXXkansxy9OheXIQdx9mmkH79HTa0aTbmYbq+NjZUZttbiCFsbazicTsrKK5mJTeJt8zHg72VcaeZzjRm/t5nExjR3N+8TnZplLj7Pndsx9rZX2by3yWQ0yuL6A3aeJHj0cwKhoLCQ5DOnSE9LwdrsQyLRUSbTc7lKjbSkjLQsFdGFJ3zz/b/0zb9m6cGvPH1+wuHxKx4fHXP44iXxjQPmf/qD/ZO/EUplckRZSaQkv4He7EVxSYujXk3IUs6V6mIuvJODLziE1tGGq8vL6kYUh8eJzmTCPzjM/d1dvhwJYbE46QuPI3gcVsoKM8gXZeJpacNQUYpNchFJ5nnOvnWKzPRUAr19lCrqUJoaiS0O0hVox9fhob+/m729bVbXVvggrxSTxYmwtTRNX5eVYIeV0VAPBedTyE06zYWkJM69nUxBXg6R0SkM9iAqUyvXYuM83F5icuwq0WE/Tw8esrdzh9SMbOzeAP8DxKwFdOmo9yMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;journey2&quot; title=&quot;journey2&quot; src=&quot;/static/a177b38e90a2acac58c25c6869ebede0/3643c/journey2.png&quot; srcset=&quot;/static/a177b38e90a2acac58c25c6869ebede0/0eb09/journey2.png 500w,
/static/a177b38e90a2acac58c25c6869ebede0/1263b/journey2.png 1000w,
/static/a177b38e90a2acac58c25c6869ebede0/3643c/journey2.png 1400w&quot; sizes=&quot;(max-width: 1400px) 100vw, 1400px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;유럽 여행을 가보는게 어렸을때부터 로망이였습니다! 그런데 대학교를 졸업하고보니, 생각보다 길게 시간 내는게 쉽지가 않아서 어느새 나이는 30이 넘었는데 유럽 여행을 못가봤더라고요. 괜히 대학생때 유럽 배낭 여행 다녀오라는게 아니구나.. 하며 생각하다가 앞으로는 더 시간 내기가 어려울거라는 생각에 ‘더 미루지말고 유럽 여행 다녀오자!’ 라는 생각으로 올해 초에 유럽 여행을 계획했습니다.&lt;/p&gt;
&lt;p&gt;이탈리아, 영국, 스위스, 프랑스, 독일 등.. 가고 싶은 나라는 많았지만 10일 정도의 일정으로는 2개국만 다녀오는걸 추천하길래 도시도시한 프랑스와 자연자연한 스위스를 다녀오게 됐습니다. 여자친구와 여행을 세부, 사이판 같은 휴양지로 다녔어서 이번 유럽여행은 더 재밌었습니다!&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1394px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/1a737f84d8caacc9b340a0218d9dae9a/02f69/journey1.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 55.199999999999996%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAADH0lEQVQozyXMaU8bBACA4f4IE5P5Sb+oiTCvTClzHKMrkg4ox2yhHOVaC9S2tF0LhcLWgzJKmSXca5GN0oxWaAsdS9nGJtuayBARZ8gWJ1HMolHjsUXF6GvMnh/wCLYfPCJ55x6R5DrDM5cZm10mntpj7vp9wiubjEdSzCW3uPLJfZKf7hJLfcWtnR+x2TVIig4iV4gQHnmBJpWU/f2/ENxYv0ff+SiN1lHqTnnxXUwQu/sTw7EvGIx8zrnYLvGPdxgKXMAz5ueDqRmiKzfRmeRk5b6MvCKHt4XPIlccZn//TwRmp5sTGj3FaiPv1hlptJyh7KSJUlUXVZpummwTTMwuoKwSIS0SUlaSQZtWwaDPiHuwC+2pat5TiLGYm/nnXxDUqmqQN1QgKsrluEKCrEFGvrSYd7IzEWW9RbZIjLPPjVSSgfjoq+TnpdNUX47Npsbco8E1Mk6rwUB3dzv/Ezh622ltayXt4JuYTK24eu00nlQiLS3ijNOBp99BKDTDfPQjfD4PLqeNpcQi0ZgX/7SW6WAfA241HYamp+HkyCBdVhOFxSV4XDb8owNYzTr6+13YXXY6zHouJxb57fETvt3b49ffH/Pkj7+JLVvp6RVisZTQ0izkfVXB09DjOUt3uwZXp5pAwM9Q/CH98w/xhj8juHiTK6kNNh/ssrP3A19+84itr79j9/ufubu1yXwizvW1VVZvrXFtbY3bG9sIwnPnUaurqZGJiEQX8N4Ax8Iv6NwxArHbXLx6h2hqg6X1bS6tphiOLDMdv8rEzAIfzi0TW1lnNBhHabRSUFOPIHzBTWFZMdKCbCLhKRpbRjC4Qph7zqGzdCBXK6hsqaPRaMARCGKeDDIUWaKt00xJjZwqdR2ZhWJeEmbwRt4xBEMeOweeO4DyRD4B/xj1pikKKjqpbD5L54Admf41Kg1HqNXl0eXUYnDaGAuFqDc2kyktQKKsIE0i5plDh3g+JxdBbXUVaWmvkJslpLfPQ9fkBjmy0xwutWPxOjne8CLl2nTK9elU6l+nsDadTpcOr38S9/gos4kkvuAlVPbTyMxt/AcjDzlVDwaTEQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;journey1&quot; title=&quot;journey1&quot; src=&quot;/static/1a737f84d8caacc9b340a0218d9dae9a/02f69/journey1.png&quot; srcset=&quot;/static/1a737f84d8caacc9b340a0218d9dae9a/0eb09/journey1.png 500w,
/static/1a737f84d8caacc9b340a0218d9dae9a/1263b/journey1.png 1000w,
/static/1a737f84d8caacc9b340a0218d9dae9a/02f69/journey1.png 1394w&quot; sizes=&quot;(max-width: 1394px) 100vw, 1394px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;파리의 에펠탑과 센강, 루브르 박물관, 스위스의 자연풍경 등 너무 좋은 추억들을 남겼습니다. 프랑스에서는 주로 걸어다니거나 버스를 타고 돌아다녔는데, 건물 하나하나가 웅장하고 멋있어서 도시를 걸어다니기만해도 즐거웠습니다. 루브르 박물관과 오랑주리, 오르셰 미술관에서도 어렸을 적 교과서에서나 보던 미술 작품들을 감상할 수 있었고, 스위스에서는 윈도우 배경화면 같은 자연 풍경들이 너무 이뻤습니다. 스위스에서는 야생의 여우도 봤습니다! 스위스에서도 야생 여우는 보기 힘들다던데 운이 정말 좋았습니다. 😁&lt;/p&gt;
&lt;img src=&quot;https://image.news1.kr/system/photos/2025/6/1/7320831/high.jpg&quot; width=&quot;400&quot;&gt;
&lt;p&gt;그리고 저희가 파리에 도착한 날이 2024-2025 챔피언스리그 결승전이 있던 날인데, 파리 생제르맹(PSG) 팀이 챔피언스리그를 처음으로 우승을 해서 파리 현지의 축제 분위기를 직접 느꼈습니다. 점점 과격해지는 분위기에 얼른 숙소로 돌아갔는데, 그 날 사망자가 2명이나 나왔었다고 합니다. 😢 프랑스라는 나라의 좋은 점도 여럿 느꼈지만, 아직은 아쉬운 부분에 대해서도 느낄 수 있었습니다.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1536px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/99dd422254b1efc5840ca542ced9d3c0/e8464/honeymoon.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 66.60000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAADJElEQVQozwEZA+b8ACZ1vCl7xDCCyDGGzDOK0Fug03eu3EOX4jqY5T2c6D+f6j+g6kev/EZyngoZOBInSxkzVRozWRoxVhMnTAAvidM1ktxOls9Hnt1Xq+aazPCbzvRbtvaNzPOCyPJJs/RKtPNoyv9dhagTJEgVLlYdO2IsUngmQ2gaL1YAhcDqVbDucavNcbvnab/3YarJjbGnrs3Elt74iN//edj/g9f90fn/jp+xMT5cTlZrS1JnXml+S1x7LUFlAJDP9Y3R+Iu2yZ/Q6J3c/4+yo4aJVYWJU7q8rLTIzKzJ0qvO2cfn8ZKjsWBWXXhye2RhamhhaV9xjVdphACny9az5P+jvMG12ee78P+jwcGgpIeyr4OZkHWBlIV8koeHlYxlrbRvj5pnVlh2bG9aVFZqZmiFfo+Mfo0ArMTAxtPVnaaexdHLvsTCmJmOs7OO6+/G0NzIwN7UxtfK/PTgm8zHXYWRgWtlvbWlgHJngm5wfnV9l3mCALGwlrGpmeDfzsjEs9TJtqCHa5eRb6S4qufax+fZwrSok8uynbzHvGmNjJWOmf/968fEr4BhR41iQWtcTQBYlZa6vrrx5c/HwK6/s6O6qJiBcFufgl24ppirk3+demO3kXZ/xbl6n56Re4HPwLbSu5qaeFVwQh9xU1YAfYl2VV1kqJaNm4Jti3Rhq4proH1bwo1QnXlRuJJswJFi3qhsgMKqe6WlVEdTTFhtkYqCknReOScdUUFHALyUaoFmUVxkbFhmbp+Uht7EmrN7XMePY8iST8GVa7OHYLuMZpKmjoGFeCI3Wxg9bzpRbZl1V0ItITUoIQD825xzX1AoNU4/aY+Bf3/Lv7afj4aFZE27jVXUonBybGxHcpNzal52WU5ERFQSL1p+aFqhaktRIxsvKy4A98qKjXlaGC1UHDtrd3d95NrL1r2whTg7lmxF5Kx0b2BZJ1J/bFhMdlxQPDhGDCdOaVNQlEw3kC0eWjIxANmqeOq8fj07RRYaLllUXLm0tsGloI5PMnVWMKFxSYJPNpdjS6lrRZByXzs2Ox8eLDApMWQsJXYqIWMmIbvrm4DOcdC3AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;honeymoon&quot; title=&quot;honeymoon&quot; src=&quot;/static/99dd422254b1efc5840ca542ced9d3c0/e8464/honeymoon.png&quot; srcset=&quot;/static/99dd422254b1efc5840ca542ced9d3c0/0eb09/honeymoon.png 500w,
/static/99dd422254b1efc5840ca542ced9d3c0/1263b/honeymoon.png 1000w,
/static/99dd422254b1efc5840ca542ced9d3c0/e8464/honeymoon.png 1536w&quot; sizes=&quot;(max-width: 1536px) 100vw, 1536px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;그리고 저희가 신혼여행은 두바이 ➜ 몰디브 ➜ 싱가폴로 가기로 했습니다! 신혼여행인만큼 신혼여행이 아니면 가기 힘든곳을 가보기로 했고, 여러 쟁쟁한 후보들중에서 최종적으로 몰디브를 다녀오기로 했습니다. 몰디브를 가는 김에 경유지인 두바이와 싱가폴을 모두 들려보기로 했습니다. 세 나라 모두 처음 가보는거라 신혼여행이 상당히 기대됩니다! 😆&lt;/p&gt;
&lt;h2&gt;ICONS MATCH&lt;/h2&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1390px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/542b1c689a0c9691c860a3e18236003b/55991/icon-match.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 72.2%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABYlAAAWJQFJUiTwAAAD6ElEQVQ4yy2KWUyTBwCAf6d72ouB4cElh1GOAhXoVHSFHtylQNsBLa2lBSlni4CioCionVxyCRIY3hvQcArjcGpwDgeZDt2WzQUWs2TJXsVXZ75lZg9fvuTLJ4jDg/Bw+wgfTzd2bt+Kr9fHBAbsJCw0AElUMKEh/gTv9cPXexsBft40tTVxp9VJ+bEs/MNC2RsVTWRsLBKlAmNJEYJUKmXXrl0EBu4mKCiYCLEYmVyK0aTDZjOTZzGQmKREJBIRHS2hvuEUOmMKkrgYlBnxpBtUJGgTkKoV2KpLEeRyGXv27CY0NASxOJwDBySo1Ykcq7BSXm6loCCXpGQFIlEIkZH7OFNfR7ZBizlfjzXfSH6hCUuhCa1JQ11jLYJCIcM/wA+FIgaVSoZGE0+6Og6DIY0KxxFKivVY8jKJjgpj754gmvvPcupKPifbrdT0G7F3aClsk1PcFUfbeAmCTqciLS0WY24KxtxkiopyaHWexV5kwFGWQ4XDgF6fjFYrw6hXM7HSSv9yPoPfVjP063Gur9q59tTB4BM7rqcNCBJJFO7ubnh5ebJjxzaiIsI41+ikt6cLnTYVPz8ffH192L7dA18fL169+oO3/7xleGSYqclZlp/8wr2FR8wtLPJ8dR3B08sHQRD+Z9N7e3tsZZ84HHd3dzZt+oDNm7e871u2fMj6+jqvX79BmpCKUpmKWpWLPE5PkEiByXIaQZORRsyBaJSyQyjjDiL79BP02iSyNEmkJMtRpyWQlCgjMTGW1BQFG282ePfuHQ5HEVKFFMnB/eyPjScg+iDp5nyEE+caOFp1HHt9A/VdPXR8OUTLwDVuj7iYHh+h2VmPs7GG0zWVtDdfZHpshNmpcQrNZtLj5TQUGygpU2MtL6S9uxtBZSxAlKonvrSGgq5bnPpqnsMFx3FeGWDt+0VsR7LRKWK4bM7kQpmN8jwjrjs30er1nKs8Su9JG3WlGeRqUiirrEKoPXOJTFMpBnst1U2XON/UxCFNDkcrqhno7KHFUYJNJqVPl8jD1jqcNSeYco3y+IcXjHzRy9DNHoaGb2PMSqfUaEYYXDxP16Mq2h5UcLalgs7OSuQJClI+01NsKaTOYiEteDdlokgeDk0yMTTHheo61v7e4EZnEyOu67imJrGbdaQqtQjOUTMZtRJqP9dgMmuwFRtIVsWjN+WyNH+PjpZ+DkdE4ci2snT/JQ8Xfmd4eJa5mXkuFmfRc/Uy7X39lJuzyTFZEUZHx+js7uO7uf+mCWa+nuLu7AyPHy/y4skSK0s/cndsmunJOV7+/CfPn62xvv4XK4sPuD96g9UXz/hm+Rm3XOP89tMq/wIPDXLs2Oy07AAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;icon match&quot; title=&quot;icon match&quot; src=&quot;/static/542b1c689a0c9691c860a3e18236003b/55991/icon-match.png&quot; srcset=&quot;/static/542b1c689a0c9691c860a3e18236003b/0eb09/icon-match.png 500w,
/static/542b1c689a0c9691c860a3e18236003b/1263b/icon-match.png 1000w,
/static/542b1c689a0c9691c860a3e18236003b/55991/icon-match.png 1390w&quot; sizes=&quot;(max-width: 1390px) 100vw, 1390px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;넥슨 주최의 ICONS MATCH에 다녀왔습니다! 아이콘 매치를 한다는건 알았지만, 표 구할수가 없을 것 같아 그림의 떡이라고 생각했는데 여자친구 회사에서 추첨으로 티켓을 나눠줬습니다. 운좋게도 여자친구가 당첨이 돼서 아이콘 매치에 다녀올 수 있었습니다! 🥳.&lt;/p&gt;
&lt;img src=&quot;https://img1.newsis.com/2025/09/12/NISI20250912_0001941729_web.jpg&quot; width=&quot;350&quot;&gt;
&lt;p&gt;정말 화려한 라인업의 세계적인 선수들을 가까이서 볼 수 있어서 좋았습니다! 박지성, 디디에 드록바, 가레스 베일, 스티븐 제라드, 아자르, 루니, 카카 등.. 학창시절에 봐오고 피파온라인에서나 써봤던 선수들을 실제로 볼 수 있어서 너무 설렜습니다. 좋은 경험 만들어준 여자친구에게 감사함을 보냅니다!&lt;/p&gt;
&lt;h2&gt;5KG 감량&lt;/h2&gt;
&lt;p&gt;작년과 비교해서 5KG 정도를 감량했습니다! 결혼 준비를 시작하고 감량을 시작했는데, 1차 목표였던 5KG 감량에 성공했습니다. 기존에 1RM ~ 3RM 정도의 중량을 들던 방식에서 8 ~ 12회를 반복 가능한 중량 운동을 메인세트로 바꿨고, 운동 후에 천국의 계단을 10~25분 정도를 꾸준히 해줬습니다. 점심에는 햄버거나 파스타, 포케 같이 초록초록한 야채들이 섞인 메뉴들로 먹고 저녁에는 먹고 싶은 메뉴 그냥 먹는 식으로 했는데, 결과는 성공적이였습니다!&lt;/p&gt;
&lt;p&gt;덕분에 웨딩사진에는 올해 초보다는 조금 더 갸름한 모습으로 사진을 남길 수 있었습니다. 이제 결혼식까지 4개월+ 정도 남았으니 그떄까지 3KG 정도 추가 감량하는게 목표입니다. 🏋&lt;/p&gt;
&lt;h2&gt;튜닙 퇴사 (예정), 이직 준비&lt;/h2&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 540px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/bd6f6e9f47fe6d06946a29c43ab4d309/03ec9/tunib.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 63.800000000000004%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAADxklEQVQ4yx3ObUzUdQDA8f+0cvagpYNm5kxIFA4uSDhA0HzAQIY4kYfjAo4DOYGTBxkHCCp4PKkcKnAgT56AIkwOUOmMcKW8gFqrtl5Z1HJr4ViIQ06OB+X3bfri8/4jzT6bYHb68ZJ9+rGYn3nCKy/sNmxPfufXX0z89ccdrN/kUGsKpqrej4zircQdkXO+IQyNXobrrveEo1wSvqHrOKTeckKat8+IhTkb88+fsjA7zcu55/w3/pA+q5HRH+u5Y02h8WoENU0hqDPXcFj9PmlZCpqvpZFnOIBOH41LwBsiItGL5OM7kRZsE9inx4X92YSwTf2L/ek4Tyf+JOukEyVlAYwON9B2PZU8gzeaDDdClB+y++Bq4jJX8kW0RHTydrEn3JnIJLk4kr1DSK9Wi3MzYn5mknnbFP+MjWK1ZKNNckYVuZmS4gQsXaUYL6iJS3Vjn2oTKdn+pOm3U9MUT1i8I05e7wj57lV4718lpKUFO4vzs8zZpni5YOfR2A/ok9wI81mOwv0twiO9MDXqyMoNRJnsgSpdQVxKAJFxMuou6ikoOsjO/R/j4ruCDZ7LkIQQLL1c5MWiHfuzSSbHxzAbs9m6XsLXew1fabyIT5VRVqHEYIhHqfElUulDZdFRqop1mCoLyM9V4uKzAgfnN5HGH/3G6PAAw/d6+fvhT1hvVRES+gmf+25A5r6M4PDVJOg2oz7qyqkiJVdqTtNuKqWyREuGLpTLVXkYTqXht8sR/6DVSEODFvbuUZAYfwhzfQkX67SEhrvg67+OyFgnCk96EqPaSHSMN+XFyVxrPUPNhWNUV2mJVrtyLDMEVbw/3oGOBO5dj9R91UjBcQ1REUGYKtJpMOUQELSJpCQ/Covk7A5ei6vHCkL2baH2XC53e5ppMZ2gvdlA8+VCqsszyM9V4em3lh1fuiI9GLyBThsrvORbyNSqGBnq4HReAlGHFewN2oiLx9t84Lgch7USOboYRgb7sbTV0d16gb62elounqb/RqPQF0URcMBBSJcqcvjMw0W4y5xJT4pgdNDMz/c6+K7XhLWzmqbzxynN15CuDsN0Npf7A9cZ6Gqks/kcnS3n6WmrEwU5seJT2bs4ea9ckrJSY4Rim4xAP0+SVWF8f7uRkbutDN28xIPblxnsqubb7mru99XydcdZ+s1lWFoNtNXmY67J46a5gpJ8DT7bNgm54iOkRFU4EQeDRYY2DmNpHg+sLQwPNL0e3u9vwNpppM9czq22CnqvlL7W03KG9ho9rcYMOupyheWqYamvo5T2hnzL/7+JfdYGdJppAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;tunib&quot; title=&quot;tunib&quot; src=&quot;/static/bd6f6e9f47fe6d06946a29c43ab4d309/03ec9/tunib.png&quot; srcset=&quot;/static/bd6f6e9f47fe6d06946a29c43ab4d309/0eb09/tunib.png 500w,
/static/bd6f6e9f47fe6d06946a29c43ab4d309/03ec9/tunib.png 540w&quot; sizes=&quot;(max-width: 540px) 100vw, 540px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;어느덧 튜닙 창업하고 5년 가까이 지났습니다. 2026년 3월이면 5년을 채우게 됩니다. 벌써 5년이라는 생각이 드는 한 편, 돌이켜보면 많은 일들이 생각나서 이제야 5년이 된 건가 싶은 마음이 공존합니다. 튜닙에 있으면서 여러 경험, 여러 동료들과 함께 좋은 경험들을 했습니다. 그동안의 경험이 앞으로 저의 삶에 큰 자양분이 될거라고 생각합니다. 회사와는 서로 합의하에 좋게 마무리를 하게 됐습니다. 저도 공동창업자로써 퇴사까지, 그리고 퇴사 후에도 제가 회사에 도움이 될만한 일들이 있다면 적극적으로 도울 생각입니다.&lt;/p&gt;
&lt;p&gt;퇴사 준비와 함께 새로운 경험과 도전을 위해 이직 준비를 하고 있습니다. 지금의 저에게 어떤 곳이 저를 한층 업그레이드 시켜줄 수 있을지를 고민하며 알아보는 중입니다.&lt;/p&gt;
&lt;h2&gt;2026년 목표&lt;/h2&gt;
&lt;p&gt;2026년은 저에게 결혼, 퇴사 &amp;#x26; 이직과 같이 큰 변화들이 기다리고 있습니다. 큰 변화들인만큼 걱정도 되고 설레기도 합니다. 2026년에는 1) 결혼 잘 마무리하고 신혼여행 즐겁게 다녀오기 2) 퇴사 마무리 잘하고 나를 한층 업그레이드 시켜줄 수 있는 곳으로 이직하기 3) 이직한 회사에서 적응 잘해서 성과내기 4) 결혼하느라 쓴 돈 열심히 다시 채우기 정도의 목표를 세웠습니다.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1536px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/0c862685df7361db384e0065474a77c1/e8464/debt.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 66.60000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAADJElEQVQozwEZA+b8AEtMV1VWXVpaY3lwboJzbId3bo57bntvZltfaF5XWFBPV15aXWJWVFFWY29jWIZ3ZHBpXmZgWWxhUzpFVwBZVlmAc1WSiWO4nYTMoYHhtIriu5W+pIOvl2y6m2+cgGGnjmmmiGWBcmWskGHHpGG1llygg1aYfFBPU1sATE1NamdOt6FdqJpxw7Wf0Lqc17ufwaSGxqRw2rF4z6t05L16zaZyspBouJpn4b57x6ZwooppjHhfcGJWAGBdS4Z7VH92W8K1of752vT34ca6oJ2IYrGXaMCfbs6oduK7hMmjdbubb5qCX7uecraab5d/YVxRTWpcUQBlY1CaiV2FgHnk2cX/99bz8dzy8dqilWWsmFyumVurkGK2lGi5kVykimKUfF2skmyTfmNSSkouMUJUTk4AZmJKloZSioV8xry09NitvbOZzcmwkYNYm4tiq6CHr6aIo5R4k3pXinlYnIFez6hzc2JTVEpETUZGU0lIAFhZSol/Vl5cWIWCj9jDscKnjKmaeKKQWaqceeLdyODextzbypyTgaGHUaWSYa2XZbSLYIVoU1pOSHpjTQBlYEpxalYbN2BDVnB/bmppbXOtkmCqkVeOgWqil4m6r5nGvKbBp26shk2UglWEcEusf0+MbUp8YkWEYT8AbmJIcWBJK0ZsRGSIWGJvRmB7m4xtuZJclYBmgGxXa1xOc2BMpYdVlINchHpap5Fkto9WyJ9npodigWE/AGxPNl1ORRk3Yy5Qe1Bti0JZcU9idJR8XdGzguTHlsSfbbKRYpB8Y4mAboVtRaCKUI6DX9Oxh86mg52IcgBQQz1NRUYtPFgmOFUtTXVCYII5Yo2AgYDFlGC5lWrp0aDYwpS6on+8n33ZsXuugT/EpXbev5W6m3tnX1gART5BU0ZDNj9VLDdQHjNVJThWMjdHfl5IvZBhx7KM0MCZxrCL38KX38CU0qx9rHNAtIlbwqR/n4lwTUY/AEI+QlVFPCgwRyIxTCM1ViAkNiweG1I5KpNnPbR/RrWEULmWcL+ccrF5SqR0QZl+V4NuTYJlQYRgPWVKNbHkgfmcZy+8AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;debt&quot; title=&quot;debt&quot; src=&quot;/static/0c862685df7361db384e0065474a77c1/e8464/debt.png&quot; srcset=&quot;/static/0c862685df7361db384e0065474a77c1/0eb09/debt.png 500w,
/static/0c862685df7361db384e0065474a77c1/1263b/debt.png 1000w,
/static/0c862685df7361db384e0065474a77c1/e8464/debt.png 1536w&quot; sizes=&quot;(max-width: 1536px) 100vw, 1536px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;p&gt;신혼집을 구하면서 지난 5년간 지냈던 자취방을 슬슬 정리하고 있습니다. 지금 사는 동네도 어느덧 5년이나 지내서 정이 많이 들었는데, 곧 이사를 가야한다고 생각하니 아쉽기도 합니다. 하지만 2026년에는 신혼집에서의 생활에 대한 기대가 더 크기 때문에 여러모로 설레고 있습니다.&lt;/p&gt;
&lt;p&gt;이제 슬슬 결혼 준비 마무리하고 청첩장을 돌려야하는데 제 주위분들은 조금만 기다려주시면 곧 청첩장 들고 연락드리겠습니다..!&lt;/p&gt;
&lt;p&gt;이상으로 2025년 회고 글을 마치겠습니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[BERT는 사실 Diffusion 모델이였다?!]]></title><description><![CDATA[BERT는 사실 Diffusion 모델이였다?! 최근 굉장히 흥미로운 글을 읽게되어 공유합니다. 원문 : link BERT와 Diffusion이 같은 방식이다?! NLP 연구자들에게 BERT는 너무 익숙한 모델입니다. 201…]]></description><link>https://sooftware.github.io/bert_diffusion/</link><guid isPermaLink="false">https://sooftware.github.io/bert_diffusion/</guid><pubDate>Tue, 21 Oct 2025 12:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;BERT는 사실 Diffusion 모델이였다?!&lt;/h1&gt;
&lt;img src=&quot;https://nathan.rs/images/roberta-diffusion.gif&quot; width=&quot;500&quot;&gt;
&lt;p&gt;최근 굉장히 흥미로운 글을 읽게되어 공유합니다.&lt;br&gt;
원문 : &lt;a href=&quot;https://nathan.rs/posts/roberta-diffusion/&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;BERT와 Diffusion이 같은 방식이다?!&lt;/h2&gt;
&lt;img width=&quot;500&quot; src=&quot;https://wikidocs.net/images/page/208933/bert.png&quot;&gt;
&lt;p&gt;NLP 연구자들에게 BERT는 너무 익숙한 모델입니다. 2018년 등장 이후, 수많은 자연어처리의 분류, 검색, QA 태스크에 활용됐습니다. &lt;code class=&quot;language-text&quot;&gt;[MASK]&lt;/code&gt; 토큰으로 단어를 가리고 맞추는 Masked Language Modeling(MLM)은 너무나 단순하고 명확한 학습 방식인데 강력한 성능으로 당시 많은 연구자들을 좌절케하기도 했었습니다.&lt;/p&gt;
&lt;p&gt;Computer Vision(CV) 연구자들에게 Diffusion은 마찬가지로 익숙한 모델입니다. DALL-E, Stable Diffusion, Midjourney, … 등 이미지 생성의 표준이 된 이 기술은 노이즈를 점진적으로 추가했다 제거하는 방식으로 학습하여 이미지 생성 AI의 부흥을 이끌었습니다.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;이 두 기술은 전혀 다른 분야, 전혀 다른 목적을 가진 다른 기술처럼 보였습니다.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;그런데 문득 생각해보면, BERT의 MLM과 Diffusion의 노이즈를 추가했다가 제거하는 방식은 상당히 닮아있습니다.&lt;/p&gt;
&lt;p&gt;Diffusion 기술을 텍스트에 적용한다고 하면, BERT의 MLM과 굉장히 유사한 방식이라는 걸 알 수 있습니다.&lt;/p&gt;
&lt;h3&gt;BERT의 MLM&lt;/h3&gt;
&lt;img src=&quot;https://raw.githubusercontent.com/UKPLab/sentence-transformers/master/docs/img/MLM.png&quot; width=&quot;500&quot;&gt;
&lt;ul&gt;
&lt;li&gt;입력 텍스트의 15%를 &lt;code class=&quot;language-text&quot;&gt;[MASK]&lt;/code&gt; 토큰으로 가림&lt;/li&gt;
&lt;li&gt;마스킹된 토큰 예측&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Diffusion&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;입력 이미지에 노이즈(&lt;code class=&quot;language-text&quot;&gt;[MASK]&lt;/code&gt;)로 가리고, 원복하는 방식&lt;/li&gt;
&lt;li&gt;노이즈의 비율을 랜덤하게 적용한 방식으로 학습&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;즉, BERT는 Diffusion 방식을 딱 입력의 15%로만 고정해놓고 학습시킨 케이스라고도 볼 수 있는거 아니냐는겁니다.&lt;/p&gt;
&lt;h2&gt;그렇다면 BERT로 텍스트 생성도 가능한걸까?&lt;/h2&gt;
&lt;p&gt;그렇다면, Diffusion 모델이 생성 모델인것처럼, BERT 같은 인코더 모델을 Diffusion처럼 &lt;code class=&quot;language-text&quot;&gt;[MASK]&lt;/code&gt;의 비율을 높여서 학습한다면, GPT처럼 텍스트 생성이 가능한걸까요?&lt;/p&gt;
&lt;p&gt;가능하다면, 굉장히 흥미로운 발견일겁니다. 최근 생성 AI는 GPT 같은 디코더 기반 모델이 주류를 이루고 있는데, 어쩌면 또다른 대안이 될테니까요.&lt;/p&gt;
&lt;p&gt;심지어 아키텍처 변경이나 새로운 학습 알고리즘도 필요없이, 학습시 마스킹 비율만 랜덤하게 해주면 됩니다!&lt;/p&gt;
&lt;h2&gt;RoBERTa로 텍스트 생성해보기&lt;/h2&gt;
&lt;p&gt;원문 글의 저자인 Nathan Barry는 BERT의 강화된 버전인 RoBERTa 모델로 텍스트 생성 모델로 바꿔보는 실험을 진행했습니다.&lt;/p&gt;
&lt;p&gt;핵심 아이디어는 위에서 설명한것처럼,학습할때 마스킹 비율을 랜덤하게 적용함으로써, 기존 BERT의 MLM을 발전시킨 방식으로 학습한다는 겁니다. (아래 코드는 Nathan이 적용한 diffusion_collator 예시입니다.)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;diffusion_collator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;examples&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    batch &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pad&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;examples&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; return_tensors&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;pt&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# 기존 BERT: mask_prob = 0.15 (고정)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Diffusion BERT: 매 배치마다 랜덤 선택&lt;/span&gt;
    mask_prob &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;choice&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# 첫 16토큰은 프롬프트로 유지 (조건부 생성을 위해)&lt;/span&gt;
    maskable_positions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; batch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;input_ids&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PREFIX_LEN&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    mask &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rand&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;maskable_positions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shape&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; mask_prob
    batch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;input_ids&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PREFIX_LEN&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;mask&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mask_token_id
    
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; batch&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이제 학습 후, 텍스트를 생성할때는 앞에 프롬프트를 고정한 상태에서, &lt;code class=&quot;language-text&quot;&gt;[MASK]&lt;/code&gt;를 점차 채워나가는 방식으로 진행됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 초기 상태: [프롬프트] + 240개의 [MASK]&lt;/span&gt;
mask_schedule &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; step&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mask_prob &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mask_schedule&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# 현재 마스킹된 위치 예측&lt;/span&gt;
    outputs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;input_ids&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;input_ids&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    predictions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; outputs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;logits
    
    &lt;span class=&quot;token comment&quot;&gt;# Top-k/top-p 샘플링으로 토큰 선택&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; pos &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; masked_positions&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        sampled_token &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sample_from_logits&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;predictions&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;pos&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        input_ids&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;pos&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sampled_token
    
    &lt;span class=&quot;token comment&quot;&gt;# 다음 단계를 위해 일부 다시 마스킹&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; mask_prob &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        remask_randomly&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;input_ids&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mask_prob&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;단계별 생성 과정:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Step 0: [PROMPT] [MASK] [MASK] [MASK] [MASK] [MASK] ...     (100% masked)
Step 1: [PROMPT] will [MASK] over [MASK] control ...        (90% masked)
Step 2: [PROMPT] will begin [MASK] greater control ...      (80% masked)
Step 5: [PROMPT] will begin to [MASK] greater control ...   (50% masked)
...
Step 10: [PROMPT] will begin to assert greater control ...  (0% masked - 완료)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이러한 컨셉을 가지고 Nathan이 직접 학습해본 결과, H200으로 30분만의 학습으로,&lt;/p&gt;
&lt;h4&gt;Input Prompt:&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Following their victory in the French and Indian War, Britain began to assert greater...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Generated Text:&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;...dominion over Europe beginning about the early 19th. There conflict took 
place on the island, between British and Irish Ireland. British officials 
administered British Ireland, a Celtic empire under the control of the Irish 
nationalist authorities, defined as a dominion of Britain. As the newly Fortic 
states acquired independent and powerful status, many former English colonies 
played their part in this new, British @-@ controlled colonial system...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;와 같은 결과를 보이게 됐습니다..!&lt;/p&gt;
&lt;p&gt;놀랍게도 문법적으로 올바르면서도 그럴듯한 문장을 생성해냈습니다. 겨우 30분의 추가 학습만으로요.&lt;/p&gt;
&lt;h3&gt;이 개념의 시사점&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;NLP와 CV 커뮤니티가 서로 다르게 발전시켜온 기술이 사실 비슷한 방식이라는 점&lt;/li&gt;
&lt;li&gt;기존 BERT 계열의 모델들(BERT, RoBERTa, ELECTRA, DeBERTa, …)이 잠재적 생성 모델이였다는 것&lt;/li&gt;
&lt;li&gt;양방향성 : GPT는 태생적으로 단방향(left to right) 모델인데, BERT는 양방향 문맥을 고려하는 모델입니다. 이러한 태생적인 차이가 생성쪽에 어떻게 활용될 수 있을지도 고민해볼만한 포인트입니다&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;물론 BERT 같은 인코더 모델이 상용에 적용될만한 모델이 되려면 기존 GPT처럼 여러 엔지니어링적인 고민들이 필요할것입니다. 하지만 AI 연구자들에게는 GPT 아키텍처만이 아닌 새로운 선택지가 생겼다는 것만으로도 굉장히 흥미로운 사실입니다 :)&lt;/p&gt;
&lt;h4&gt;Reference&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nathan.rs/posts/roberta-diffusion/&quot;&gt;Original Blog Post by Nathan Barry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/nathan-barry/RoBERTaDiffusion&quot;&gt;Code on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[LangGraph로 구현하는 RAG 시스템 실습]]></title><description><![CDATA[LangGraph로 구현하는 Self-Correcting RAG 시스템 이번 실습에서는 LangGraph를 활용하여 스스로 품질을 검증하고 개선하는 고급 RAG…]]></description><link>https://sooftware.github.io/langgraph/</link><guid isPermaLink="false">https://sooftware.github.io/langgraph/</guid><pubDate>Tue, 21 Oct 2025 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;LangGraph로 구현하는 Self-Correcting RAG 시스템&lt;/h1&gt;
&lt;p&gt;이번 실습에서는 LangGraph를 활용하여 스스로 품질을 검증하고 개선하는 고급 RAG 시스템을 만듭니다.&lt;br&gt;
각 단계마다 품질을 체크하고, 문제가 있으면 자동으로 수정하는 시스템입니다!&lt;/p&gt;
&lt;h2&gt;목차&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://claude.ai/chat/b18974d7-558c-4ce8-a784-a7e50f7b6ba6#0-%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95&quot;&gt;0. 환경 설정&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://claude.ai/chat/b18974d7-558c-4ce8-a784-a7e50f7b6ba6#1-self-correcting-rag-%EA%B0%9C%EC%9A%94&quot;&gt;1. Self-Correcting RAG 개요&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://claude.ai/chat/b18974d7-558c-4ce8-a784-a7e50f7b6ba6#2-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A4%80%EB%B9%84&quot;&gt;2. 데이터 준비&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://claude.ai/chat/b18974d7-558c-4ce8-a784-a7e50f7b6ba6#3-state-%EC%A0%95%EC%9D%98&quot;&gt;3. State 정의&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://claude.ai/chat/b18974d7-558c-4ce8-a784-a7e50f7b6ba6#4-%EB%85%B8%EB%93%9C-%ED%95%A8%EC%88%98-%EA%B5%AC%ED%98%84&quot;&gt;4. 노드 함수 구현&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://claude.ai/chat/b18974d7-558c-4ce8-a784-a7e50f7b6ba6#5-%EB%9D%BC%EC%9A%B0%ED%8C%85-%ED%95%A8%EC%88%98-%EC%A0%95%EC%9D%98&quot;&gt;5. 라우팅 함수 정의&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://claude.ai/chat/b18974d7-558c-4ce8-a784-a7e50f7b6ba6#6-%EA%B7%B8%EB%9E%98%ED%94%84-%EA%B5%AC%EC%84%B1&quot;&gt;6. 그래프 구성&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://claude.ai/chat/b18974d7-558c-4ce8-a784-a7e50f7b6ba6#7-%EC%8B%A4%ED%96%89-%EB%B0%8F-%ED%85%8C%EC%8A%A4%ED%8A%B8&quot;&gt;7. 실행 및 테스트&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;0. 환경 설정&lt;/h2&gt;
&lt;h3&gt;필요한 라이브러리 설치&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;pip &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; langgraph langchain langchain-openai langchain-community chromadb openai python-dotenv&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;company_info.json&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;company_overview&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;topic&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;회사 소개&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;테크노바는 2020년에 설립된 AI 기반 솔루션을 제공하는 스타트업입니다. 서울 강남구에 본사를 두고 있으며, 현재 직원 수는 약 50명입니다.&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;main_product&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;topic&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;주력 제품&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;우리의 주력 제품은 &apos;SmartAssist&apos;라는 AI 챗봇 플랫폼입니다. 고객 서비스 자동화와 업무 효율성 향상을 위한 솔루션을 제공합니다.&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ceo_info&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;topic&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;대표이사&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;김철수 대표는 카이스트에서 인공지능을 전공했으며, 이전에 네이버에서 AI 연구원으로 근무했습니다. 10년 이상의 AI 개발 경험을 보유하고 있습니다.&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;office_location&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;topic&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;사무실 위치&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;본사는 서울특별시 강남구 테헤란로 123에 위치해 있습니다. 지하철 2호선 강남역에서 도보 5분 거리이며, 15층에 사무실이 있습니다.&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;work_hours&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;topic&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;근무 시간&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;근무 시간은 오전 9시부터 오후 6시까지이며, 코어타임은 오전 10시부터 오후 4시까지입니다. 주 5일 근무제를 시행하고 있습니다.&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;benefits&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;topic&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;복지 제도&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;직원들에게 최신형 맥북 프로와 듀얼 모니터를 제공하며, 점심 식대 지원, 간식 무제한 제공, 연 1회 워크샵, 도서 구입비 지원 등의 복지를 제공합니다.&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;tech_stack&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;topic&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;기술 스택&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;백엔드는 Python FastAPI와 Django를 사용하고, 프론트엔드는 React와 TypeScript를 사용합니다. AI 모델 학습에는 PyTorch를 주로 사용합니다.&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;team_structure&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;topic&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;팀 구조&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;회사는 크게 개발팀, 디자인팀, 영업팀, 마케팅팀으로 구성되어 있습니다. 개발팀이 가장 크며 약 30명의 엔지니어가 근무하고 있습니다.&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;funding&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;topic&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;투자 유치&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2023년에 시리즈 A 라운드에서 50억원의 투자를 유치했습니다. 주요 투자사는 카카오벤처스와 네이버 D2SF입니다.&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;clients&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;topic&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;주요 고객사&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;현재 삼성전자, LG전자, 현대자동차 등 대기업을 포함해 총 100여개의 고객사를 보유하고 있습니다.&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;라이브러리 Import&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; json
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; dotenv &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; load_dotenv
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; typing &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; TypedDict&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Literal

&lt;span class=&quot;token comment&quot;&gt;# LangChain 관련&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; langchain_openai &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; ChatOpenAI&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OpenAIEmbeddings
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; langchain_community&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vectorstores &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Chroma
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; langchain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;schema &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Document

&lt;span class=&quot;token comment&quot;&gt;# LangGraph 관련&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; langgraph&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;graph &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; StateGraph&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; END

&lt;span class=&quot;token comment&quot;&gt;# 환경 변수 로드&lt;/span&gt;
load_dotenv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;✅ 환경 설정 완료!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2&gt;1. Self-Correcting RAG 개요&lt;/h2&gt;
&lt;h3&gt;일반 RAG vs Self-Correcting RAG&lt;/h3&gt;
&lt;h4&gt;일반 RAG (3강):&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;질문 → 검색 → 답변 생성 → 끝&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Self-Correcting RAG (4강):&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;질문 → 질문 평가 → ❌ → 질문 재작성 → 다시 평가
         ↓ ✅
       검색 → 검색 평가 → ❌ → 쿼리 재작성 → 다시 검색
         ↓ ✅
     답변 생성 → 답변 평가 → ❌ → 문제 진단 → 해당 단계 복귀
         ↓ ✅
       최종 답변&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;일반 RAG의 한계&lt;/h3&gt;
&lt;h4&gt;1. 부정확한 검색&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;문제&lt;/strong&gt;: “우리 회사 휴가 정책은?” → 근무시간 문서 검색됨&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;원인&lt;/strong&gt;: 질문이 모호하거나 임베딩 매칭 실패&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;결과&lt;/strong&gt;: 잘못된 문서 기반 답변&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2. 관련 없는 문서 검색&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;문제&lt;/strong&gt;: 질문과 무관한 문서가 상위 검색됨&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;원인&lt;/strong&gt;: 키워드는 유사하지만 맥락이 다름&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;결과&lt;/strong&gt;: “문서에서 찾을 수 없습니다” (있는데도!)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;3. 불완전한 답변&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;문제&lt;/strong&gt;: 검색은 잘 됐는데 답변이 부정확&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;원인&lt;/strong&gt;: LLM이 문서를 잘못 해석하거나 환각(Hallucination)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;결과&lt;/strong&gt;: 신뢰할 수 없는 답변&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;4. 컨텍스트 부족&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;문제&lt;/strong&gt;: 여러 문서를 조합해야 하는 질문&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;원인&lt;/strong&gt;: Top-K 검색으로 중요한 문서 누락&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;결과&lt;/strong&gt;: 불완전한 답변&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Self-Correcting RAG의 해결책&lt;/h3&gt;
&lt;p&gt;✅ &lt;strong&gt;자동 검증 및 재시도&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;각 단계마다 품질 검증&lt;/li&gt;
&lt;li&gt;실패 시 자동으로 재시도&lt;/li&gt;
&lt;li&gt;최적의 결과 도출&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;✅ &lt;strong&gt;적응형 검색&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;검색 실패 시 쿼리 재작성&lt;/li&gt;
&lt;li&gt;다양한 검색 전략 시도&lt;/li&gt;
&lt;li&gt;관련성 점수 기반 필터링&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;✅ &lt;strong&gt;답변 검증&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;생성된 답변의 정확성 평가&lt;/li&gt;
&lt;li&gt;문서와의 일치도 확인&lt;/li&gt;
&lt;li&gt;환각 방지&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;2. 데이터 준비&lt;/h2&gt;
&lt;h3&gt;벡터 스토어 로드&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# JSON 파일에서 데이터 로드&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;company_info.json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;r&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; encoding&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;utf-8&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    company_data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;load&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Document 객체로 변환&lt;/span&gt;
documents &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; item &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; company_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    doc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Document&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        page_content&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;주제: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;topic&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;\n내용: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;content&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        metadata&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;topic&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;topic&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    documents&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 임베딩 및 벡터 스토어&lt;/span&gt;
embeddings &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; OpenAIEmbeddings&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;text-embedding-3-small&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

vectorstore &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Chroma&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    persist_directory&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;./chroma_db&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    embedding_function&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;embeddings&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    collection_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;company_info&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

retriever &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vectorstore&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;as_retriever&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;search_type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;similarity&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; search_kwargs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;k&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# LLM 초기화&lt;/span&gt;
llm &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ChatOpenAI&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gpt-4o-mini&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; temperature&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;✅ 준비 완료! 문서 수: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;vectorstore&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_collection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2&gt;3. State 정의&lt;/h2&gt;
&lt;p&gt;Self-Correcting RAG의 모든 상태를 관리하는 State를 정의합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SelfCorrectingRAGState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;TypedDict&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Self-Correcting RAG 워크플로우 상태&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# 입력&lt;/span&gt;
    original_question&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 원본 질문&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# 질문 처리&lt;/span&gt;
    current_question&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 현재 처리 중인 질문 (재작성될 수 있음)&lt;/span&gt;
    question_quality&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# &quot;good&quot; or &quot;bad&quot;&lt;/span&gt;
    question_rewrite_count&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 질문 재작성 횟수&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# 검색 처리&lt;/span&gt;
    search_query&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 검색 쿼리&lt;/span&gt;
    retrieved_docs&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 검색된 문서들&lt;/span&gt;
    retrieval_quality&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# &quot;relevant&quot; or &quot;irrelevant&quot;&lt;/span&gt;
    search_retry_count&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 검색 재시도 횟수&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# 답변 처리&lt;/span&gt;
    answer&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 생성된 답변&lt;/span&gt;
    answer_quality&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# &quot;good&quot; or &quot;bad&quot;&lt;/span&gt;
    problem_diagnosis&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 문제 진단 결과&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# 제어&lt;/span&gt;
    max_retries&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 최대 재시도 횟수&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2&gt;4. 노드 함수 구현&lt;/h2&gt;
&lt;h3&gt;Step 1: 질문 평가 노드&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;evaluate_question&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;질문이 명확하고 구체적인지 평가합니다.&quot;&quot;&quot;&lt;/span&gt;
    question &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;current_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    
    evaluation_prompt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;&quot;&quot;
다음 질문이 명확하고 구체적인지 평가해주세요.

질문: &quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;

평가 기준:
1. 질문이 무엇을 묻는지 명확한가?
2. 문맥 없이도 이해 가능한가?
3. 회사 정보에 대한 질문인가?

&quot;good&quot; 또는 &quot;bad&quot; 중 하나로만 답변하세요.
&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; llm&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;evaluation_prompt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    quality &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lower&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;good&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; quality&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        quality &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;good&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        quality &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bad&quot;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;🔍 [질문 평가] &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;   결과: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quality&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;**&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;question_quality&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; quality
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Step 2: 질문 재작성 노드&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rewrite_question&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;질문을 더 명확하고 구체적으로 재작성합니다.&quot;&quot;&quot;&lt;/span&gt;
    question &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;current_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    
    rewrite_prompt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;&quot;&quot;다음 질문을 더 명확하고 구체적으로 재작성해주세요.

원본 질문: &quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;

재작성 시 고려사항:
1. 회사 정보를 묻는 것이 명확하게 드러나도록
2. 애매한 표현 제거
3. 구체적인 정보 요청으로 변환

재작성된 질문만 답변하세요.
&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
    
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; llm&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rewrite_prompt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    rewritten &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;✏️ [질문 재작성]&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;   원본: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;   재작성: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;rewritten&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;**&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;current_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; rewritten&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;question_rewrite_count&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;question_rewrite_count&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Step 3: 문서 검색 노드&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;retrieve_documents&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;벡터 DB에서 관련 문서를 검색합니다.&quot;&quot;&quot;&lt;/span&gt;
    query &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;search_query&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;current_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    
    docs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; retriever&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;query&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;📚 [문서 검색] 쿼리: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;query&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;   검색된 문서 수: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;docs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; doc &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;docs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;   &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;. &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;metadata&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;topic&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;N/A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;**&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;retrieved_docs&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; docs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;search_query&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; query
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Step 4: 검색 결과 평가 노드&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;evaluate_retrieval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;검색된 문서가 질문과 관련있는지 평가합니다.&quot;&quot;&quot;&lt;/span&gt;
    question &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;current_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    docs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;retrieved_docs&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    
    docs_content &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;\n\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;문서 &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;page_content&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token format-spec&quot;&gt;100]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;...&quot;&lt;/span&gt;&lt;/span&gt; 
                                 &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; doc &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;docs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    evaluation_prompt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;&quot;&quot;다음 질문에 대해 검색된 문서들이 관련성이 있는지 평가해주세요.

질문: &quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;

검색된 문서들:
&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;docs_content&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;

평가 기준:
1. 문서에 질문에 답할 수 있는 정보가 포함되어 있는가?
2. 문서와 질문의 주제가 일치하는가?

&quot;relevant&quot; 또는 &quot;irrelevant&quot; 중 하나로만 답변하세요.
&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
    
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; llm&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;evaluation_prompt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    quality &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lower&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;relevant&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; quality&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        quality &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;relevant&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        quality &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;irrelevant&quot;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;✅ [검색 평가] 결과: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quality&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;**&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;retrieval_quality&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; quality
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Step 5: 검색 쿼리 재작성 노드&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rewrite_search_query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;더 나은 검색 결과를 위해 쿼리를 재작성합니다.&quot;&quot;&quot;&lt;/span&gt;
    question &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;current_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    previous_query &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;search_query&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; question&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    rewrite_prompt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;&quot;&quot;검색 결과가 부적절했습니다. 더 나은 검색 결과를 위해 쿼리를 재작성해주세요.

원본 질문: &quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;
이전 검색 쿼리: &quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;previous_query&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;

재작성 시 고려사항:
1. 핵심 키워드 강조
2. 동의어나 관련 용어 포함
3. 더 구체적인 표현 사용

재작성된 검색 쿼리만 답변하세요.
&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
    
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; llm&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rewrite_prompt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    new_query &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;🔄 [쿼리 재작성]&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;   이전: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;previous_query&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;   재작성: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;new_query&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;**&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;search_query&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; new_query&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;search_retry_count&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;search_retry_count&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Step 6: 답변 생성 노드&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;generate_answer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;검색된 문서를 바탕으로 답변을 생성합니다.&quot;&quot;&quot;&lt;/span&gt;
    question &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;current_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    docs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;retrieved_docs&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    
    context &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;\n\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;page_content &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; doc &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; docs&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    answer_prompt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;&quot;&quot;당신은 회사 정보를 안내하는 전문 AI 어시스턴트입니다.
아래 컨텍스트를 바탕으로 질문에 정확하고 친절하게 답변해주세요.

컨텍스트:
&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;

질문: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;

답변:&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
    
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; llm&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;answer_prompt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    answer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content
    
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;💬 [답변 생성] 완료&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;**&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;answer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; answer
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Step 7: 답변 평가 노드&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;evaluate_answer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;생성된 답변의 품질을 평가합니다.&quot;&quot;&quot;&lt;/span&gt;
    question &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;current_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    answer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;answer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    
    evaluation_prompt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;&quot;&quot;다음 답변의 품질을 평가해주세요.

질문: &quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;
답변: &quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;answer&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;

평가 기준:
1. 질문에 직접적으로 답변하는가?
2. 컨텍스트의 정보를 정확히 사용했는가?
3. 답변이 구체적이고 유용한가?
4. 환각(hallucination)이 없는가?

&quot;good&quot; 또는 &quot;bad&quot; 중 하나로만 답변하세요.
&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
    
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; llm&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;evaluation_prompt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    quality &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lower&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;good&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; quality&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        quality &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;good&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        quality &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bad&quot;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;⭐ [답변 평가] 결과: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quality&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;**&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;answer_quality&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; quality
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Step 8: 문제 진단 노드&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;diagnose_problem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;답변에 문제가 있을 때, 어디에서 문제가 발생했는지 진단합니다.&quot;&quot;&quot;&lt;/span&gt;
    question &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;current_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    docs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;retrieved_docs&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    answer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;answer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    
    docs_summary &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;- &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;metadata&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;topic&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;N/A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; doc &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; docs&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    diagnosis_prompt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;&quot;&quot;답변에 문제가 있습니다. 어디에서 문제가 발생했는지 진단해주세요.

질문: &quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;
검색된 문서들:
&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;docs_summary&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
생성된 답변: &quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;answer&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;

다음 중 하나를 선택하세요:
1. &quot;question_issue&quot; - 질문 자체에 문제가 있음 (애매하거나 불명확)
2. &quot;retrieval_issue&quot; - 검색된 문서가 부적절함
3. &quot;generation_issue&quot; - 답변 생성 과정에서 문제 발생

진단 결과만 답변하세요 (question_issue, retrieval_issue, generation_issue 중 하나).
&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
    
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; llm&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;diagnosis_prompt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    diagnosis &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lower&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;question&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; diagnosis&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        diagnosis &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;question_issue&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;retrieval&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; diagnosis&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        diagnosis &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;retrieval_issue&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        diagnosis &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;generation_issue&quot;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;🔧 [문제 진단] &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;diagnosis&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;**&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;problem_diagnosis&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; diagnosis
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2&gt;5. 라우팅 함수 정의&lt;/h2&gt;
&lt;p&gt;각 평가 결과에 따라 어디로 갈지 결정하는 함수들입니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;route_after_question_eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;질문 평가 후 라우팅&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;question_quality&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;good&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;retrieve&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;question_rewrite_count&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;max_retries&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;retrieve&quot;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 최대 재시도 도달, 그냥 진행&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rewrite_question&quot;&lt;/span&gt;


&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;route_after_retrieval_eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;검색 평가 후 라우팅&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;retrieval_quality&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;relevant&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;generate&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;search_retry_count&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;max_retries&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;generate&quot;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 최대 재시도 도달, 그냥 진행&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rewrite_query&quot;&lt;/span&gt;


&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;route_after_answer_eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;답변 평가 후 라우팅&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;answer_quality&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;good&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;end&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;diagnose&quot;&lt;/span&gt;


&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;route_after_diagnosis&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;문제 진단 후 라우팅&quot;&quot;&quot;&lt;/span&gt;
    diagnosis &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;problem_diagnosis&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; diagnosis &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;question_issue&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rewrite_question&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; diagnosis &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;retrieval_issue&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rewrite_query&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# generation_issue&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;generate&quot;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 답변만 다시 생성&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2&gt;6. 그래프 구성&lt;/h2&gt;
&lt;p&gt;모든 노드와 라우팅을 연결하여 완전한 Self-Correcting RAG 그래프를 만듭니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; IPython&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;display &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Image&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; display

&lt;span class=&quot;token comment&quot;&gt;# 그래프 생성&lt;/span&gt;
workflow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; StateGraph&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;SelfCorrectingRAGState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 노드 추가&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_node&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;evaluate_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; evaluate_question&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_node&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;rewrite_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rewrite_question&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_node&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;retrieve&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; retrieve_documents&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_node&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;evaluate_retrieval&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; evaluate_retrieval&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_node&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;rewrite_query&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rewrite_search_query&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_node&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;generate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; generate_answer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_node&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;evaluate_answer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; evaluate_answer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_node&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;diagnose&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; diagnose_problem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 시작점 설정&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;set_entry_point&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;evaluate_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 엣지 연결&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# 1. 질문 평가 → 조건부 분기&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_conditional_edges&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;evaluate_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    route_after_question_eval&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;retrieve&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;retrieve&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;rewrite_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rewrite_question&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 2. 질문 재작성 → 다시 평가&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_edge&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;rewrite_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;evaluate_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 3. 검색 → 검색 평가&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_edge&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;retrieve&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;evaluate_retrieval&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 4. 검색 평가 → 조건부 분기&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_conditional_edges&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;evaluate_retrieval&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    route_after_retrieval_eval&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;generate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;generate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;rewrite_query&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rewrite_query&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 5. 쿼리 재작성 → 다시 검색&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_edge&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;rewrite_query&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;retrieve&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 6. 답변 생성 → 답변 평가&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_edge&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;generate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;evaluate_answer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 7. 답변 평가 → 조건부 분기&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_conditional_edges&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;evaluate_answer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    route_after_answer_eval&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;end&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; END&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;diagnose&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;diagnose&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 8. 문제 진단 → 조건부 분기 (해당 단계로 복귀)&lt;/span&gt;
workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_conditional_edges&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;diagnose&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    route_after_diagnosis&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;rewrite_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rewrite_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;rewrite_query&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rewrite_query&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;generate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;generate&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 컴파일&lt;/span&gt;
app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; workflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;compile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;✅ Self-Correcting RAG 그래프 구성 완료!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

display&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Image&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_graph&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;draw_mermaid_png&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;워크플로우 구조:&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[시작]
  ↓
[질문 평가] → bad? → [질문 재작성] → [질문 평가]
  ↓ good
[문서 검색]
  ↓
[검색 평가] → irrelevant? → [쿼리 재작성] → [문서 검색]
  ↓ relevant
[답변 생성]
  ↓
[답변 평가] → bad? → [문제 진단] → question? → [질문 재작성]
  ↓ good              ↓              retrieval? → [쿼리 재작성]
[종료]                                generation? → [답변 생성]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2&gt;7. 실행 및 테스트&lt;/h2&gt;
&lt;h3&gt;헬퍼 함수&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ask_with_self_correction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; max_retries&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Self-Correcting RAG로 질문에 답변&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;\n&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;=&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;💭 원본 질문: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;=&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    initial_state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;original_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; question&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;current_question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; question&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;question_quality&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;question_rewrite_count&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;search_query&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;retrieved_docs&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;retrieval_quality&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;search_retry_count&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;answer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;answer_quality&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;problem_diagnosis&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;max_retries&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; max_retries
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# 실행&lt;/span&gt;
    result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;initial_state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;\n&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;=&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;✨ 최종 답변:&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;answer&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;=&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;\n📊 통계:&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;  - 질문 재작성 횟수: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;question_rewrite_count&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;  - 검색 재시도 횟수: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;search_retry_count&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;  - 최종 질문: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;current_question&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; result&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;테스트 실행&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;ask_with_self_correction&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;테크노바의 근무시간은 어떻게 돼?&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2&gt;주요 특징&lt;/h2&gt;
&lt;h3&gt;1. 다층 검증 시스템&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;질문 품질 검증&lt;/li&gt;
&lt;li&gt;검색 결과 검증&lt;/li&gt;
&lt;li&gt;답변 품질 검증&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 자동 복구 메커니즘&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;문제 발생 시 자동 재시도&lt;/li&gt;
&lt;li&gt;적절한 단계로 자동 복귀&lt;/li&gt;
&lt;li&gt;최대 재시도 횟수 제한&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 지능형 문제 진단&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;어느 단계에서 문제가 발생했는지 판단&lt;/li&gt;
&lt;li&gt;문제에 맞는 해결책 적용&lt;/li&gt;
&lt;li&gt;불필요한 재시도 방지&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;장단점&lt;/h2&gt;
&lt;h3&gt;장점&lt;/h3&gt;
&lt;p&gt;✅ 높은 답변 품질&lt;br&gt;
✅ 자동 오류 수정&lt;br&gt;
✅ 투명한 프로세스&lt;br&gt;
✅ 확장 가능한 구조&lt;/p&gt;
&lt;h3&gt;단점&lt;/h3&gt;
&lt;p&gt;❌ 응답 시간 증가&lt;br&gt;
❌ 높은 토큰 사용량&lt;br&gt;
❌ 복잡한 로직&lt;br&gt;
❌ LLM 호출 빈도 증가&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;실전 활용 팁&lt;/h2&gt;
&lt;h3&gt;1. 최대 재시도 횟수 조정&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;품질 우선: &lt;code class=&quot;language-text&quot;&gt;max_retries=3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;속도 우선: &lt;code class=&quot;language-text&quot;&gt;max_retries=1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 평가 기준 커스터마이징&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;도메인별 평가 기준 추가&lt;/li&gt;
&lt;li&gt;품질 임계값 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 캐싱 활용&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;동일 질문 결과 저장&lt;/li&gt;
&lt;li&gt;검색 결과 재사용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. 모니터링 추가&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;각 단계별 소요 시간 측정&lt;/li&gt;
&lt;li&gt;재시도 빈도 분석&lt;/li&gt;
&lt;li&gt;실패 원인 로깅&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;결론&lt;/h2&gt;
&lt;p&gt;Self-Correcting RAG는 일반 RAG의 한계를 극복하는 강력한 시스템입니다. 자동 검증과 수정 메커니즘을 통해 높은 품질의 답변을 제공하며, LangGraph의 유연한 구조로 쉽게 확장할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;핵심 포인트:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;각 단계마다 품질을 검증하고 필요시 자동으로 수정&lt;/li&gt;
&lt;li&gt;문제 발생 지점을 정확히 진단하여 효율적으로 대응&lt;/li&gt;
&lt;li&gt;최대 재시도 횟수 설정으로 무한 루프 방지&lt;/li&gt;
&lt;li&gt;투명한 프로세스로 디버깅과 개선이 용이&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 시스템을 기반으로 도메인 특화 평가 기준을 추가하거나, 더 정교한 검색 전략을 구현할 수 있습니다!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[LangChain으로 구현하는 RAG 시스템 실습]]></title><description><![CDATA[LangChain으로 구현하는 RAG 시스템 실습 이번 실습에서는 LangChain을 활용하여 완전한 RAG 시스템을 구축해봅니다. 회사 정보를 담은 JSON 데이터를 기반으로 질문에 답변하는 AI 챗봇을 만들어볼게요!…]]></description><link>https://sooftware.github.io/langchain/</link><guid isPermaLink="false">https://sooftware.github.io/langchain/</guid><pubDate>Fri, 10 Oct 2025 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;LangChain으로 구현하는 RAG 시스템 실습&lt;/h1&gt;
&lt;p&gt;이번 실습에서는 LangChain을 활용하여 완전한 RAG 시스템을 구축해봅니다.&lt;br&gt;
회사 정보를 담은 JSON 데이터를 기반으로 질문에 답변하는 AI 챗봇을 만들어볼게요!&lt;/p&gt;
&lt;h2&gt;0. 환경설정&lt;/h2&gt;
&lt;h3&gt;필요한 라이브러리 설치&lt;/h3&gt;
&lt;p&gt;먼저 터미널에서 필요한 패키지들을 설치합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;pip &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; langchain langchain-openai langchain-community chromadb openai python-dotenv langsmith faiss-cpu&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;라이브러리 Import 및 API 키 설정&lt;/h3&gt;
&lt;p&gt;먼저 .env 파일을 생성하여 API 키를 관리합니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# .env 파일
OPENAI_API_KEY=sk-your-openai-api-key
LANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=ls_your-langsmith-api-key
LANGCHAIN_PROJECT=langchain-rag-tutorial&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; json
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; dotenv &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; load_dotenv
&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; langsmith &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; traceable
    LANGSMITH_AVAILABLE &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;✅ LangSmith 추적 활성화!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;except&lt;/span&gt; ImportError&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    LANGSMITH_AVAILABLE &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 환경 변수 로드&lt;/span&gt;
load_dotenv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;✅ 환경 설정 완료!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;✅ LangSmith 추적 활성화!
✅ 환경 설정 완료!&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;💡 LangSmith란?&lt;/h3&gt;
&lt;p&gt;LangSmith는 LangChain 애플리케이션의 실행을 추적하고 모니터링하는 도구입니다. 각 단계별 실행 시간, 입출력, 비용 등을 시각적으로 확인할 수 있어 디버깅과 최적화에 매우 유용합니다!&lt;br&gt;
LangSmith API 키는 &lt;a href=&quot;https://smith.langchain.com%EC%97%90%EC%84%9C&quot;&gt;https://smith.langchain.com에서&lt;/a&gt; 무료로 발급받을 수 있습니다.&lt;/p&gt;
&lt;h2&gt;1. 사전 준비 단계&lt;/h2&gt;
&lt;h3&gt;Document Loader (문서 로드)&lt;/h3&gt;
&lt;p&gt;이 단계에서는 외부 데이터 소스에서 필요한 문서를 로드하고 초기 처리를 합니다.&lt;br&gt;
이번 예제에서는 회사 정보를 담은 JSON 파일을 로드해서 진행해보겠습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# JSON 파일에서 데이터 로드&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;company_info.json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;r&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; encoding&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;utf-8&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    company_data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;load&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;✅ 총 &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;company_data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;개의 데이터 로드 완료!&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;\n첫 번째 데이터 예시:&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;json&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dumps&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;company_data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ensure_ascii&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; indent&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;✅ 총 20개의 데이터 로드 완료!

첫 번째 데이터 예시:
{
  &quot;id&quot;: &quot;company_overview&quot;,
  &quot;topic&quot;: &quot;회사 소개&quot;,
  &quot;content&quot;: &quot;테크노바는 2020년에 설립된 AI 기반 솔루션을 제공하는 스타트업입니다. 서울 강남구에 본사를 두고 있으며, 현재 직원 수는 약 50명입니다.&quot;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Document 객체로 변환&lt;/h3&gt;
&lt;p&gt;LangChain에서 사용할 수 있도록 데이터를 Document 형식으로 변환합니다.
Document는 page_content(본문)와 metadata(메타데이터)로 구성됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; langchain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;schema &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Document

documents &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; item &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; company_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    doc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Document&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        page_content&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;Topic: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;topic&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;\nContent: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;content&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        metadata&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;topic&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;topic&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    documents&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;✅ &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;documents&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;개의 Document 객체 생성 완료!\n&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;첫 번째 Document 예시:&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;내용: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;documents&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;page_content&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;메타데이터: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;documents&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;metadata&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;✅ 20개의 Document 객체 생성 완료!

첫 번째 Document 예시:
내용: Topic: 회사 소개
Content: 테크노바는 2020년에 설립된 AI 기반 솔루션을 제공하는 스타트업입니다. 서울 강남구에 본사를 두고 있으며, 현재 직원 수는 약 50명입니다.
메타데이터: {&apos;id&apos;: &apos;company_overview&apos;, &apos;topic&apos;: &apos;회사 소개&apos;}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;2. Text Splitting (텍스트 분할)&lt;/h2&gt;
&lt;h3&gt;왜 텍스트를 분할하나요?&lt;/h3&gt;
&lt;p&gt;긴 문서를 그대로 사용하면 검색 정확도가 떨어집니다. 큰 책을 작은 챕터로 나누듯이, 문서를 적절한 크기의 청크(chunk)로 분할하면 더 정확한 검색이 가능합니다.&lt;/p&gt;
&lt;p&gt;예를 들어, “회사 위치가 어디인가요?”라는 질문에 대해 전체 문서 대신 회사 정보만 담긴 작은 청크를 검색할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; langchain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text_splitter &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; RecursiveCharacterTextSplitter

text_splitter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; RecursiveCharacterTextSplitter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    chunk_size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;      &lt;span class=&quot;token comment&quot;&gt;# 청크 하나당 최대 200자&lt;/span&gt;
    chunk_overlap&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;# 청크 간 50자 겹침 (문맥 유지)&lt;/span&gt;
    length_function&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

splits &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; text_splitter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split_documents&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;documents&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;✅ 텍스트 분할 완료!&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;원본 문서 수: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;documents&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;분할 후 청크 수: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;splits&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;✅ 텍스트 분할 완료!
원본 문서 수: 20
분할 후 청크 수: 20&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;💡 &lt;strong&gt;Tip:&lt;/strong&gt; 이 예시에서는 문서가 짧아 분할이 크게 일어나지 않지만, 실제로 긴 문서를 다룰 때는 여러 개의 청크로 나뉩니다.&lt;/p&gt;
&lt;h2&gt;3. Embedding (임베딩)&lt;/h2&gt;
&lt;h3&gt;임베딩이란?&lt;/h3&gt;
&lt;p&gt;임베딩은 텍스트를 숫자 벡터로 변환하는 과정입니다. 컴퓨터는 텍스트의 의미를 직접 이해할 수 없기 때문에, 수치로 표현해야 합니다.&lt;br&gt;
비슷한 의미를 가진 텍스트는 벡터 공간에서 가까운 위치에 배치됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“회사 위치” ≈ “사무실 주소”&lt;/li&gt;
&lt;li&gt;“대표 이름” ≈ “CEO는 누구”&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; langchain_openai &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; OpenAIEmbeddings

&lt;span class=&quot;token comment&quot;&gt;# OpenAI 임베딩 모델 초기화&lt;/span&gt;
embeddings &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; OpenAIEmbeddings&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;text-embedding-3-small&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 테스트: 샘플 텍스트 임베딩&lt;/span&gt;
sample_text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;회사 위치가 어디인가요?&quot;&lt;/span&gt;
sample_embedding &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; embeddings&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;embed_query&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sample_text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;✅ 임베딩 모델 초기화 완료!&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;\n샘플 텍스트: &apos;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sample_text&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;임베딩 벡터 차원: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sample_embedding&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;임베딩 벡터 일부: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sample_embedding&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token format-spec&quot;&gt;5]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;✅ 임베딩 모델 초기화 완료!

샘플 텍스트: &apos;회사 위치가 어디인가요?&apos;
임베딩 벡터 차원: 1536
임베딩 벡터 일부: [0.015228848904371262, 0.012781930156052113, 0.05640791356563568, 0.05310242623090744, 0.013790748082101345]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;4. Vector Store (벡터 저장소)&lt;/h2&gt;
&lt;h3&gt;Chroma DB에 저장하기&lt;/h3&gt;
&lt;p&gt;임베딩된 벡터들을 저장하고 검색할 수 있는 데이터베이스를 만듭니다.&lt;br&gt;
도서관의 색인 시스템과 비슷합니다. 책의 내용을 분류하고 저장해두면, 나중에 원하는 정보를 빠르게 찾을 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; langchain_community&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vectorstores &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Chroma

&lt;span class=&quot;token comment&quot;&gt;# 벡터 스토어 생성&lt;/span&gt;
vectorstore &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Chroma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_documents&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    documents&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;splits&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    embedding&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;embeddings&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    collection_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;company_info&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    persist_directory&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;./chroma_db&quot;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 로컬에 저장&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;✅ Chroma 벡터 스토어 생성 완료!&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;저장된 문서 수: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;vectorstore&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_collection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;✅ Chroma 벡터 스토어 생성 완료!
저장된 문서 수: 40&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;💡 &lt;strong&gt;Chroma의 장점:&lt;/strong&gt; 별도의 저장 명령 없이 persist_directory를 지정하면 자동으로 디스크에 저장됩니다!&lt;/p&gt;
&lt;p&gt;⚠️ &lt;strong&gt;주의:&lt;/strong&gt; 기존 DB가 있으면 스키마 충돌이 발생할 수 있으니, 처음 실행 시 기존 폴더를 삭제하거나 다른 collection_name을 사용하세요.&lt;/p&gt;
&lt;h2&gt;5. Retriever (검색기)&lt;/h2&gt;
&lt;h3&gt;다양한 검색 방식 이해하기&lt;/h3&gt;
&lt;p&gt;Retriever는 질문과 가장 유사한 문서를 찾아주는 역할을 합니다.&lt;br&gt;
여러 가지 검색 옵션을 제공합니다.&lt;/p&gt;
&lt;h3&gt;방법 1: 기본 유사도 검색 (Similarity Search)&lt;/h3&gt;
&lt;p&gt;가장 유사한 상위 k개의 문서를 반환합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 기본 Retriever 설정&lt;/span&gt;
retriever_basic &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vectorstore&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;as_retriever&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    search_type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;similarity&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    search_kwargs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;k&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 상위 3개 문서 검색&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;✅ 기본 Retriever 설정 완료!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 테스트&lt;/span&gt;
test_query &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;회사 팀은 어떻게 구성되어 있나요?&quot;&lt;/span&gt;
retrieved_docs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; retriever_basic&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;test_query&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;\n테스트 질문: &apos;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;test_query&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;검색된 문서 수: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;retrieved_docs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;\n가장 관련성 높은 문서:&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;retrieved_docs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;page_content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;✅ 기본 Retriever 설정 완료!

테스트 질문: &apos;회사 팀은 어떻게 구성되어 있나요?&apos;
검색된 문서 수: 3

가장 관련성 높은 문서:
회사는 크게 개발팀, 디자인팀, 영업팀, 마케팅팀으로 구성되어 있습니다. 개발팀이 가장 크며 약 30명의 엔지니어가 근무하고 있습니다.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;방법 2: 유사도 점수 임계값 검색 (Similarity Score Threshold)&lt;/h3&gt;
&lt;p&gt;일정 유사도 이상인 문서만 검색합니다. 관련성이 낮은 문서를 필터링할 때 유용합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 유사도 임계값 Retriever&lt;/span&gt;
retriever_threshold &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vectorstore&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;as_retriever&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    search_type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;similarity_score_threshold&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    search_kwargs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;score_threshold&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 유사도 0.3 이상만 반환&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;k&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 최대 5개까지&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;✅ 유사도 임계값 Retriever 설정 완료!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 테스트&lt;/span&gt;
test_query &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;회사의 주요 고객사는 어떻게 되나요?&quot;&lt;/span&gt;
retrieved_docs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; retriever_threshold&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;test_query&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;\n테스트 질문: &apos;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;test_query&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;유사도 0.3 이상인 문서 수: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;retrieved_docs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; doc &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;retrieved_docs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;  [&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;] &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;metadata&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;topic&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;N/A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;✅ 유사도 임계값 Retriever 설정 완료!

테스트 질문: &apos;회사의 주요 고객사는 어떻게 되나요?&apos;
유사도 0.3 이상인 문서 수: 1
  [1] 주요 고객사&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;방법 3: MMR (Maximum Marginal Relevance)&lt;/h3&gt;
&lt;p&gt;유사도가 높으면서도 다양성을 보장하는 검색 방식입니다. 비슷한 내용의 문서가 중복으로 검색되는 것을 방지합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# MMR Retriever&lt;/span&gt;
retriever_mmr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vectorstore&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;as_retriever&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    search_type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;mmr&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    search_kwargs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;k&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 최종적으로 4개 반환&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;fetch_k&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 먼저 10개를 가져온 후&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;lambda_mult&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 다양성 조절 (0=다양성 우선, 1=유사도 우선)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;✅ MMR Retriever 설정 완료!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 테스트&lt;/span&gt;
test_query &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;회사의 주요 고객사는 어떻게 되나요?&quot;&lt;/span&gt;
retrieved_docs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; retriever_mmr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;test_query&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;\n테스트 질문: &apos;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;test_query&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;MMR로 검색된 다양한 문서들:&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; doc &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;retrieved_docs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;  [&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;] &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;metadata&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;topic&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;N/A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;✅ MMR Retriever 설정 완료!

테스트 질문: &apos;회사의 주요 고객사는 어떻게 되나요?&apos;
MMR로 검색된 다양한 문서들:
  [1] 주요 고객사
  [2] 팀 구조
  [3] 회사 문화
  [4] 복지 제도&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;이번 실습에서는 기본 유사도 검색을 사용하겠습니다.&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 실습용 Retriever&lt;/span&gt;
retriever &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vectorstore&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;as_retriever&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    search_type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;similarity&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    search_kwargs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;k&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;✅ 실습용 Retriever 설정 완료!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;✅ 실습용 Retriever 설정 완료!&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;6. LLM 초기화 및 프롬프트 작성&lt;/h2&gt;
&lt;h3&gt;ChatGPT 모델 설정&lt;/h3&gt;
&lt;p&gt;검색된 문서를 바탕으로 자연스러운 답변을 생성할 LLM을 초기화합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; langchain_openai &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; ChatOpenAI

llm &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ChatOpenAI&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gpt-4o-mini&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    temperature&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.7&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;✅ LLM 모델 초기화 완료!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;✅ LLM 모델 초기화 완료!&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;프롬프트 템플릿 작성&lt;/h3&gt;
&lt;p&gt;RAG 시스템이 어떻게 답변할지 가이드를 제공하는 프롬프트 템플릿을 작성합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; langchain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prompts &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; PromptTemplate

prompt_template &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;
당신은 회사 정보를 안내하는 친절한 AI 어시스턴트입니다.
제공된 컨텍스트를 기반으로 질문에 답변해주세요.
컨텍스트에 정보가 없다면 &quot;죄송하지만 해당 정보는 제공되지 않았습니다&quot;라고 답변하세요.
답변은 친근하고 따뜻한 톤으로 작성해주세요.

컨텍스트:
{context}

질문: {question}

답변:
&quot;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

PROMPT &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; PromptTemplate&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    template&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;prompt_template&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    input_variables&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;context&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;✅ 프롬프트 템플릿 작성 완료!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;✅ 프롬프트 템플릿 작성 완료!&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;7. RAG Chain 구성&lt;/h2&gt;
&lt;h3&gt;LCEL(LangChain Expression Language)로 체인 만들기&lt;/h3&gt;
&lt;p&gt;이제 파이프(|) 연산자를 사용하여 RAG 체인을 만들어봅시다.&lt;br&gt;
파이프 연산자는 데이터가 흐르는 방향을 명확하게 보여줍니다. 마치 공장의 컨베이어 벨트처럼 각 단계를 거쳐 최종 결과물이 만들어집니다!&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; langchain_core&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;runnables &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; RunnablePassthrough
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; langchain_core&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;output_parsers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; StrOutputParser

&lt;span class=&quot;token comment&quot;&gt;# RAG 체인 구성&lt;/span&gt;
rag_chain &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;context&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; retriever&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 질문과 관련된 문서 검색&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;question&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; RunnablePassthrough&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 질문을 그대로 전달&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; PROMPT  &lt;span class=&quot;token comment&quot;&gt;# 프롬프트 템플릿에 context와 question 삽입&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; llm  &lt;span class=&quot;token comment&quot;&gt;# LLM이 답변 생성&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; StrOutputParser&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 문자열로 파싱&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;✅ RAG 체인 구성 완료!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;✅ RAG 체인 구성 완료!&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;데이터 흐름 이해하기:&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;사용자 질문
    ↓
① {&quot;context&quot;: 검색된 문서들, &quot;question&quot;: 원본 질문}
    ↓
② PROMPT (프롬프트에 context와 question이 들어감)
    ↓
③ LLM (답변 생성)
    ↓
④ StrOutputParser (문자열로 변환)
    ↓
최종 답변&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;💡 &lt;strong&gt;LCEL이란?&lt;/strong&gt; LangChain Expression Language의 약자로, | 연산자로 각 단계를 연결하는 직관적인 방식입니다. 각 컴포넌트가 순서대로 실행되며, 앞 단계의 출력이 다음 단계의 입력으로 자동으로 전달됩니다!&lt;/p&gt;
&lt;h3&gt;Invoke 메서드로 체인 실행하기&lt;/h3&gt;
&lt;p&gt;체인을 실행하는 방법은 여러 가지가 있습니다.&lt;/p&gt;
&lt;h3&gt;방법 1: invoke() - 단일 실행&lt;/h3&gt;
&lt;p&gt;가장 기본적인 실행 방법입니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 단일 질문 실행&lt;/span&gt;
question &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;회사는 언제 설립되었나요?&quot;&lt;/span&gt;
answer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; rag_chain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;질문: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;답변: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;answer&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;질문: 회사는 언제 설립되었나요?
답변: 테크노바는 2020년에 설립되었습니다! 궁금한 점이 더 있으시면 언제든지 말씀해 주세요.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;방법 2: batch() - 여러 질문 동시 실행&lt;/h3&gt;
&lt;p&gt;여러 질문을 한 번에 처리할 때 효율적입니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 여러 질문 동시 실행&lt;/span&gt;
questions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;주력 제품은 무엇인가요?&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;사무실은 어디에 있나요?&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;근무 시간은 어떻게 되나요?&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

answers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; rag_chain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;batch&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;questions&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; q&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; a &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;questions&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; answers&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;\nQ: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;q&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;A: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Q: 주력 제품은 무엇인가요?
A: 우리의 주력 제품은 &apos;SmartAssist&apos;라는 AI 챗봇 플랫폼입니다. 이 플랫폼은 고객 서비스 자동화와 업무 효율성 향상을 위한 훌륭한 솔루션을 제공합니다. 더 궁금한 점이 있으시면 언제든지 말씀해 주세요!

Q: 사무실은 어디에 있나요?
A: 안녕하세요! 저희 사무실은 서울특별시 강남구 테헤란로 123에 위치해 있습니다. 지하철 2호선 강남역에서 도보로 약 5분 거리에 있으며, 15층에 있습니다. 언제든지 방문해 주세요! 😊

Q: 근무 시간은 어떻게 되나요?
A: 안녕하세요! 근무 시간은 오전 9시부터 오후 6시까지이며, 코어타임은 오전 10시부터 오후 4시까지입니다. 주 5일 근무제를 시행하고 있어요. 궁금한 점이 더 있으면 언제든지 말씀해 주세요!&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;방법 3: stream() - 스트리밍 응답&lt;/h3&gt;
&lt;p&gt;답변이 생성되는 과정을 실시간으로 볼 수 있습니다. ChatGPT처럼 글자가 하나씩 나타나는 효과를 만들 때 유용합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 스트리밍 실행&lt;/span&gt;
question &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;회사의 복지 제도는 어떤가요?&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;질문: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;답변: &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; end&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; chunk &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; rag_chain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;stream&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;chunk&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; end&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; flush&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;질문: 회사의 복지 제도는 어떤가요?
답변: 회사의 복지 제도는 정말 훌륭해요! 직원들에게 최신형 맥북 프로와 듀얼 모니터를 제공하고, 점심 식대를 지원하며 간식도 무제한으로 제공됩니다. 또한, 연 1회 워크샵과 도서 구입비 지원도 있어 직원들이 더욱 성장할 수 있도록 도와주고 있어요. 정말 든든한 지원이죠!&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;8. RAG 시스템 테스트&lt;/h2&gt;
&lt;h3&gt;질문 함수 만들기&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ask_question&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;질문에 대한 답변과 출처를 출력하는 함수&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;\n&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;=&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;❓ 질문: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;=&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# 답변 생성&lt;/span&gt;
    answer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; rag_chain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;# 검색된 문서 확인 (별도로 retriever 호출)&lt;/span&gt;
    retrieved_docs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; retriever&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;question&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;\n💬 답변:\n&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;answer&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;\n📚 참고한 문서:&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; doc &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;retrieved_docs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;\n  [&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;] &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;metadata&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;topic&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;N/A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;      &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;page_content&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token format-spec&quot;&gt;80]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;...&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; answer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; retrieved_docs&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;다양한 질문으로 테스트&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 테스트 1: 회사 소개&lt;/span&gt;
ask_question&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;회사 팀 구조는 어떻게 되나요?&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;============================================================
❓ 질문: 회사 팀 구조는 어떻게 되나요?
============================================================

💬 답변:
회사의 팀 구조는 크게 개발팀, 디자인팀, 영업팀, 마케팅팀으로 구성되어 있어요. 그중에서도 개발팀이 가장 크며, 약 30명의 엔지니어가 함께 일하고 있답니다. 도움이 더 필요하시면 언제든지 말씀해 주세요!

📚 참고한 문서:

  [1] 팀 구조
      회사는 크게 개발팀, 디자인팀, 영업팀, 마케팅팀으로 구성되어 있습니다. 개발팀이 가장 크며 약 30명의 엔지니어가 근무하고 있습니다....

  [2] 팀 구조
      Topic: 팀 구조
Content: 회사는 크게 개발팀, 디자인팀, 영업팀, 마케팅팀으로 구성되어 있습니다. 개발팀이 가장 크며 약 30명의 ...

  [3] 회사 소개
      Topic: 회사 소개
Content: 테크노바는 2020년에 설립된 AI 기반 솔루션을 제공하는 스타트업입니다. 서울 강남구에 본사를 두고 있...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 테스트 2: 데이터에 있는 정보&lt;/span&gt;
ask_question&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;투자는 얼마나 받았나요?&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;============================================================
❓ 질문: 투자는 얼마나 받았나요?
============================================================

💬 답변:
2023년에 시리즈 A 라운드에서 50억원의 투자를 유치했습니다! 정말 멋진 성과네요!

📚 참고한 문서:

  [1] 투자 유치
      Topic: 투자 유치
Content: 2023년에 시리즈 A 라운드에서 50억원의 투자를 유치했습니다. 주요 투자사는 카카오벤처스와 네이버 D...

  [2] 투자 유치
      2023년에 시리즈 A 라운드에서 50억원의 투자를 유치했습니다. 주요 투자사는 카카오벤처스와 네이버 D2SF입니다....

  [3] 성장 현황
      설립 이후 매년 100% 이상의 성장률을 기록하고 있으며, 2024년 목표 매출은 100억원입니다. 해외 진출도 계획하고 있습니다....&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;인터랙티브 채팅&lt;/h2&gt;
&lt;h3&gt;대화형 인터페이스&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;interactive_chat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;사용자와 대화하는 인터랙티브 모드&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;\n&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;=&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;🤖 RAG 챗봇이 준비되었습니다!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;질문을 입력하세요. (종료하려면 &apos;quit&apos; 입력)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;=&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        user_question &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;\n질문: &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; user_question&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lower&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;quit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;exit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;q&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;종료&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;\n챗봇을 종료합니다. 감사합니다! 👋&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; user_question&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;continue&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            answer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; rag_chain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;user_question&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;\n🤖 답변: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;answer&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;except&lt;/span&gt; Exception &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;\n❌ 오류 발생: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 실행&lt;/span&gt;
interactive_chat&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;출력:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;============================================================
🤖 RAG 챗봇이 준비되었습니다!
질문을 입력하세요. (종료하려면 &apos;quit&apos; 입력)
============================================================

질문: 최근 성장 현황이 어떤가요?

🤖 답변: 안녕하세요! 최근 성장 현황에 대해 알려드릴게요. 설립 이후 매년 100% 이상의 성장률을 기록하고 있으며, 2024년 목표 매출은 100억원으로 설정되어 있습니다. 또한 해외 진출도 계획하고 있다는 긍정적인 소식이 있습니다. 더 궁금한 점이 있으시면 언제든지 말씀해 주세요!

질문: 투자쪽은 어때요?

🤖 답변: 안녕하세요! 투자 쪽에 대한 정보가 있어요. 2023년에 시리즈 A 라운드에서 50억원의 투자를 유치했답니다. 주요 투자사로는 카카오벤처스와 네이버 D2SF가 있죠. 더 궁금한 점이 있으시면 언제든지 물어보세요! 😊

질문: quit

챗봇을 종료합니다. 감사합니다! 👋&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;마무리&lt;/h2&gt;
&lt;p&gt;이번 실습에서는 LangChain을 사용하여 완전한 RAG 시스템을 구축해보았습니다. 주요 단계를 요약하면:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Document Loading&lt;/strong&gt;: JSON 데이터를 LangChain Document 형식으로 변환&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Text Splitting&lt;/strong&gt;: 문서를 검색 가능한 청크로 분할&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Embedding&lt;/strong&gt;: 텍스트를 벡터로 변환&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vector Store&lt;/strong&gt;: Chroma DB에 벡터 저장&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Retriever&lt;/strong&gt;: 유사도 기반 문서 검색&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM &amp;#x26; Prompt&lt;/strong&gt;: GPT 모델과 프롬프트 설정&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RAG Chain&lt;/strong&gt;: LCEL로 전체 파이프라인 구성&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Testing&lt;/strong&gt;: 다양한 방식으로 시스템 테스트&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title><![CDATA[Throwback 2024]]></title><description><![CDATA[Throwback 2024 Throwback 2024 2020년 회고 글 2021년 회고 글 2023년 회고 글 어느덧 4번째 1년 회고글이자, 5년차 회고글입니다! 2024년은 유독 길게 느껴졌습니다. 202…]]></description><link>https://sooftware.github.io/2024/</link><guid isPermaLink="false">https://sooftware.github.io/2024/</guid><pubDate>Wed, 01 Jan 2025 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Throwback 2024&lt;/h1&gt;
&lt;h1&gt;Throwback 2024&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://sooftware.github.io/2020/&quot;&gt;2020년 회고 글&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sooftware.github.io/2021/&quot;&gt;2021년 회고 글&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sooftware.github.io/2023/&quot;&gt;2023년 회고 글&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;어느덧 4번째 1년 회고글이자, 5년차 회고글입니다! 2024년은 유독 길게 느껴졌습니다. 2024년은 회사에서도 많은 일들이 있었고, 개인적으로도 많은 일들이 있었던 한 해였습니다. 힘들면서도 많은 성장을 할 수 있었고, 많은 추억 또한 남긴 한 해였습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;🏢 SAMSUNG C-Lab Outside&lt;/h2&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/1875eb75-6265-4c99-a30a-b1c56802281f&quot; width=&quot;400&quot;&gt;
&lt;p&gt;올해 저희 튜닙이 C-Lab Outside에 선정됐습니다. C-Lab Outside는 매년 삼성에서 뽑는 스타트업 육성 프로그램입니다. C-Lab 혜택으로 1억의 지원금과 ‘삼성 서울 R&amp;#x26;D 캠퍼스’에 사무실이 지원됐습니다. 기존 사무실은 판교에 있었기에 올해 초 사무실을 이전하게 되었습니다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/058bc0f1-7239-4362-a144-827b752b1008&quot; width=&quot;350&quot;&gt;
&lt;p&gt;사무실이 판교에서 양재로 멀어져서 출퇴근 시간이 길어지는 게 걱정됐는데 다행히 삼성에서 출퇴근 셔틀버스를 운영해서 편하게 다닐 수 있었습니다! 제가 사는 동네는 출근 버스가 6:40 한 타임밖에 없어서 기존보다 훨씬 일찍 일어나긴 했지만요 🥲&lt;/p&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/02362678-217a-4d05-83c5-05386a166de7&quot; width=&quot;350&quot;&gt;
&lt;p&gt;머슴짓도 대감 집에서 해야된다더니, 삼성 밥을 먹으며 이 말이 크게 체감됐습니다. 😭&lt;/p&gt;
&lt;p&gt;매일 밥 먹을때마다 맛있는 메뉴들 중 뭘 먹을지 골라먹는 호사를 누릴 수 있었습니다. 아침 / 저녁에는 밥 대신에 코인샵에 가서 5코인 내로 음료, 간식, 샐러드, 과일 중 알아서 골라서 가져갈 수 있었는데, 출퇴근할때 코인샵 들려서 필요한거 골라서 가는 재미가 쏠쏠했습니다.&lt;/p&gt;
&lt;img width=&quot;450&quot; alt=&quot;image&quot; src=&quot;https://github.com/user-attachments/assets/c46b074b-baef-41ac-8d16-48a91403651b&quot;&gt;
&lt;p&gt;C-Lab 사무실 지원이 2024년까지라 말일인 12/31에 양재 AI Hub 사무실로 또 한 번 이사를 했습니다. 사무실은 크게 아쉽지 않지만 삼성에서 주던 맛있는 밥과 코인샵은 그리울 것 같습니다.&lt;/p&gt;
&lt;p&gt;카카오에서 나와 네이버 D2, 삼성 C-Lab을 거쳐서 이번에는 양재 AI Hub까지 여러 문화를 체험할 수 있었습니다. 단점으로 볼 수도 있겠지만, 이렇게 다양한 경험이 가능한것도 스타트업의 장점이라고 생각합니다. 😎&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;The Startup Valley of Death&lt;/h2&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/e38ede00-0240-4e5f-b0ad-fe9a62c6b4c3&quot; width=&quot;400&quot;&gt;
&lt;p&gt;초기 스타트업이 3년차에 힘들다는 말이 있습니다. 이를 흔히 Valley of Death라고 합니다. 저희만은 다를거라 생각했지만 애석하게도 저희 역시 3년차가 되기 무섭게 여러 위기에 맞닥뜨렸습니다.&lt;/p&gt;
&lt;p&gt;올해 초에 대대적인 정부의 R&amp;#x26;D 예산 삭감이 있었습니다. 저희 튜닙은 2021, 2022 AI 온라인 경진대회, 2022 AI Grand Challenge 등을 통해 정부로부터 꽤 많은 지원금을 받았습니다. R&amp;#x26;D 마피아 같은 말들이 있지만 저희는 정부에서 주최한 대회에 나가서 당당히 입상하고 지원금을 따냈기 때문에 이러한 예산 삭감이 당장 저희가 진행 중인 과제와는 연관이 없을 거라고 생각했습니다.&lt;/p&gt;
&lt;p&gt;하지만 ‘2022 AI 그랜드 챌린지’로 2024년에 지원받기로 약속된 10억원 중 80%가 삭감되어 2억원만 지원해줄 수 있다는 통보가 날라왔습니다. (나중에 알고보니 저희 과제가 가장 큰 폭으로 삭감됐다고 합니다..)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;관련 기사 : &lt;a href=&quot;https://zdnet.co.kr/view/?no=20240702133834&quot;&gt;https://zdnet.co.kr/view/?no=20240702133834&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/bf584990-22e5-429d-83d4-3a607ce68a48&quot; width=&quot;350&quot;&gt;
&lt;p&gt;갑작스러운 통보에 이미 짜여진 2024년 예산안을 뒤엎을 수 밖에 없었습니다.&lt;/p&gt;
&lt;p&gt;당시에 주위 여러 스타트업들에서 구조조정, 권고사직, 폐업과 같은 말들이 많이 들렸었지만 저희와는 상관 없다고 생각했던게 무색했습니다.&lt;/p&gt;
&lt;p&gt;이러한 상황 속에서 회사 내부 분위기는 뒤숭숭했고, 회사의 좋지 않은 상황과 구성원들의 이직 시기가 맞물리며 많은 분들이 퇴직/이직을 하게 됐습니다. 그동안 많은 분들이 퇴사하긴 했지만, 이렇게 한 번에 많은 분들이 퇴사하게 되는 경우는 없었습니다. 회사의 공동창업자로써 이런 상황이 오게 된 상황에 대해서 책임감도 느끼고 안타까운 마음도 들며 힘든 시기를 보냈습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;🙇‍♂️ 울트라 러닝 - Backend&lt;/h2&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/ad84c452-96af-410a-9c01-7d12688aef41&quot; width=&quot;400&quot;&gt;
&lt;p&gt;저는 ‘AI 엔지니어’라는 직업 정체성을 가지고 일을 했기 때문에 여태까지는 데이터 관련 작업 / AI 개발 / AI 모델 서빙 정도의 작업들을 위주로 업무를 했습니다. 저희 튜닙에서 ‘디어메이트’라는 서비스와 TUNiBridge라는 자연어처리 API 서비스를 운영하고 있습니다. 저는 주로 거기에 들어가는 AI 개발을 담당했었고 백엔드 업무는 다른 인원들이 맡았습니다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/40842552-8804-449d-9590-b5bcfee67247&quot; width=&quot;350&quot;&gt;
&lt;p&gt;하지만 기존에 백엔드 업무를 보던 인원들이 퇴사를 하면서 어쩔 수 없이 제가 업무 인수인계를 받게 되었습니다. 한 명 인수인계 받으면 그 다음 사람 인수인계 받고.. 의 연속이였습니다. 😭&lt;/p&gt;
&lt;p&gt;기존에 백엔드 업무를 하지도 않았지만, 여러 백엔드 개발자의 업무를 인수인계 받고 유지/보수하는건 정말 쉽지 않았습니다. 아무 이슈가 없기를 간절히 바랐지만, 매일이 새로운 버그와의 사투였습니다. 😭 🐞&lt;/p&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/74686b2a-0a39-44bc-8df6-bbcb1fecde2d&quot; width=&quot;600&quot;&gt;
&lt;p&gt;저희 서비스가 MSA 아키텍처(Microservice Architecture)로 개발되어 있어서 디어메이트라는 서비스가 여러 작은 프로젝트들의 집합으로 구성이 되어있고, 각 프로젝트별로 인스턴스, Lambda 함수, CloudWatch 등이 모두 따로 있는 구조입니다. 서비스에서 버그가 나면 어느 쪽을 살펴봐야하는지를 파악하는것부터도 저에게는 큰 난관이였고, EC2 정도나 사용해봤던 AWS(Amazon Web Services)의 ECS, SQS, Lambda 등의 기능들에 대해서 파악하는건 더더욱 머리가 아팠습니다. 😩&lt;/p&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/d481cb42-3cc1-4ac9-b843-d4a0c3fb6074&quot; width=&quot;350&quot;&gt;
&lt;p&gt;그렇게 올해 중반기 정도부터 몇 달간 삽질의 연속이였습니다. 한국에서 기본적인 영어 교육을 받고 당장 미국 땅에 떨어져서 생활해야하는 기분이였습니다. 그렇게 몇 달간 이미 있었던 이슈, 새로 생긴 이슈, 당장 필요한 개발들을 처리하다보니 점점 전체적인 구조에 대한 파악이 됐고, 어느 순간부터는 적어도 저희 서비스에 대한 백엔드 작업은 처리할 수 있게 됐습니다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/eb4c406b-143d-477a-b7a9-527e94fa7fb5&quot; width=&quot;350&quot;&gt;
&lt;p&gt;’&lt;a href=&quot;https://sooftware.github.io/ultra-learning/&quot;&gt;울트라 러닝&lt;/a&gt;‘은 제가 연초에 읽은 책입니다. 어떻게 짧은 시간동안 큰 학습 효과를 누릴 수 있는지에 대한 책이였는데, 돌이켜보니 제가 의도치는 않았지만 백엔드 업무에 대해서 울트라 러닝을 하게 된 것 같습니다.&lt;/p&gt;
&lt;p&gt;울트라 러닝은 세 가지 정도의 핵심 포인트가 있었다고 생각합니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;학습하고자 하는 대상에 몰입할 수 있는 최상의 환경을 만들어라.&lt;/li&gt;
&lt;li&gt;냉정하고 비판적인 피드백을 받아라.&lt;/li&gt;
&lt;li&gt;굉장히 높은 목표를 세우고 도전하라.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;위 3개의 키 포인트 중 1-2번에 대해서는 상황상 어쩔 수 없이 아래처럼 자동으로 적용이 됐습니다. 😅&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;사내 유일한 개발자로서 내가 버그를 처리하지 않으면 안 되는 상황 + 내가 개발한게 서비스에 실시간으로 반영이 되는 특수한 상황&lt;/li&gt;
&lt;li&gt;내가 작업한게 잘못되면 서비스가 다운되거나 버그가 해결되지 않는다&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;위와 같은 상황 덕분에, 비교적 짧은 기간동안 거의 전무했던 제 백엔드 역량이 크게 향상될 수 있었습니다. 힘들었지만 그 고생한 기간 덕분에 제게 백엔드라는 새로운 무기가 하나 더 생길 수 있었습니다. 😎&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;🧩 Special Moments&lt;/h2&gt;
&lt;p&gt;2024년은 개인적으로도 기억할만한 많은 일들이 있었습니다.&lt;/p&gt;
&lt;h3&gt;💍 혈육의 결혼&lt;/h3&gt;
&lt;img width=&quot;400&quot; alt=&quot;image&quot; src=&quot;https://github.com/user-attachments/assets/8d502baa-0f44-48a2-b613-a48d33d9a5e2&quot;&gt;
&lt;p&gt;올해 3살 위인 누나의 결혼이 있었습니다. 결혼하는 본인과 저희 부모님이 가장 정신없었겠지만 저도 상견례 참여, 결혼 전 가족 여행, 결혼식까지 꽤 신경이 쓰였습니다. 결혼식까지 잘 마무리됐고, 매형이 저희 새로운 가족으로 들어오게 됐습니다. Welcome! 🎉&lt;/p&gt;
&lt;h3&gt;✈️ Journey&lt;/h3&gt;
&lt;p&gt;작년에는 해외 여행은 못 가고, 울릉도 여행을 다녀왔는데, 올해는 해외 여행 2곳과 국내 여행 여러 곳을 다녀왔습니다! 연말에 목표했던 한라산 등반은 날씨 이슈로 인해서 못 다녀왔지만 🥲, 그래도 올해에는 여러 곳을 여행다니며 많은 추억을 쌓았습니다!&lt;/p&gt;
&lt;h4&gt;🏖️ SAIPAN&lt;/h4&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/badfa7a0-acef-4634-8f9f-0cc3a4fcb0a6&quot; width=&quot;650&quot;&gt;
&lt;p&gt;여름에 여자친구랑 사이판 여행을 다녀왔습니다. Håfa adai! 🤟 (안녕하세요)&lt;/p&gt;
&lt;p&gt;저랑 여자친구 둘 다 물에서 노는걸 좋아하는데, 바다가 이쁘기로 유명한 사이판에 다녀왔습니다. 해외 여행을 동남아 쪽으로만 다녀본 터라, 다른곳도 가보고 싶었는데 나름 미국(?)에 처음으로 가보게 됐습니다.&lt;/p&gt;
&lt;p&gt;마나가하섬에서의 스노쿨링, 세계적인 다이빙 명소인 그로토 스노쿨링, 켄싱턴 호캉스 등 정말 만족스러운 여행이었습니다!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/1d9d3935-d32e-4765-ac51-f4aa8ba7333c&quot; width=&quot;350&quot;&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;사진 출처 : &lt;a href=&quot;https://blog.naver.com/yongorca/221199419888&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;특히 마나가하섬에서 스노쿨링하면서 위 사진의 새끼 상어를 만났는데, 새끼지만 야생의 상어를 보는건 처음이라 초흥분상태로 상어를 엄청 따라다녔습니다. 직접 사진이나 동영상을 찍고 싶었지만 어찌나 빠르던지 직접 찍지는 못했습니다. 😩 나중에 사이판 원주민에게 들은 얘기로는 더 깊은 수심으로 가면 저 새끼의 부모들도 만날 수 있다고 하네요 😱&lt;/p&gt;
&lt;img width=&quot;500&quot; alt=&quot;image&quot; src=&quot;https://github.com/user-attachments/assets/33d31e5c-f724-432b-a70e-438a7cd1626d&quot;&gt;
&lt;p&gt;사이판은 주말이 되면 온가족이 모여서 바닷가에서 바베큐를 해서 먹는 문화가 있다고 하더라고요. 우연히 지나가다가 보고는 여자친구랑 저 둘 다 ‘끼고 싶다..’라는 생각을 했습니다. 👀&lt;/p&gt;
&lt;p&gt;아는 원주민이 없으니 우리끼리 하자! 라는 생각으로 호기롭게 숯이랑 고기랑 싸서 호텔 앞 바닷가 바베큐 테이블로 갔습니다. (사이판에는 비치 바베큐 테이블이 대부분 있습니다!) 하지만 바베큐의 시작인 불 붙이는것부터 잘 안 되는 바람에 주위 원주민들에게 라이터를 빌리러 다녔습니다. 😤&lt;/p&gt;
&lt;p&gt;그러는 저희가 측은하게 보였는지.. 라이터를 빌려주려던 머피(아래 사진)의 초대로 원주민 가족과 함께 바베큐 파티를 즐겼습니다! 🍗 🥳&lt;/p&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/f24ef8d3-f8a6-4454-bb53-eba6045055e4&quot; width=&quot;350&quot;&gt;
&lt;p&gt;머피가 사이판의 방식을 보여주겠다면서 바나나잎을 뜯어서 깐 다음에 바베큐도 직접 다 해주고 소주까지 제공해줬습니다. 😭&lt;/p&gt;
&lt;p&gt;머피네 가족과 바베큐 파티를 즐기며 머피가 지금 하는 일(배 선장), 머피가 미국 배에 타서 일했던 얘기, 미국에 가서 외로웠었던 기억을 얘기하며 가족이 가장 중요하다며 해준 얘기를 들으면서 여러 생각이 들었고, 잊지 못할 추억을 남겨준 머피네 가족에게 너무 고맙습니다!!&lt;/p&gt;
&lt;h4&gt;🍣 OSAKA&lt;/h4&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/5d4ca91e-b123-4e30-bc7c-db54259e7dc1&quot; width=&quot;650&quot;&gt;
&lt;p&gt;11월에는 대학교 친구들과 오사카 여행을 다녀왔습니다. 친구들과 국내 여행은 종종 다녔지만 해외 여행은 처음이기도 했고, 일본은 처음 가보게 됐습니다.&lt;/p&gt;
&lt;p&gt;USJ(Universal Studio Japan), 교토, 난바, 아메리카무라, 온천 등 친구들과 다니면서 많은 추억을 쌓았습니다. 온김에 뽕 뽑고 놀자라는 생각에 하루 4-5끼씩 먹고 종일 걸었습니다. 🐷&lt;/p&gt;
&lt;p&gt;개인적으로 별 기대 안했던 USJ는 이번 여행에서 가장 하이라이트였을 정도로 만족스럽게 놀고왔습니다. 해리포터부터 닌텐도 월드, 여러 기념품 상점들까지 하나하나 정말 재밌었습니다. USJ 가실 분들은 처음에 조금이라도 빨리 들어가는게 중요하니 꼭 오픈런 추천드립니다. 🏃&lt;/p&gt;
&lt;p&gt;초밥, 라멘, 야끼토리 등 다 맛있었지만 교토 ‘우나기 소라’에서 먹은 장어 덮밥은 정~말 맛있었습니다.. 교토갈일 있으신분들은 꼭 드시는걸 추천드립니다!&lt;/p&gt;
&lt;h3&gt;🏋️ Hobby&lt;/h3&gt;
&lt;h4&gt;웨이트 트레이닝&lt;/h4&gt;
&lt;p&gt;2023년에 3대 400을 달성하고, 2024년에는 살을 한 5KG 빼면서 현재 수행 능력을 유지하는게 목표였습니다. 목표와는 다르게 수행능력은 좋아지고 몸무게는 그대로입니다. 😅&lt;/p&gt;
&lt;p&gt;요즘은 1RM 측정보다는 5-12개 정도 할 수 있는 무게에서 최대한 좋은 자세를 유지하려고 노력중입니다. 인바디 상으로는 큰 변화가 없었지만 운동 자세를 고치고, 그동안 소홀했던 운동 부위(팔, 어깨, 복근)에 좀 더 투자를 하면서 조금이지만 변화가 생긴 것 같습니다.&lt;/p&gt;
&lt;p&gt;올해에는 좀 더 큰 변화를 목표로 열심히 해보겠습니다. 🫡&lt;/p&gt;
&lt;h4&gt;토트넘  vs K리그 올스타 직관&lt;/h4&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/aa89f924-23c1-4c60-a4bd-da05c1f7aa57&quot; width=&quot;600&quot;&gt;
&lt;p&gt;이번에 쿠팡시리즈 초청으로 토트넘이 내한해서 ‘토트넘 vs K리그 올스타’ 경기가 있었습니다. 같은 시기에 FC 바이에른뮌헨도 초청을해서 ‘토트넘 vs FC 바이에른 뮌헨’ 경기를 가장 가고 싶었지만, 해당 경기는 티케팅에 실패하고, K리그 올스타전은 성공해서 다녀오게 됐습니다!&lt;/p&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/2d60f612-36d5-4319-8881-7def7faac1cc&quot; width=&quot;350&quot;&gt;
&lt;p&gt;평소에 같이 토트넘 경기를 보며 손흥민 선수를 응원하던 저랑 여자친구였기에 설레는 마음으로 경기장을 다녀왔습니다. 이번에 토트넘으로 이적한 양민혁 선수도 K리그 올스타 팀에서 뛰었는데 뛴 시간이 그리 길진 않았지만 순간순간 번뜩이는 모습이 미래가 기대됐습니다. 좌흥민 우민혁을 볼 수 있었으면 좋겠네요.&lt;/p&gt;
&lt;p&gt;작년에는 ‘아틀레티코 마드리드 vs K리그 올스타’전을 직관하고 왔는데, 올해도 해외 유명 클럽 축구 경기를 직관할 수 있어서 좋았습니다. &lt;strong&gt;쿠팡플레이 사랑합니다!!&lt;/strong&gt; 2025년에도 좋은 팀 초청 부탁드려요!&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;🐍 2025년&lt;/h2&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/3d0c11cd-5af1-406f-8ec1-b0f7646aa009&quot; width=&quot;400&quot;&gt;
&lt;p&gt;위에 적은대로 올해는 저희 튜닙에게 2024년은 쉽지 않은 한 해였습니다. 인원수도 많이 줄고 여러모로 쉽지 않은 상황이었지만 남은 인원들의 노력 덕분에 저희에게 크고작은 몇 건의 매출이 발생했습니다.&lt;/p&gt;
&lt;p&gt;모든 스타트업들에게 쉽지 않은 2024년이였기 때문에 매출 발생이 너무나 소중했고, 저희가 그동안 연구/개발한 기술들이 판매됐기 때문에 더더욱 값졌습니다. 덕분에 큰 위기는 넘길 수 있었고, 다가오는 2025년도 쉽지는 않겠지만 이번에 위기를 넘긴것처럼 2025년도 잘 해낼 수 있을거라 믿습니다.&lt;/p&gt;
&lt;h3&gt;2025년 계획&lt;/h3&gt;
&lt;p&gt;2025년에는 운전 연수를 좀 받아서 10년간 묵혀둔 면허를 좀 사용해보려고 합니다. 그리고 아무래도 재택근무 위주로 하다보니 매일 책상에 앉아서 노트북으로 모든 일을 하고 있습니다. 일할때도 공부할때도 노트북으로 하고 있고, 쉴 때도 유튜브나 넷플릭스를 보다보니, 책상에 앉아서 펜을 잡고 하는 필기 공부나 독서와 점점 멀어지더군요. 올해에는 스터디 카페를 다니며 멀어졌던 필기 공부와 독서와 다시 가까워져려고 합니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[llama.cpp (On device llm inference tool)]]></title><description><![CDATA[llama.cpp (On device llm inference tool) 최근에 llama.cpp를 사용해봤는데, 상당히 편리하고 미래에 더 많이 쓰일 툴이라는 생각이 들어서 기록해둔다! llama.cpp란? 대표적인 오픈소스 LLM인 Meta…]]></description><link>https://sooftware.github.io/llama-cpp/</link><guid isPermaLink="false">https://sooftware.github.io/llama-cpp/</guid><pubDate>Sat, 07 Sep 2024 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;llama.cpp (On device llm inference tool)&lt;/h1&gt;
&lt;img src=&quot;https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSiULtz3uHsF-6HAuU2sAyxlSxP7jRAuNndVA&amp;amp;s&quot; width=&quot;400&quot;&gt;
&lt;p&gt;최근에 &lt;a href=&quot;https://github.com/ggerganov/llama.cpp&quot;&gt;llama.cpp&lt;/a&gt;를 사용해봤는데, 상당히 편리하고 미래에 더 많이 쓰일 툴이라는 생각이 들어서 기록해둔다!&lt;/p&gt;
&lt;h2&gt;llama.cpp란?&lt;/h2&gt;
&lt;p&gt;대표적인 오픈소스 LLM인 Meta의 llama에서 이름을 따온 이 라이브러리는 llama에만 종속되는게 아닌 오픈소스 LLM들을 순수 C/C++로만 인퍼런스 가능하게 해주는 툴이다. 일반적으로 AI 모델들은 대부분 Python 기반으로 작동하기 때문에 온디바이스 상에서 LLM 구동을 위해서는 제약이 꽤 있는 편이다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/a787c756-2843-4a91-9bdd-cd34a285ddde&quot; width=&quot;350&quot;&gt;
&lt;p&gt;일반적인 리눅스 기반 서버에서는 쉽게 사용 가능한 PyTorch, Hugginface Transformers 등을 온디바이스 상에서 구동하려면 라이브러리 단에서 제공되는 API도 한정적일 뿐더러 연산 대부분이 GPU에 맞춰져 있기 때문에 파이썬 기반으로 llm을 온비다이스에서 구동하기란 상당히 어려운 일이다. (매우 큰 프로젝트가 될 것)&lt;/p&gt;
&lt;p&gt;이러한 문제를 해결하기 위해 llama.cpp는 순수 C/C++ 기반으로 LLM 구동을 가능하게 하며, CUDA/ARM/Android/Vulkan 등 여러 하드웨어 기반으로 돌아갈 수 있도록 하는 프로젝트다!&lt;/p&gt;
&lt;h2&gt;llama.cpp 사용법&lt;/h2&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/5ee981ad-e4b5-40b8-9546-3669e08b4d8e&quot; width=&quot;400&quot;&gt;
&lt;p&gt;그럼 llama.cpp 사용법을 살펴보자!&lt;/p&gt;
&lt;h3&gt;Build llama.cpp&lt;/h3&gt;
&lt;p&gt;어떤 환경에서 사용하는지에 따라 빌드 방법이 다르기 때문에 &lt;a href=&quot;https://github.com/ggerganov/llama.cpp/blob/master/docs/build.md&quot;&gt;llama.cpp의 공식 How to build 도큐먼트&lt;/a&gt;를 살펴보는걸 추천한다. 여기서는 linux or Mac 환경에서의 빌드 방법만 다루겠다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Using make (linux or Mac)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;make&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Using CMake&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;cmake -B build
cmake --build build --config Release&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Download Huggingface Model&lt;/h3&gt;
&lt;p&gt;프로젝트 build가 되었으면 사용할 허깅페이스 모델을 로컬에 다운받아 놓는다. 여기서 주의할 점은 llama.cpp는 아직 현재진행형 프로젝트이기 때문에 &lt;strong&gt;일부 모델들만 지원&lt;/strong&gt;한다는 점이다. llama.cpp의 README.md를 참고하여 내가 사용하려는 모델을 지원하는지를 먼저 꼭 체크해봐야 한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; transformers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; AutoTokenizer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; AutoModelForCausalLM

HF_REPO_NAME &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;HF_REPO_NAME&quot;&lt;/span&gt;

tokenizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AutoTokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;HF_REPO_NAME&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AutoModelForCausalLM&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;HF_REPO_NAME&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;save_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;hf_model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;save_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;hf_mode&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Convert Huggingface to gguf Format&lt;/h3&gt;
&lt;p&gt;허깅페이스 포맷의 모델을 다운로드 했으면, 이제 llama.cpp 구동 포맷인 &lt;code class=&quot;language-text&quot;&gt;gguf&lt;/code&gt; 포맷으로 모델을 변환해야한다.&lt;br&gt;
모델 변환을 하는 파일은 &lt;code class=&quot;language-text&quot;&gt;convert_hf_to_gguf.py&lt;/code&gt; 파일을 실행하면 되는데, 기본적으로 지원이 되는 모델이 아니라면 &lt;code class=&quot;language-text&quot;&gt;convert_hf_to_gguf_update.py&lt;/code&gt; 파일을 한 번 수정 &amp;#x26; 실행해준 뒤에 모델을 변환해야한다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;convert_hf_to_gguf_update.py&lt;/code&gt;의 &lt;a href=&quot;https://github.com/ggerganov/llama.cpp/blob/947538acb8617756a092042ff7e58db18dde05ec/convert_hf_to_gguf_update.py#L66C1-L66C7&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;models&lt;/code&gt; 변수가 선언된 부분&lt;/a&gt;에 변환하려는 모델을 추가해주어야한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;exaone&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;         &lt;span class=&quot;token string&quot;&gt;&quot;tokt&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; TOKENIZER_TYPE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;BPE&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;repo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://huggingface.co/LGAI-EXAONE/EXAONE-3.0-7.8B-Instruct&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위와 같은 형식으로 토크나이저가 BPE인지 SPM(sentencepiece)인지를 표시하고 허깅페이스 레포 주소를 기록한 뒤 아래 커맨드를 실행하면 된다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ python3 convert_hf_to_gguf_update.py &lt;span class=&quot;token variable&quot;&gt;$HF_TOKEN&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이 파일은 &lt;code class=&quot;language-text&quot;&gt;convert_hf_to_gguf&lt;/code&gt;의 &lt;code class=&quot;language-text&quot;&gt;get_base_vocab_pre&lt;/code&gt;라는 메서드를 생성하는 역할을 한다. 해당 과정이 잘 됐으면 &lt;code class=&quot;language-text&quot;&gt;convert_hf_to_gguf&lt;/code&gt; 파일을 실행하면 된다!&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ python3 convert_hf_to_gguf.py --outfile models/llama-cpp-model.gguf --outtype bf16 --model hf_model&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Run&lt;/h3&gt;
&lt;p&gt;프로젝트 빌드 &amp;#x26; 모델 변환까지 잘 되었으면 아래 명령어를 실행해서 &lt;code class=&quot;language-text&quot;&gt;-p&lt;/code&gt; 옵션으로 준 프롬프트에 대해서 모델이 뒤이어서 잘 생성하는지를 확인하면 된다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;./build/bin/llama-cli -m your_model.gguf -p &lt;span class=&quot;token string&quot;&gt;&quot;I believe the meaning of life is&quot;&lt;/span&gt; -n &lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Output:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# I believe the meaning of life is to find your own truth and to live in accordance with it. For me, this means being true to myself and following my passions, even if they don&apos;t align with societal expectations. I think that&apos;s what I love about yoga – it&apos;s not just a physical practice, but a spiritual one too. It&apos;s about connecting with yourself, listening to your inner voice, and honoring your own unique journey.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;llama-server&lt;/h3&gt;
&lt;p&gt;위 llama-cli는 간단한 테스트를 위한 파일이라면 실제로 API 형태로 사용을 위해서는 &lt;code class=&quot;language-text&quot;&gt;llama-server&lt;/code&gt; 파일을 이용하면 된다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./build/bin/llama-server -m your_model.gguf --port &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Basic web UI can be accessed via browser: http://localhost:8080&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 명령어가 잘 실행되었으면 아래 같은 curl 등의 커맨드로 요청을 보내면 된다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; --request POST &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
--url http://localhost:8080/completion &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
--header &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
--data &lt;span class=&quot;token string&quot;&gt;&apos;{&quot;prompt&quot;: &quot;가나다라마바사아자차카타&quot;,&quot; n_predict&quot;: -1, &quot;stream&quot;: true}&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;llama-server 실행시 여러 옵션을 활용할 수 있는데, 자세한 내용은 &lt;a href=&quot;https://github.com/ggerganov/llama.cpp/blob/master/examples/server/README.md&quot;&gt;이 문서&lt;/a&gt;를 살펴보면 된다.&lt;/p&gt;
&lt;h2&gt;Android에서 llama.cpp 돌려보기&lt;/h2&gt;
&lt;p&gt;감사하게도 llama.cpp에서는 Android NDK를 이용한 빌드도 지원해준다.&lt;/p&gt;
&lt;p&gt;관련 문서는 &lt;a href=&quot;https://github.com/ggerganov/llama.cpp/blob/master/docs/android.md&quot;&gt;이 문서&lt;/a&gt;를 참고하면 된다. 아래 영상은 Pixel 5 폰에서 구동한 llama-2 7B 데모 영상이다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://user-images.githubusercontent.com/271616/225014776-1d567049-ad71-4ef2-b050-55b0b3b9274c.mp4&quot;&gt;https://user-images.githubusercontent.com/271616/225014776-1d567049-ad71-4ef2-b050-55b0b3b9274c.mp4&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[ELK] Elastic Search logstash - Nori 토크나이저 설정]]></title><description><![CDATA[Elastic Search logstash - Nori 토크나이저 설정 이번에 회사에서 검색 기능을 구현하면서 Elastic Search를 다루게 됐다. 이 엔진을 다루면서 삽질을 많이 했는데, 다음에는 하지 않도록 기록용으로 남겨둔다. Elastic…]]></description><link>https://sooftware.github.io/elastic-search/</link><guid isPermaLink="false">https://sooftware.github.io/elastic-search/</guid><pubDate>Sat, 24 Aug 2024 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Elastic Search logstash - Nori 토크나이저 설정&lt;/h1&gt;
&lt;img src=&quot;https://github.com/user-attachments/assets/eba59a7d-2ecf-4f47-a15d-e8082a9586e7&quot; width=&quot;550&quot;&gt;
&lt;p&gt;이번에 회사에서 검색 기능을 구현하면서 Elastic Search를 다루게 됐다. 이 엔진을 다루면서 삽질을 많이 했는데, 다음에는 하지 않도록 기록용으로 남겨둔다.&lt;/p&gt;
&lt;h2&gt;Elastic Search란?&lt;/h2&gt;
&lt;p&gt;간단히 말하면, 가장 널리 쓰이는 검색 엔진 중 하나이다. 검색 대상이 되는 문서들을 저장하고, 주기마다 인덱싱해고, 검색 쿼리를 날렸을때 사용자가 지정한 토크나이저 등을 이용해서 검색 결과를 반환해주는 엔진이다.&lt;/p&gt;
&lt;h2&gt;Nori 토크나이저&lt;/h2&gt;
&lt;p&gt;Elasticsearch(이하 ES)는 세계적으로 쓰이는 엔진이므로 당연하게도 한국어에 특화되어 있지 않다. 한국어처럼 특이한 형태소 구조를 가진 언어의 경우, 검색 효율을 높이기 위해 특수한 토크나이저가 필요한데, 많이 쓰이는 토크나이저가 Nori 토크나이저다. (Mecab 기반의 형태소 분석기인데, 이 부분은 생략)&lt;/p&gt;
&lt;p&gt;예를 들면 ES에서 기본적으로 제공하는 토크나이저로는 ‘주웠어’를 검색한다고 하면, 검색 대상 문서에 ‘주웠다’가 있다고 해도 검색에 걸리지를 않는다. 하지만 Nori 토크나이저로 ‘주웠어’와 ‘주웠다’를 형태소 분리하게 되면 아래와 같이 동일하게 분리되므로, ‘주웠어’라고 검색해도 ‘주웠다’가 포함된 문서가 검색에 걸리게 된다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;{  
  “tokens” : [  
    {  
      “token” : “주웠“,  
    },  
    {  
      “token” : “줍”,  
    }  
  ]  
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 결과를 보면 유추할 수 있듯이, ‘주웠어’를 토큰화하면 ‘주웠’ 뿐만 아니라 ‘줍’도 포함되기 때문에 ‘줍다’를 검색해도 ES의 검색에 걸리게 된다!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/554d9533-7f72-4cf3-b463-57445bd8222e&quot; width=&quot;400&quot;&gt;.&lt;/p&gt;
&lt;h2&gt;Logstash&lt;/h2&gt;
&lt;p&gt;Logstash는 ELK(Elasticsearch, Logstash, Kibana)의 구성요소 중 &lt;strong&gt;L&lt;/strong&gt; 에 해당하는데, 쉽게 보면 Elasticsearch를 사용하는데 필요한 툴킷이다. 데이터 파이프라인의 중간 역할을 수행한다고 보면 되는데, 데이터 인덱싱, 필터링, 저장하는 역할을 수행한다.&lt;/p&gt;
&lt;p&gt;Logstash에 특정 인덱스에 Nori 토크나이저를 적용하려면 아래와 같은 &lt;code class=&quot;language-text&quot;&gt;curl&lt;/code&gt; 문을 실행해주면 된다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;curl -X PUT &quot;http://localhost:9200/target_index&quot; -H &apos;Content-Type: application/json&apos; -d&apos;
{
  &quot;settings&quot;: {
    &quot;analysis&quot;: {
      &quot;filter&quot;: {
        &quot;lowercase_filter&quot;: {
          &quot;type&quot;: &quot;lowercase&quot;
        },
        &quot;nori_part_of_speech_filter&quot;: {
          &quot;type&quot;: &quot;nori_part_of_speech&quot;,
          &quot;stoptags&quot;: [&quot;E&quot;,&quot;J&quot;]  // 원하는 stoptags 값으로 변경
        }
      },
      &quot;analyzer&quot;: {
        &quot;my_analyzer&quot;: {
          &quot;type&quot;: &quot;custom&quot;,
          &quot;tokenizer&quot;: &quot;nori_tokenizer&quot;,
          &quot;filter&quot;: [&quot;lowercase_filter&quot;, &quot;nori_part_of_speech_filter&quot;]
        }
      },
      &quot;tokenizer&quot;: {
        &quot;nori_tokenizer&quot;: {
          &quot;type&quot;: &quot;nori_tokenizer&quot;,
          &quot;decompound_mode&quot;: &quot;mixed&quot;
        }
      }
    },
    &quot;number_of_shards&quot;: 1,
    &quot;number_of_replicas&quot;: 1
  },
  &quot;mappings&quot;: {
    &quot;properties&quot;: {
      &quot;{TARGET_COLUMN}&quot;: {
        &quot;type&quot;: &quot;text&quot;,
        &quot;analyzer&quot;: &quot;my_analyzer&quot;
      }
    }
  }
}
&apos;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;그리고 적용을 원하는 index에 해당하는 설정을 &lt;code class=&quot;language-text&quot;&gt;logstash/pipeline/{TARGET_INDEX}.conf&lt;/code&gt; 를 작성해주면 된다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;input {
	jdbc {
		jdbc_driver_library =&gt; &quot;/usr/share/logstash/logstash-core/lib/jars/postgresql.jar&quot; 
		jdbc_driver_class =&gt; &quot;org.postgresql.Driver&quot;
		jdbc_connection_string =&gt; &quot;${DB_URL}&quot; 
		jdbc_user =&gt; &quot;${DB_USER}&quot;
		jdbc_password =&gt; &quot;${DB_PASSWORD}&quot;
		schedule =&gt; &quot;*/10 * * * *&quot;
		statement =&gt; &apos;SELECT id, {TARGET_COLUMN} FROM {TABLE_NAME}&apos;. # 검색 대상 가져오는 
	}
}
output {
	elasticsearch { 
		hosts =&gt; [&quot;http://elasticsearch:9200&quot;]
		index =&gt; &quot;target_index&quot;
		document_id =&gt; &quot;%{id}&quot;
		doc_as_upsert =&gt; true
	}
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[AI Joker 공개]]></title><description><![CDATA[AI Joker 공개 이번에 회사에서 작업한 A.I. Joker 모델을 공개했습니다! Joker 모델은 한국어 Hate Speech를 생성하는 모델입니다. 최근 많은 LLM들이 나오고 있는 만큼 해당 모델들의 Safety…]]></description><link>https://sooftware.github.io/joker/</link><guid isPermaLink="false">https://sooftware.github.io/joker/</guid><pubDate>Wed, 10 Jul 2024 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;AI Joker 공개&lt;/h1&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/9253490a-0de9-4f8f-abec-6fd7158d709b&quot; height=&quot;350&quot;&gt;
&lt;p&gt;이번에 회사에서 작업한 A.I. Joker 모델을 공개했습니다!&lt;/p&gt;
&lt;p&gt;Joker 모델은 한국어 Hate Speech를 생성하는 모델입니다.&lt;/p&gt;
&lt;p&gt;최근 많은 LLM들이 나오고 있는 만큼 해당 모델들의 Safety 처리 능력을 확인하는 것도 중요한 이슈입니다.&lt;/p&gt;
&lt;p&gt;연구자들이 직접 Hate Speech를 써가면서 모델을 평가하는건 시간적으로도 정신적으로도 힘든 일이기 때문에, 해당 부분을 좀 더 자동화하고자 Joker 모델을 만들고 공개하게 됐습니다.&lt;/p&gt;
&lt;p&gt;총 7가지 카테고리(‘ABUSE’, ‘CENSURE’, ‘CRIME’, ‘DISCRIMINATION’, ‘HATE’, ‘SEXUAL’, ‘VIOLENCE’)에 대한 hate speech를 생성하도록 학습됐으며, 카테고리를 지정해서 발화하도록 컨트롤 할 수도 있습니다 😄&lt;/p&gt;
&lt;p&gt;많은 관심 및 사용 부탁드립니다!&lt;/p&gt;
&lt;p&gt;* 윤리적 이슈가 있는 모델인만큼, 신청-승인 절차를 거쳐서 모델 사용을 할 수 있도록 하려고 합니다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/4237307a-01c7-4424-99b9-12a0e602c8cf&quot; height=&quot;400&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Github link : &lt;a href=&quot;https://github.com/tunib-ai/joker&quot;&gt;https://github.com/tunib-ai/joker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Demo link : &lt;a href=&quot;http://114.110.134.81:7860&quot;&gt;http://114.110.134.81:7860&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[단 30줄로 ChatGPT 웹페이지 만들기 (Streamlit chat_message)]]></title><description><![CDATA[단 30줄로 ChatGPT 웹페이지 만들기 (Streamlit chat_message) Streamlit은 파이썬 기반의 오픈소스 웹 UI 라이브러리입니다. 매우 간단한 코드로 손쉽게 웹페이지를 띄울 수 있어서 간단한 데모나 PoC…]]></description><link>https://sooftware.github.io/streamlit-chatgpt/</link><guid isPermaLink="false">https://sooftware.github.io/streamlit-chatgpt/</guid><pubDate>Wed, 01 May 2024 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;단 30줄로 ChatGPT 웹페이지 만들기 (Streamlit chat_message)&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/streamlit/streamlit&quot;&gt;Streamlit&lt;/a&gt;은 파이썬 기반의 오픈소스 웹 UI 라이브러리입니다. 매우 간단한 코드로 손쉽게 웹페이지를 띄울 수 있어서 간단한 데모나 PoC 제품을 빠르게 만들어볼때 굉장히 유용합니다. 실제로 개인적으로 간단한 데모를 만들때 &lt;a href=&quot;https://github.com/gradio-app/gradio&quot;&gt;Gradio&lt;/a&gt;와 함께 가장 많이 쓰는 라이브러리입니다.&lt;/p&gt;
&lt;img width=&quot;400&quot; alt=&quot;image&quot; src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/134118d0-c4b2-4689-bc85-4c805b8c7154&quot;&gt;
&lt;p&gt;두 라이브러리 모두 간단하게 웹페이지를 띄울 수 있다는 장점이 있지만, 제 경험상 streamlit으로 코드를 작성했을 때 보다 간편헀던 것 같습니다. 그래서 이번 포스트에서는 streamlit에서 제공하는 &lt;strong&gt;chat_message&lt;/strong&gt; 메서드와 OpenAI API를 이용해서 &lt;strong&gt;단 30줄의 코드&lt;/strong&gt;로 ChatGPT를 웹페이지에 띄워보려고 합니다! (chat_message 외의 사용법을 알고싶으신 분들은 &lt;a href=&quot;https://sooftware.github.io/streamlit/&quot;&gt;이전 streamlit 포스트&lt;/a&gt;를 참고하세요!)&lt;/p&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;먼저 스트림릿 설치를 위해서 아래 커먼드롤 입력합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ pip install streamlit&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;그리고 OpenAI API 사용을 위해서 아래 커맨드로 openai 라이브러리도 설치해줍니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ pip install openai==1.2.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;참고로 openai 버전은 꼭 1.2.0이 아니여도 되지만, 버전마다 사용법이 조금씩 다를 수 있기 때문에, 이번 포스트에서는 버전을 고정해줬습니다.&lt;/p&gt;
&lt;h2&gt;Build Streamlit ChatGPT Page&lt;/h2&gt;
&lt;p&gt;이 섹션에서는 Streamlit을 처음 사용해보신다고 가정하고 하나하나 자세하게 보고 넘어가겠습니다. 이미 Streamlit에 익숙해서 전체 코드만 필요하신 분은 아래로 내리시면 코드가 있으니 해당 부분 참고하시면 되겠습니다. :)&lt;/p&gt;
&lt;h3&gt;Step 1: import libraries&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; streamlit &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; st  
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os  
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; openai &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; OpenAI&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;먼저, 필요한 라이브러리들을 import 해줍니다. 앞에서 설치해준 streamlit, openai와 openai API 키 등록을 위해 기본 내장 라이브러리인 os를 import 해줍니다.&lt;/p&gt;
&lt;h3&gt;Step 2: OpenAI API 세팅&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;OPENAI_API_KEY&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;YOUR_OPENAI_API_KEY&quot;&lt;/span&gt;  
client &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; OpenAI&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;환경에 OpenAI API 키를 등록하고, API 사용을 위한 client를 생성합니다. OpenAI API 키는 &lt;a href=&quot;https://platform.openai.com&quot;&gt;https://platform.openai.com&lt;/a&gt; 에서 회원가입 및 결제카드를 등록하면 받을 수 있습니다.&lt;/p&gt;
&lt;h3&gt;Step 3: Streamlit 코드 작성&lt;/h3&gt;
&lt;p&gt;이제 본격적으로 Streamlit 코드를 작성해주면 됩니다!&lt;/p&gt;
&lt;p&gt;먼저 생성할 페이지의 타이틀과 ChatGPT와 주고받을 메세지를 저장할 리스트를 생성해줍니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Streamlit ChatGPT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  
  
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;messages&apos;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session_state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  
    st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session_state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;messages &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Streamlit은 기본적으로 매 event가 발생할때마다 페이지를 새로 로드하는 방식입니다. 그래서 &lt;strong&gt;st.session_state&lt;/strong&gt;가 아닌 새로 변수를 생성하게 되면 이벤트가 발생할대마다 해당 변수가 초기화되어 버립니다. 그래서 스트림릿에서 변수들을 기록할때는 &lt;strong&gt;st.session_state&lt;/strong&gt;에 위와 같은 형식으로 저장하는 것을 추천드립니다.&lt;/p&gt;
&lt;p&gt;다음으로는 사용자로부터 텍스트를 입력받을 창과 텍스트를 전송할 버튼을 만들어 보겠습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;user_message &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text_input&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;User:&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  
  
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;button&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Send&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  
    st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session_state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;messages&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; user_message&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;스트림릿에서 텍스트를 입력받을 때는 &lt;strong&gt;st.text_input&lt;/strong&gt; 메서드를 사용합니다. 버튼은 &lt;strong&gt;st.button&lt;/strong&gt; 메서드를 이용하면 되는데, 저희는 버튼이 눌렸을때의 동작이 필요하므로 &lt;strong&gt;if st.button(“Send”)&lt;/strong&gt; 와 같이 작성했습니다. 그리고 유저 메세지를 ChatGPT에게 보내기 위해 기존에 초기화를 해둔 &lt;strong&gt;st.session_state.messages&lt;/strong&gt;에 ChatGPT에서 요구하는 형식에 맞게 append를 해주겠습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;button&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Send&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  
    st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session_state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;messages&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; user_message&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  
  
    completion &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;chat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;completions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;create&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;  
        model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gpt-3.5-turbo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  
        messages&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session_state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;messages&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; completion&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;choices&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content  
    st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session_state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;messages&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;assistant&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;입력받은 유저 메세지를 ChatGPT에게 전송해서 응답을 받아옵니다! 이전 세팅에서 생성한 openai client의 &lt;strong&gt;chat.completions.create&lt;/strong&gt; 메서드를 이용하여 응답을 받아오고, ChatGPT의 응답을 유저 메세지 같이 &lt;strong&gt;st.session_state.messages&lt;/strong&gt;에 append 해줍니다. 여기까지 코드작성이 됐다면 아래와 같은 플로우가 완성됩니다!&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;유저 메세지 입력&lt;/li&gt;
&lt;li&gt;messages에 유저 메세지 추가&lt;/li&gt;
&lt;li&gt;messages 기반으로 ChatGPT 응답 생성&lt;/li&gt;
&lt;li&gt;ChatGPT 응답 messages에 추가&lt;/li&gt;
&lt;li&gt;1로 돌아가서 반복하며 messages에는 [유저, ChatGPT, 유저, ChatGPT, …] 순서로 주고받은 대화 내역이 저장됨&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Step 4: chat_message 메서드로 대화 display&lt;/h3&gt;
&lt;p&gt;주고받은 대화들을 시각적으로 볼 수 있게 하기 위해 주고받는 대화들을 streamlit의 &lt;strong&gt;chat_message&lt;/strong&gt; 메서드로 display 해줍니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; message &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;reversed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session_state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;messages&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  
    &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;chat_message&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;role&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;role&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;user&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  
            st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;write&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;content&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  
        &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  
            st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;write&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;content&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; avatar&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;assets/openai-logo.png&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위에서 저장한 &lt;strong&gt;st.session_state.messages&lt;/strong&gt;를 for 문을 돌면서 하나씩 가져와서 사용자인지 ChatGPT인지를 판별하고, display 해줍니다. (최근 대화가 위에 오도록 하기 위하여 reversed 메서드를 사용합니다) 조금 더 명확하게 표시를 해주기 위해 ChatGPT의 경우 미리 저장해둔 OpenAI logo로 아바타를 표시해줬습니다.&lt;/p&gt;
&lt;h2&gt;Step 5: Run Streamlit&lt;/h2&gt;
&lt;p&gt;Streamlit 기반 웹페이지를 실행할때는 아래와 같이 &lt;strong&gt;streamlit run ***.py&lt;/strong&gt; 형식으로 입력해주시면 됩니다. 저는 파이썬 파일명을 app.py로 했으니 아래와 같이 실행했습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ streamlit run app.py&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 명령어를 실행하면 아래와 같이 Streamlit으로 만든 ChatGPT 페이지를 사용해볼 수 있습니다!&lt;/p&gt;
&lt;img width=&quot;500&quot; alt=&quot;image&quot; src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/2dff5ff4-2ee5-49b2-a3eb-3fadd1ab51e0&quot;&gt;
이렇게 총 31줄의 코드로 AI와 대화하는 웹페이지를 만들 수 있다니 세상 좋아졌다는게 체감이 됩니다. 😎   
&lt;p&gt;이번 포스트에서는 간단하게 ChatGPT와 대화하는 정도의 페이지만 만들었지만 스트림릿에서 제공하는 더 많은 기능들을 활용하면 보다 복잡한 어플리케이션도 빠르게 제작할 수 있습니다. 아래는 제가 운영하는 서비스인 &lt;a href=&quot;https://dearmate.ai/&quot;&gt;Dearmate&lt;/a&gt; 케릭터들과의 대화를 Streamlit으로 만들어본 예시입니다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/236e96dd-c65f-4489-9c06-154c92702c95&quot; width=&quot;400&quot;&gt;
&lt;p&gt;이렇게 Streamlit을 활용하면 내부 데모페이지, PoC 정도의 페이지를 손쉽게 구성할 수 있습니다. 저도 일하면서 반복적으로 손이 가는 업무들은 스트림릿을 이용해서 웹페이지를 하나 띄워두고 즐겨찾기 해두고 일을 하는데, 상당히 편리하고 일의 능률도 많이 올라갑니다. 😎 이 포스트를 읽는 여러분들도 스트림릿을 적극적으로 활용해보시는 것을 추천합니다!&lt;/p&gt;
&lt;h3&gt;전체 코드&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; streamlit &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; st  
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os  
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; openai &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; OpenAI  
  
os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;OPENAI_API_KEY&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;YOUR_OPENAI_API_KEY&quot;&lt;/span&gt;  
client &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; OpenAI&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  
  
st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Streamlit ChatGPT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  
  
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;messages&apos;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session_state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  
    st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session_state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;messages &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;  
  
user_message &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text_input&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;User:&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  
  
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;button&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Send&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  
    st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session_state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;messages&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; user_message&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  
  
    completion &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;chat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;completions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;create&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;  
        model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gpt-3.5-turbo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  
        messages&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session_state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;messages&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; completion&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;choices&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content  
    st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session_state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;messages&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;assistant&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  
  
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; message &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;reversed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session_state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;messages&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  
    &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;chat_message&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;role&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;role&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;user&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  
            st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;write&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;content&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  
        &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  
            st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;write&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;content&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; avatar&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;assets/openai-logo.png&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[GitHub Follow 500 달성!!]]></title><description><![CDATA[GitHub Follow 500 달성!! 최근에 깃허브 팔로워 500명을 달성했습니다! 🎉🎉 창업 이후에는 사실 깃허브 활동을 못하고 있었는데도, 꾸준히 팔로워가 늘어서 어느새 50…]]></description><link>https://sooftware.github.io/github_follow_500/</link><guid isPermaLink="false">https://sooftware.github.io/github_follow_500/</guid><pubDate>Mon, 15 Apr 2024 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;GitHub Follow 500 달성!!&lt;/h1&gt;
&lt;p&gt;최근에 깃허브 팔로워 500명을 달성했습니다! 🎉🎉&lt;/p&gt;
&lt;img width=&quot;650&quot; alt=&quot;image&quot; src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/e9d34b02-6051-432a-866a-69bab5bf1a87&quot;&gt;
&lt;p&gt;창업 이후에는 사실 깃허브 활동을 못하고 있었는데도, 꾸준히 팔로워가 늘어서 어느새 500명이 됐네요.&lt;/p&gt;
&lt;p&gt;한참 음성인식쪽에 몰두하던 시절 이후로는 제대로 된 오픈소스 활동을 못했는데도, 꽤 많은 팔로워분들이 생겨서 신기하네요. 앞으로도 기회가 생기면 오픈소스 활동을 열심히 해보도록 하겠습니다.&lt;/p&gt;
&lt;p&gt;성원에 감사합니다!!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Terabyte(TB) 단위 데이터 셔플링 - terashuf]]></title><description><![CDATA[Terabyte(TB) 단위 데이터 셔플링 - terashuf 리눅스에서 TB 단위의 데이터를 line 기준으로 셔플링이 필요할 때가 (가끔) 있다. 직접 코딩해서 쓰기에는 메모리, 속도 등을 신경써야해서 생각보다 큰 작업인데, terashuf…]]></description><link>https://sooftware.github.io/terashuf/</link><guid isPermaLink="false">https://sooftware.github.io/terashuf/</guid><pubDate>Wed, 20 Mar 2024 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Terabyte(TB) 단위 데이터 셔플링 - terashuf&lt;/h1&gt;
&lt;p&gt;리눅스에서 TB 단위의 데이터를 line 기준으로 셔플링이 필요할 때가 (가끔) 있다. 직접 코딩해서 쓰기에는 메모리, 속도 등을 신경써야해서 생각보다 큰 작업인데, &lt;a href=&quot;https://github.com/alexandres/terashuf&quot;&gt;&lt;strong&gt;terashuf&lt;/strong&gt;&lt;/a&gt; 라는 오픈소스가 있어서 사용해봤더니, 작동도 잘 되고 속도도 빠르다! 👍&lt;/p&gt;
&lt;h2&gt;Terashuf&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ cd $BASE_DIR
$ git clone https://github.com/alexandres/terashuf.git
$ cd terashuf
$ make&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ export TMPDIR=/path/to/large/directory ./terashuf &amp;lt; filetoshuffle.txt &gt; shuffled.txt&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/alexandres/terashuf&quot;&gt;https://github.com/alexandres/terashuf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[RLHF는 수다쟁이를 만든다?! (Does RLHF Breed Verbose Chatterboxes?!)]]></title><description><![CDATA[RLHF는 수다쟁이를 만든다?! (Does RLHF Breed Verbose Chatterboxes?!) RLHF(Reinforcement Learning from Human Feedback)는 OpenAI의 ChatGPT…]]></description><link>https://sooftware.github.io/rlhf-vervosity/</link><guid isPermaLink="false">https://sooftware.github.io/rlhf-vervosity/</guid><pubDate>Wed, 13 Mar 2024 01:11:55 GMT</pubDate><content:encoded>&lt;h1&gt;RLHF는 수다쟁이를 만든다?! (Does RLHF Breed Verbose Chatterboxes?!)&lt;/h1&gt;
&lt;p&gt;RLHF(&lt;em&gt;Reinforcement Learning from Human Feedback&lt;/em&gt;)는 OpenAI의 ChatGPT를 만드는데 사용됐다고 알려지며 LLM(&lt;em&gt;Large-scaled Language Model&lt;/em&gt;)의 새로운 연구분야로 자리잡은 기술입니다. RLHF는 이름에서 알 수 있듯이 사람의 피드백을 사용하여 AI 모델을 학습시키는 방법입니다. RLHF가 자리잡기 전까지는 Pre-training → SFT(&lt;em&gt;Supervised Fine-Tuning&lt;/em&gt;)으로 이루어지는 파이프라인이 정석이였다면, 현재는 Pre-training → SFT → RLHF 파이프라인이 정석으로 자리잡게 되었습니다.
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/99ae9556-430d-4903-a2c1-fba58a14fec5&quot; width=&quot;550&quot;&gt;&lt;/p&gt;
&lt;p&gt;RLHF가 인기를 끌면서, RLAIF(&lt;em&gt;Reinforcement Learning from AI Feedback&lt;/em&gt;), DPO(&lt;em&gt;Direct Preference Optimization&lt;/em&gt;) 등의 RLHF 기반하여 나온 파생 학습법들이 등장하게 됐습니다. 저희를 포함한 국내﹒해외 LLM 기업들은 이런 RLHF 류의 학습법을 적용하면서 LLM의 성능을 끌어올리고 있습니다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/8a8b79a5-9b8b-4952-ac19-f2b7c7572276&quot; width=&quot;400&quot;&gt;
&lt;p&gt;RLHF는 LLM이 생성한 답변에 대해서 사람의 피드백(좋다, 나쁘다)을 받아서 학습을 하기 때문에, 학습 이후 생성되는 답변을 보면 “오? 답변이 좋아졌는데?!” 싶게 바로 체감될 정도로 꽤나 큰 효과를 내고 있습니다. 하지만 RLHF의 문제점이 하나 있는데요, 바로 RLHF가 AI 모델을 투 머치 토커(too much talker)로 만든다는 것입니다!&lt;/p&gt;
&lt;h2&gt;RLHF와 답변 길이의 상관관계?&lt;/h2&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/b800288a-282c-4855-bd9b-5d4c34a07828&quot; width=&quot;350&quot;&gt;
&lt;p&gt;RLHF(or DPO 등) 학습 전후를 비교해본 NLP 연구자분들은 가장 직접적으로 달라진 점을 느끼는 부분이 ‘응답 길이’일 것입니다. SFT만 한 모델과 RLHF까지 적용한 모델을 비교해보면 눈에 띄게 응답 길이가 길어진 것을 볼 수 있는데요, 아래는 &lt;a href=&quot;https://arxiv.org/abs/2310.03716&quot;&gt;A Long Way to Go: Investigating Length Correlations in RLHF&lt;/a&gt; 논문에서 같은 질문에 대해 응답 길이를 비교한 예시입니다.&lt;/p&gt;
&lt;img width=&quot;400&quot; alt=&quot;image&quot; src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/014b0b84-a42b-46ed-92e7-e3c076f2e372&quot;&gt;
&lt;p&gt;내용 자체는 비슷하지만, RLHF를 적용한 모델이 약 4배나 더 길게 생성한 것을 볼 수 있습니다.&lt;/p&gt;
&lt;img width=&quot;700&quot; alt=&quot;image&quot; src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/c77d6eca-095f-4cd6-8223-f0434bbd2327&quot;&gt;
&lt;p&gt;위 그래프에 보이는것처럼 RLHF 적용 전후를 비교했을 때, 응답 길이에 분명한 차이가 있는 것을 볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;이 외의 연구들에서도 RLHF를 적용 했을 때 응답 길이가 길어진다는 연구 결과를 볼 수 있는데요, &lt;a href=&quot;https://arxiv.org/abs/2308.02312&quot;&gt;Is Stack Overflow Obsolete? An Empirical Study of the Characteristics of ChatGPT Answers to Stack Overflow Questions&lt;/a&gt;에서는 ChatGPT 응답 중 77%가 verbose 하다고 평가했으며, &lt;a href=&quot;https://arxiv.org/abs/2312.11456&quot;&gt;Iterative Preference Learning from Human Feedback: Bridging Theory and Practice for RLHF under KL-Constraint&lt;/a&gt;에서는 DPO iterate마다 응답 길이가 2.5배씩 길어진다는 연구 결과도 리포트 됐습니다.&lt;/p&gt;
&lt;h2&gt;AI가 말을 길게 하면 좋은거 아닌가?&lt;/h2&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/8a3ce021-df65-42ea-ad2d-b29cfc7a1e9f&quot; width=&quot;400&quot;&gt;
&lt;p&gt;LLM이 응답을 길게길게하면 좋은거 아닐까요? 실제로 RLHF 나오기 이전에는 LLM의 응답이 짧은게 큰 골칫거리였습니다. 😮‍💨 그리고 실제로 사람들은 AI가 길게 답변을 해주면 더 좋은 답변이라고 느끼는 경향이 있다고 합니다! 😲 그런데 이제 RLHF가 나오면서 말이 길어졌다고 하니, 좋은거 아닌가? 하는 분들도 있으실 것 같습니다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/8d1fd586-1f60-4cd6-b705-b49f9a40aff6&quot; width=&quot;400&quot;&gt;
&lt;p&gt;하지만, 뭐든지 그때그때 “알맞게” 답변해주는 것이 가장 이상적입니다. ‘네’, ‘아니오’ 정도의 응답만 필요한데, ‘네 그것은 어쩌고저쩌고 …’ 와 같이 항상 길게 답변을 해준다면, 읽는 사람 입장에서 피로감을 유발하게 됩니다. 그런 관점에서, LLM의 응답이 전체적으로 길어지는 현상은 마냥 좋다고 볼 수는 없습니다. 또한, 현재 RLHF를 적용한 모델의 경향성을 보면, 응답 길이의 평균 자체가 상당히 높아져서 오히려 짧은 답변을 못한다고 봐야될 것 같습니다.&lt;/p&gt;
&lt;h2&gt;그렇다면 해결방법은?&lt;/h2&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/3a6679b2-b4ec-42bc-84be-13145402182f&quot; width=&quot;400&quot;&gt;
&lt;p&gt;그렇다고 RLHF를 적용 안 할 수도 없는 노릇인데.. 어떻게 해야될까요?&lt;/p&gt;
&lt;p&gt;아직 명확한 답은 없지만, 최근 1-2개월 사이의 연구들에서 다양한 방식으로 이 문제를 해결하기 위한 방법들을 내놓고 있습니다. 다양한 방법들이 나오고 있는 만큼 조만간 이 문제에 대해서도 해결되지 않을까 기대해보고 있습니다! 관심 있으신 분들을 위해 관련 논문 2편 추천드리고 이번 포스팅은 여기에서 마무리하도록 하겠습니다! 😎&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2402.18571&quot;&gt;Arithmetic Control of LLMs for Diverse User Preferences: Directional Preference Alignment with Multi-Objective Rewards&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/7108c7d6-d435-4654-9457-81e63d51783f&quot; width=&quot;500&quot;&gt;
&lt;p&gt;DPA(Directional Preference Alignment)라는 방법을 제시하며 multi-objective reward를 통해 LLM의 응답 길이 및 기타 문제들을 완화하는 방법을 제안&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2402.07319&quot;&gt;ODIN: Disentangled Reward Mitigates Hacking in RLHF&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/3b271b64-8b0f-463d-916d-48dea2d7f132&quot; width=&quot;500&quot;&gt;
&lt;p&gt;ODIN이라는 방식을 제안. 기존 loss에서 length와 quality 관련된 수식을 추가함.&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2310.03716&quot;&gt;A Long Way to Go: Investigating Length Correlations in RLHF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2402.18571&quot;&gt;Arithmetic Control of LLMs for Diverse User Preferences: Directional Preference Alignment with Multi-Objective Rewards&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2308.02312&quot;&gt;Is Stack Overflow Obsolete? An Empirical Study of the Characteristics of ChatGPT Answers to Stack Overflow Questions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2312.11456&quot;&gt;Iterative Preference Learning from Human Feedback: Bridging Theory and Practice for RLHF under KL-Constraint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2402.07319&quot;&gt;ODIN: Disentangled Reward Mitigates Hacking in RLHF&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[규칙 없음 (No Rules Rules)]]></title><description><![CDATA[규칙 없음 (No Rules Rules) ‘오징어게임’, ‘더 글로리’, ‘종이의 집’ 등으로 알려진 세계 최대 OTT(Over The Top) 플랫폼 ‘넷플릭스’는 이제는 국내에서도 누구나 알만한 서비스가 됐다. 2023년 1…]]></description><link>https://sooftware.github.io/no-rules-rules/</link><guid isPermaLink="false">https://sooftware.github.io/no-rules-rules/</guid><pubDate>Mon, 04 Mar 2024 22:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;규칙 없음 (No Rules Rules)&lt;/h1&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/5862ee79-335a-4e72-b021-58c3f306bdda&quot; height=&quot;250&quot;&gt;
&lt;p&gt;‘오징어게임’, ‘더 글로리’, ‘종이의 집’ 등으로 알려진 세계 최대 OTT(Over The Top) 플랫폼 ‘넷플릭스’는 이제는 국내에서도 누구나 알만한 서비스가 됐다. 2023년 10월 기준으로 국내 넷플릭스 MAU(월간 활성 이용자 수)는 1,137만명이라고 한다. 😲 개인적으로도 굉장히 애용하는 서비스인데, 넷플릭스 오리지널 시리즈는 정말 획기적인 아이디어였다고 생각한다. OTT 서비스를 하는 기업에서 직접 영화/드라마를 만들고, 해당 OTT에서만 볼 수 있게 함으로써, 넷플릭스 오리지널 시리즈를 보고 싶은 사람들은 넷플릭스를 구독할 수 밖에 없게 만들어버렸다. 과연 이런 혁신적인 아이디어는 어떻게 나오게 되고 어떻게 실행되는걸까?&lt;/p&gt;
&lt;h2&gt;규칙없음&lt;/h2&gt;
&lt;p&gt;[규칙없음]은 넷플릭스의 이런 혁신의 바탕이 된 기업 문화에 대해서 창립자이자 CEO인 ‘리드 헤이스팅스’와 기업 문화에 대해서 연구하는 ‘에린 마이어’가 저술한 책이다. 세계적인 기업의 CEO가 저술했다는 사실만으로도 굉장히 흥미로운 책인데, 넷플릭스의 기업 문화에 대해 다룬다는 점에서 더 매력적이였다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/e724a42d-51ca-4cb7-83b3-dab3b6038274&quot; width=&quot;450&quot;&gt;
&lt;p&gt;한국과 미국의 기업 문화는 어떤 점이 얼마나 다를까? 그리고 넷플릭스의 기업 문화는 뭐가 얼마나 특별하길래 책 제목을 [규칙없음]으로 지어놓은걸까? 나도 스타트업의 공동창업자로써 어느덧 3년이 지났는데, 창업 이후 여러 경험을 하면서 기업 문화의 중요성에 대해서 체감하고 있다. 창업 이전에 있었던 회사는 자유로운 분위기의 회사였다. 직원이였던 내 입장에서는 자유로운 분위기가 좋았지만, 때로는 지나친 자유로 인해 생기는 마찰들도 있었다. 하나하나 모든걸 통제하는 문화도 너무 숨막히고, 그렇다고 너무 자유로운것도 문제가 생기는 것을 보면서, 과연 이 중심을 어떻게 잡는게 좋은 것인지에 대해서 많은 생각을 했다. 과연 세계적인 기업의 리더는 어떻게 기업 문화를 형성하고 이끌어가는지 궁금했고, 이 물음에 대한 ‘리드 헤이스팅스’(이하 리드)의 답을 [규칙없음]에서 읽어볼 수 있었다!&lt;/p&gt;
&lt;h3&gt;인재밀도를 높여라!&lt;/h3&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/d8c6a6c5-de58-41ff-bfa2-aa5adbfdbdb6&quot; width=&quot;450&quot;&gt;
&lt;p&gt;넷플릭스에는 이런 말이 있다고 한다. “최고의 복지는 최고의 동료다!” 이 말처럼, 리드는 인재밀도(talent density)를 높여야 한다고 말한다. 인재밀도를 높이라는 말은 쉽게 말하면 탁월한 능력을 가진 사람들로 팀을 구성하라는 말이다. 평범한 10명의 사람보다 능력있는 1명의 사람이 더 높은 성과를 낸다는 말이다. 리드는 넷플릭스 이전에 창업했던 ‘퓨어소프트’라는 회사에서 회사 상황이 안 좋아지면서 성과가 좋지 않은 직원들을 해고할 수 밖에 없었다고 한다. 그런데 이상하게도 직원의 수가 줄었는데도 불구하고, 성과가 좋았던 직원들로만 팀을 구성하니 회사의 능률과 퍼포먼스가 좋아지면서 위기를 극복할 수 있었고, 리드는 이를 계기로 인재밀도의 중요성에 대해서 알게 됐다고 한다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/8b8092c7-ab30-491a-8df2-0f9561b790dc&quot; width=&quot;350&quot;&gt;
&lt;p&gt;리드는 이를 두고, 성과는 전염성이 강하다고 표현했다. 성과가 좋지 않은 직원들은 능력있는 직원들의 퍼포먼스도 낮추기 때문에, 회사를 위해서 이런 직원들은 퇴직금을 두둑히 주고 떠나보내야 한다고 한다. 😲 (여기서 말하는 인재밀도는 능력적인 부분도 있지만, 회사 분위기를 망친다던지, 일반적인 상식선에서의 행동 등 다양한 부분을 포괄한다.)&lt;/p&gt;
&lt;p&gt;그래서 넷플릭스에는 인재 밀도를 높이기 위한 규칙이 있다고 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;평범한 사람들은 두둑한 퇴직금을 주고 내보낸다.&lt;/li&gt;
&lt;li&gt;주기적으로 이 직원이 해당 업무에서 최고의 인재인지를 물어보는 ‘키퍼 테스트’를 한다.&lt;/li&gt;
&lt;li&gt;최고의 인재라면, 업계 최고의 대우를 해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;아래는 넷플릭스의 키퍼 테스트 문구다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;팀원 중 한 사람이 내일 그만두겠다고 하면,
다시 한 번 생각해보라고 설득하겠는가,
아니면 속으로 다행이라고 생각하며 사직서를 수리하겠는가?

후자라면 지금 당장 퇴직금을 주고 스타 플레이어를 찾아라.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;넷플릭스에서는 이런 질문을 주기적으로 해보면서 자체적으로 키퍼 테스트를 한 뒤, 후자에 해당하는 사람들에게는 퇴직금을 주고 해고한다고 한다. 넷플릭스가 인재밀도를 높이기 위해 얼마나 노력하는지/냉정한지를 알 수 있었던 대목이였다.&lt;/p&gt;
&lt;h3&gt;솔직한 피드백&lt;/h3&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/e82a8cf3-6765-4cbb-860c-3ce7ecce1e6b&quot; width=&quot;350&quot;&gt;
&lt;p&gt;두 번째로 넷플릭스에서는 솔직한 피드백을 강조한다. 그게 팀장이 팀원에게 하는 피드백만이 아닌, 팀원이 팀장에게 주는 피드백을 포함하여 CEO를 포함한 모든 넷플릭스 구성원들에게 피드백을 할 수 있다고 한다. 업무 방식, 영어 발음, 회의 중 혼자만 너무 말을 많이하는 것 등 일할 때 아쉬운 점들에 대해 즉각적으로 피드백할 것을 권장한다고 한다.하지만 피드백을 가장한 비난이 될 수도 있기 때문에 넷플릭스에서는 ‘피드백 4A 원칙’을 세웠다고 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AIM TO ASSIST (피드백을 도움을 주겠다는 생각으로 하라)&lt;/li&gt;
&lt;li&gt;ACTIONABLE (피드백에 실질적인 조치를 포함하라)&lt;/li&gt;
&lt;li&gt;APPRECIATE (피드백 준것에 대해 고마워해라)&lt;/li&gt;
&lt;li&gt;ACCEPT OR DISCARD (피드백을 받아들이거나 거부하라)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;‘피드백’이라는게 실제로 회사생활을 해보면 참 어려운 주제다. 우리나라말로하면 ‘쓴소리’라고 할 수 있을 것 같다. 그리고 우리나라 정서상 다른 사람에게 쓴소리를 하거나 듣는게 익숙치 않은게 사실이다. 하지만 피드백을 적절히 주고받는 조직일수록, 구성원들과 조직이 더 성장할 수 있을 것이다. 넷플릭스는 이러한 문화를 만들기 위해 대표부터 리더들까지 직원들로부터 피드백을 받는것에 모범을 보이기 위해 많은 노력을 했다고 한다.&lt;/p&gt;
&lt;h3&gt;통제를 없애라&lt;/h3&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/1552e3e1-a41f-4606-bf42-1b9086ac9b68&quot; width=&quot;500&quot;&gt;
&lt;p&gt;넷플릭스에는 휴가에 대한 규정도, 출장이나 경비에 대한 승인 절차도 없다고 한다. 다음 두가지 상황을 보자.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;해외 출장이 있고, 비행기는 몇 일을 타야하는데, 도착하자마자 중요한 비즈니스 미팅이 있다. 그러면 출장시 비즈니스석으로 예매를 해야할까 아니면 일반석으로 예매를 해야할까?&lt;/li&gt;
&lt;li&gt;제주도 출장 일정이 잡혔고, 도착 다음 날 비즈니스 미팅이 있다. 그러면 출장시 비즈니스석으로 예매를 해야할까 아니면 일반석으로 예매를 해야할까?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;위의 1번과 2번 상황 같이 똑같은 출장이여도 얼마나 중요한 미팅인지, 탑승 시간이 얼마나 되는지, 미팅이 당일에 있는지 다음날에 있는지 등 여러 케이스가 있다. 보통의 회사들은 이런 상황들에 대해서 규정이 하나하나 정해져 있을 것이다. 정해진 규정이 없는 경우에는 새로 논의해서 새로 만들기도하며, 일반적인 회사들은 회사규정을 통해서 직원들을 통제한다.&lt;/p&gt;
&lt;p&gt;하지만 세상 일이 그렇게 딱딱 떨어지지 않는다. 규정상은 일반석으로 타야되더라도 너무나 중요한 미팅이라 내 컨디션이 최고로 중요할 경우도 있고, 당장 행사에 필요한 지출인데 승인이 필요해서 법인카드를 사용하지 못하는 바람에 행사를 망칠수도 있다.&lt;/p&gt;
&lt;p&gt;반면에, 이러한 규정이 없어버리면 일부 인원들이 남용하며 사용하는 경우도 있다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/72ed1fd1-f925-42bd-b656-0f7540ba3243&quot; width=&quot;400&quot;&gt;
&lt;p&gt;넷플릭스는 이러한 상황에 대해 규정을 하나하나 만드는 대신, 다음 문구 하나만을 규정했다고 한다.&lt;/p&gt;
&lt;p&gt;”&lt;em&gt;&lt;strong&gt;넷플릭스의 이익에 최선이 되는 방향으로 행동하라&lt;/strong&gt;&lt;/em&gt;”&lt;/p&gt;
&lt;p&gt;넷플릭스에서는 직원들의 자율적인 판단에 맡긴다고 한다. 비용 지출에 대한 상사의 승인도 필요없고, 출장시 비즈니스석을 탈지 or 일반석을 탈지에 대해서 승인 없이 본인이 선택하면 된다고 한다. 하지만 이러한 규정 없음을 남용하는 경우를 방지하기 위해 넷플릭스 감사팀에서 랜덤하게 뽑아서 살펴본 뒤, 남용이라고 판단되는 경우는 가차없이 해고를 한다고 한다. 🥶&lt;/p&gt;
&lt;h2&gt;규칙없음에 대한 나의 의견&lt;/h2&gt;
&lt;p&gt;넷플릭스의 기업 문화와 CEO가 추구하는 방향성에 대해서 살펴볼 수 있어서 굉장히 인상깊고 재밌게 읽었다. 스타트업 공동창업자로서 기업 문화를 만들어나갔고, 현재도 만들어나가고 있는 입장에서 글로벌 기업 대표의 경험담을 들어볼 수 있어서 많은 참고가 됐다.&lt;/p&gt;
&lt;h3&gt;인재밀도에 대한 의견&lt;/h3&gt;
&lt;p&gt;좋은 인재로 직원들을 구성하는게 좋다는걸 모르는 사람은 없다. 문제는 보통의 기업은업계 최고의 인재를 데려오는게 어렵다는 것이다. 업계 최고의 인재를 데려오고, 업계 최고의 대우를 해주며, 이 인원이 더 이상 업계최고의 인재가 아니게 됐을 때 가차없이 해고를 하는건 넷플릭스 정도의 글로벌 대기업이니까 가능한게 아닌가하는 생각이 들었다.&lt;/p&gt;
&lt;p&gt;작게 시작하는 스타트업에서 최고의 인재만을 고집한다면 그 스타트업은 채용이 더뎌질 수 밖에 없고, (아예 채용을 못하게 될수도..) 이는 속도가 중요한 스타트업에게 있어서 속도를 낼 수 없게 되는 큰 걸림돌이 될 것이다. 그래서 내 생각엔 기업의 규모, 단계에 따라서 유연성을 가지고 접근해야 된다고 생각한다. 작은 스타트업이 구글, OpenAI, 넷플릭스 같은 기업들과 연봉 경쟁을 할 수 있을지에 대해서도 생각해봐야 할 것이다. 물론, 핵심 인력에 있어서는 최고를 고집해야 된다고 생각하지만, 모든 직원들을 최고의 인재로 유지한다는건 넷플릭스 정도의 글로벌 기업에서나 가능한 일 아닐까? 🤔&lt;/p&gt;
&lt;p&gt;또한, 최고의 인재밀도를 유지하기 위해서는 잦은 해고가 불가피한데, 직원들이 본인이 언제 짤릴지 모른다는 불안감과 긴장감이 사내에 돌 것이다. 직원 입장에서는 열심히 성과를 냈는데 잠시 슬럼프가 와서 성과가 안 좋았더니 바로 해고를 당한다면, 토사구팽 당한다고 생각할 수도 있는 문제이다.&lt;/p&gt;
&lt;p&gt;이에 대해서 리드는 어려운 일이지만 이렇게 최고의 인재밀도만을 고집해서 넷플릭스 같은 기업을 만들 수 있었다고 얘기할지도 모르겠다. 하지만 이게 현실적으로도 도덕적으로도 맞는지에 대해서 좀 더 생각해 볼 필요가 있어보인다.&lt;/p&gt;
&lt;h3&gt;솔직한 피드백에 대한 의견&lt;/h3&gt;
&lt;p&gt;대부분의 한국 회사들은 피드백 문화가 거의 없는 것 같다. 직원들이 상사에게 피드백을 주는 것은 퇴사할 때를 제외하고는 보기 드물며, 상사가 피드백을 주는 경우도 꼰대 혹은 잔소리 정도로 치부하고 넘어가는 경우가 많다. 그리고 무엇보다 문제점은 피드백을 줄 때, 비난성 피드백을 주는 경우가 많은게 가장 문제인 것 같다.&lt;/p&gt;
&lt;p&gt;그런 의미에서 리드가 제시한 ‘피드백 4A 원칙’은 정말 좋은 원칙이라고 생각한다. 이 원칙을 실제로 사내 문화로 자리잡게 하는 것은 정말 어렵다고 생각되지만, 나부터도 피드백을 줄 때 / 받을 때 이 원칙들을 잘 지키고 있는지 돌아봐야겠다.&lt;/p&gt;
&lt;h3&gt;‘통제하지 마라!’에 대한 의견&lt;/h3&gt;
&lt;p&gt;직원들이 상황에 유연하게 대처할 수 있도록 하나하나 규정하지 않는 것은 아주 좋은 제도라고 생각한다! 규정이 하나하나 있으면 직원들이 그때마다 규정집을 찾아봐야하며, 인사팀에 이건 어떤 규정에 해당하는지를 문의하고 답하며 괜한 에너지를 소비하게 만든다. 그런면에서, “넷플릭스의 이익에 최선이 되는 방향으로 행동하라”라는 문구로 통제를 없앤 것은 굉장히 현명했다고 생각이 든다. 하지만 한편으로는 명확한 규정이 없다보니 회사에서 남용이라고 판단한 사안에 대해서 직원 입장에서는 항의하기가 어려우며, 어떻게보면 회사 입장에서 가장 편리한 규정을 만든 것이 아닌가라는 생각도 든다. 🤔&lt;/p&gt;
&lt;h2&gt;마치며&lt;/h2&gt;
&lt;p&gt;[규칙없음]을 읽으며 넷플릭스의 업무 방식은 어떤지, 대표인 리드 헤이스팅스는 어떤 생각을 가지고 기업 문화를 꾸려나가는지를 간접적으로 경험하며 우리 기업 문화와도 비교해보며 많은 것을 배울 수 있었다! 기업 문화 관련된 일을 하는 분들, 창업하려는 분들, 스타트업에 종사하는 분들은 한 번씩 읽어보면 좋을 것 같다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[튜닙, AICA H100 * 8대 GPU 지원 선정]]></title><description><![CDATA[튜닙, AICA H100 * 8대 GPU 지원 선정 저희 튜닙이 인공지능산업융합사업단(AICA)에서 지원하는 ‘2024년 AI 데이터센터 서비스’ 사업에 선정되면서 1년간 H100 *…]]></description><link>https://sooftware.github.io/aica-h100/</link><guid isPermaLink="false">https://sooftware.github.io/aica-h100/</guid><pubDate>Sat, 24 Feb 2024 14:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;튜닙, AICA H100 * 8대 GPU 지원 선정&lt;/h1&gt;
&lt;p&gt;저희 튜닙이 인공지능산업융합사업단(AICA)에서 지원하는 ‘2024년 AI 데이터센터 서비스’ 사업에 선정되면서 1년간 H100 * 8대를 지원받게 됐습니다! 🎉 🎉.&lt;/p&gt;
&lt;p&gt;이 사업공고가 나오자마자 이건 무조건 돼야된다고 생각하고 사업계획서를 작성하는데 크게 공 들였습니다. 선정 발표가 예정보다 늦어지면서 가슴 졸이며 기다렸는데 어제 선정됐다는 좋은 결과가 나와서 무척 다행이였습니다! 😭&lt;/p&gt;
&lt;p&gt;AI 개발에 GPU 자원은 필수적입니다. H100은 현재 사용 가능한 최고 성능의 GPU입니다. AWS에서 H100 8대를 1년간 사용할 시, 비용이 11억 8,200만원입니다. ($=1,350 기준) 💸&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/5082178d-e05b-4553-9f2d-33efb5e74d19&quot; width=&quot;550&quot;&gt;
&lt;p&gt;H100 이전 시리즈인 A100도 충분히 좋은 GPU인데도 불구하고, H100과 비교하면 성능 차이가 꽤 나게 됩니다. 어떤 AI 모델을 사용하느냐에 따라 다르겠지만, A100과 비교하여 3~6배 정도 더 빠르다고 알려져 있습니다. 이렇게 성능 좋은 장비를 8대나 지원받게 되어 무척 기쁘고, 앞으로 해볼 여러 실험들에 속도를 가할 수 있게 됐습니다! 이 장비들로 올해에 저희 자체 LLM인 &lt;em&gt;&lt;strong&gt;Cheetah&lt;/strong&gt;&lt;/em&gt; 성능을 크게 더 높여보겠습니다. 😎&lt;/p&gt;
&lt;p&gt;인공지능산업융합사업단 만세 !!!!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[튜닙, 삼성 C-Lab Outside 선정 & 사무실 이사]]></title><description><![CDATA[튜닙, 삼성 C-Lab Outside 선정 & 사무실 이사 저희 튜닙이 삼성 C-Lab Outside에 선정됐습니다! 😄 😄 C-Lab Outside는 삼성전자의 사외 스타트업 육성 프로그램으로, 국내 유망 스타트업을 육성하기 위해 201…]]></description><link>https://sooftware.github.io/c-lab/</link><guid isPermaLink="false">https://sooftware.github.io/c-lab/</guid><pubDate>Sat, 24 Feb 2024 11:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;튜닙, 삼성 C-Lab Outside 선정 &amp;#x26; 사무실 이사&lt;/h1&gt;
&lt;p&gt;저희 튜닙이 삼성 C-Lab Outside에 선정됐습니다! 😄 😄&lt;br&gt;
C-Lab Outside는 삼성전자의 사외 스타트업 육성 프로그램으로, 국내 유망 스타트업을 육성하기 위해 2018년부터 출범한 프로그램입니다.&lt;/p&gt;
&lt;p&gt;삼성전자 같은 우리나라 대표적인 대기업이자 글로벌 기업에서 지원해주는 프로그램에 선정된것이 기쁩니다. C-Lab Ouside에 선정된 기업은 아래와 같은 혜택이 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;img width=&quot;650&quot; alt=&quot;image&quot; src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/e35734cf-adc3-4160-ab08-5dff23240b34&quot;&gt;.&lt;/p&gt;
&lt;p&gt;그래서 저희가 이번에 판교에 있던 사무실을 삼성전자 서울 R&amp;#x26;D 캠퍼스로 (서울 서초구 성촌길 33) 이사를 하게 됐습니다! 내부 사진은 찍지 못하게 되어있어서 사진은 공유하기 어렵지만, 공간이 넓고 굉장히 쾌적합니다. 전에 있었던 네이버 D2SF 사무실과 비슷한 분위기입니다. 그리고 무엇보다 아침, 점심, 저녁 식사를 제공해주는데 밥이 굉장히 맛있어서 저희 튜니버들도 만족하고 있습니다.&lt;/p&gt;
&lt;p&gt;사무실은 양재역 근처인데, 근처에 있으신 분들 중 티타임 가지실 분은 편하게 연락주세요!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[tmux - conf]]></title><description><![CDATA[tmux - conf Tmux 설정을 위한 tmux configuraion 기록]]></description><link>https://sooftware.github.io/tmux-conf/</link><guid isPermaLink="false">https://sooftware.github.io/tmux-conf/</guid><pubDate>Thu, 15 Feb 2024 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;tmux - conf&lt;/h1&gt;
&lt;p&gt;Tmux 설정을 위한 tmux configuraion 기록&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;~/.tmux.conf&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;set-option -g remain-on-exit on

unbind C-b
set-option -g prefix C-b

&lt;span class=&quot;token comment&quot;&gt;# Make shift+arrows, ctrl+arrows etc work in Vim.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; -g xterm-keys on

&lt;span class=&quot;token comment&quot;&gt;# See if this fixes slow ESC issues.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# http://unix.stackexchange.com/questions/23138/esc-key-causes-a-small-delay-in-terminal-due-to-its-alt-behavior&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; -s escape-time &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Start window and pane indices at 1.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; -g base-index &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; -g pane-base-index &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Status bar styling and content.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; -g status-bg black
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; -g status-fg white
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; -g status-left &lt;span class=&quot;token string&quot;&gt;&apos;#S &apos;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Show keyboard layout in prompt, assuming some script writes it to that path;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# it&apos;s &quot;/User/…&quot; instead of &quot;~&quot; so VMs can read from their symlinked OS X host home directory.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; -g status-right &lt;span class=&quot;token string&quot;&gt;&apos;#(cat /Users/$USER/.keyboard_layout 2&gt; /dev/null) | #22T | %H:%M %d-%b-%y&apos;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; -g status-right-length &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; -g status-interval &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Highlight the active window in the status bar.&lt;/span&gt;
set-window-option -g window-status-current-bg yellow
set-window-option -g window-status-current-fg black

&lt;span class=&quot;token comment&quot;&gt;# Don&apos;t prompt to kill panes/windows.&lt;/span&gt;
bind-key x kill-pane
bind-key &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; kill-window

&lt;span class=&quot;token comment&quot;&gt;# Cycle panes.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;bind&lt;/span&gt; b select-pane -t :.+
&lt;span class=&quot;token builtin class-name&quot;&gt;bind&lt;/span&gt; C-b select-pane -t :.+

&lt;span class=&quot;token comment&quot;&gt;# More intuitive split-window mappings.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;bind&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&apos;&quot;&lt;/span&gt; split-window -h
&lt;span class=&quot;token builtin class-name&quot;&gt;bind&lt;/span&gt; - split-window -v

&lt;span class=&quot;token comment&quot;&gt;# Maximize pane, e.g. for copying.&lt;/span&gt;
bind-key z resize-pane -Z

&lt;span class=&quot;token comment&quot;&gt;# Switch pane and zoom&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# https://twitter.com/tskogberg/status/792025881573199872&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;bind&lt;/span&gt; C-z select-pane -t :.+ &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; resize-pane -Z

&lt;span class=&quot;token comment&quot;&gt;# Reload tmux conf.&lt;/span&gt;
unbind r
&lt;span class=&quot;token builtin class-name&quot;&gt;bind&lt;/span&gt; r source-file ~/.tmux.conf&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; display &lt;span class=&quot;token string&quot;&gt;&quot;Reloaded conf.&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# http://robots.thoughtbot.com/tmux-copy-paste-on-os-x-a-better-future&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Use vim keybindings in copy mode&lt;/span&gt;
setw -g mode-keys &lt;span class=&quot;token function&quot;&gt;vi&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Unbork my iTerm ctrl+1 etc mappings in tmux 2.1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# https://github.com/tmux/tmux/issues/159&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; -g assume-paste-time &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ tmux source ~/.tmux.conf&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[울트라러닝 (Ultra Learning)]]></title><description><![CDATA[# 울트라러닝 (Ultra Learning) 읽은지 한 달 정도 지나서 어느새 디테일한 내용은 가물가물하지만, 기억이 더 희미해지기 전에 리뷰를 남겨두려고 한다. 가끔 참 너무하다 싶을 정도로 공부해야될게 너무 많다. 초중고 12년과 대학 교육…]]></description><link>https://sooftware.github.io/ultra-learning/</link><guid isPermaLink="false">https://sooftware.github.io/ultra-learning/</guid><pubDate>Sun, 04 Feb 2024 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;# 울트라러닝 (Ultra Learning)&lt;/h1&gt;
&lt;p&gt;읽은지 한 달 정도 지나서 어느새 디테일한 내용은 가물가물하지만, 기억이 더 희미해지기 전에 리뷰를 남겨두려고 한다. 가끔 참 너무하다 싶을 정도로 공부해야될게 너무 많다. 초중고 12년과 대학 교육 4년의 교육을 받았지만, 아직도 공부해야될건 산더미같다. 이 책의 저자는 ‘울트라 러닝’이라는 개념에 대해 소개하고, 여러 사례들을 소개해준다. MIT 컴퓨터공학 4년 과정을 1년만에 독파한 사례, 외국어를 몇 달마다 하나씩 능숙하게 구사하는 사람의 사례 등 다양한 울트라 러닝 사례를 소개한다.&lt;/p&gt;
&lt;h2&gt;## 내 전공을 1년 안에 독파 할 수 있을까?&lt;/h2&gt;
&lt;p&gt;공학을 전공한 사람으로써, MIT 컴퓨터 공학을 1년만에 독파했다는 글을 봤을 때 굉장히 흥미로웠다. 과연 내 전공(전자통신공학)은 1년만에 독파할 수 있을까? 에 대해 생각해보았다.&lt;/p&gt;
&lt;p&gt;총 4년의 교육과정 중 실제로 빡세게 공부해야 했던 기간은 2학년, 3학년, 4학년 1학기 정도였던 것 같다. 1학년은 교양과목이나 기초 수학, 물리 등을 배웠는데, 고등학생때 배웠던 개념을 활용하는 수준이였고, 4학년 2학기때는 전공과목을 하나도 안 들었으니, 내가 전공 공부를 한 기간은 2.5년 정도 잡아야 될 것 같다. 그리고 난 부전공도 했으니, 이 부전공을 제외한 전공만 계산한다면, 2.0년으로 잡으면 될 것 같다.&lt;/p&gt;
&lt;p&gt;난 내 전공을 위해서 2년을 투자했다는 계산이 나왔다. 과연 이걸 1년으로 줄일 수 있을까?&lt;/p&gt;
&lt;p&gt;내 대학시절을 돌이켜보면, 난 정말 열심히 공부했던 것 같다. 매학기 7-8 전공을 듣느라 오전부터 저녁까지는 계속 수업을 듣고, 저녁부터 새벽까지는 친구들과 도서관에서 과제와 공부를 하면 하루가 끝났던 기억이 난다. 그렇게 매일을 살아도 과제를 다 못하거나 시험 범위를 모두 공부 못하는 일이 꽤 있었던걸로 기억한다. 그랬던 전공 공부를 2년에서 1년으로 줄이기는 어려워보인다. 그런데 저자는 어떻게 컴퓨터공학을 1년만에 독파했을까? 그것도 MIT의 교육과정을.&lt;/p&gt;
&lt;h2&gt;## 울트라러닝&lt;/h2&gt;
&lt;p&gt;저자는 여러 사례를 들며, 울트라러닝에 대해 설명해준다. 특별한 비법을 기대했지만, 사실 특별하다고 느껴진 건 딱히 없었다. 영어를 빠르게 배우려면, 영어권 나라에 가서 오직 영어만 쓴다는 법칙을 정하고 이행하라, 피드백 받는걸 두려워하지 말고 적극적으로 피드백을 받고 개선하라, 안전지대에 있지말고 도전적인 목표를 세우고 실행하라와 같이 어찌보면 뻔한 말들의 연속이였다.&lt;/p&gt;
&lt;p&gt;하지만, 하나같이 이론으로 알고는 있지만 직접 실천하기에는 어려운 일들이였다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;미국에 가서 한국인을 만나도 오직 영어만 사용한다.&lt;/li&gt;
&lt;li&gt;최대한 냉정하고 비판적인 말을 들을 수 있는 곳으로 가서 피드백을 구한다.&lt;/li&gt;
&lt;li&gt;(일반적으로 생각했을 때) 말도안될 정도로 높은 목표를 세우고 도전한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;실력 향상에 도움이 된다는걸 머리로는 알지만, 실제로 실행하려면 많은 용기와 결단력이 필요한 일들이다. 그래서 책을 다 읽고 나서 든 생각은 울트라러닝에 특별한 비법이 있는건 아니고, 우리가 학습에 도움이 되는걸 알지만 실행하지 못한 일들을 정말 열심히 처절하게 실천했을 때, 나오는 결과가 울트라러닝이라는 생각이 들었다.&lt;/p&gt;
&lt;p&gt;개인적으로 즐겨보는 웹툰 ‘화산귀환’에 아래와 같은 대사가 나온다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;하루 중 반 이상을 공부하고, 남은 시간에 몸가짐을 바르게 하며, 부모를 진심으로 봉양하고,
약자를 기만하지 않으며, 재물을 탐하지 않고, 위로는 예를 다하되,
아래로는 존중을 잃지 않고, 친우를 진심으로 대하며,
나라에는 충성을 다하며 살라고 하면 그렇게 살 수 있나?

왜 못해? 그것만 지키면 군자가 되는데.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 대사처럼 군자가 되는 법을 이론적으로 아는건 쉽다. 이를 평생 실천할 수 있는 사람이 극소수일 뿐이다.&lt;/p&gt;
&lt;p&gt;군자의 경우처럼, 울트라러닝도 무언가를 학습하는데 저자만이 아는 특별한 비법이 있는게 아니라, 우리들이 일반적으로 알고있는 학습에 도움이 되는 일들을 피하지말고 열심히 실천하는게 가장 중요한 것 같다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Meta는 왜 LLaMA를 공개할까?]]></title><description><![CDATA[Meta는 왜 LLaMA를 공개할까? Meta(구 Facebook)은 FAANG(Facebook, Apple, Amazon, Netflix, Google)라는 용어가 있을 정도로 거대 IT 기업 중 하나입니다. Meta는 지금 LLM…]]></description><link>https://sooftware.github.io/meta-llama/</link><guid isPermaLink="false">https://sooftware.github.io/meta-llama/</guid><pubDate>Sat, 20 Jan 2024 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Meta는 왜 LLaMA를 공개할까?&lt;/h1&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/6dfc9147-fa1e-4dc2-b9ef-2609d23b4dbf&quot; width=&quot;500&quot;&gt;
&lt;p&gt;Meta(구 Facebook)은 FAANG(Facebook, Apple, Amazon, Netflix, Google)라는 용어가 있을 정도로 거대 IT 기업 중 하나입니다. Meta는 지금 LLM 시대가 열리기 전, &lt;a href=&quot;https://arxiv.org/abs/1907.11692&quot;&gt;RoBERTa&lt;/a&gt;, &lt;a href=&quot;https://arxiv.org/abs/2006.11477&quot;&gt;Wav2vec 2.0&lt;/a&gt;, &lt;a href=&quot;https://arxiv.org/abs/2208.03188&quot;&gt;Blenderbot&lt;/a&gt; 등 A.I.쪽에 큰 영향력을 끼친 연구들을 공개하며, OpenAI, Google과 함께 대표적인 A.I. 선진 기업이였습니다.&lt;/p&gt;
&lt;p&gt;또한, 현재는 많이 쓰이진 않지만, &lt;a href=&quot;https://github.com/facebookresearch/fairseq&quot;&gt;Fairseq&lt;/a&gt;이라는 오픈소스 툴킷으로 자신들의 연구에 쓰인 코드들을 모두 공개하며, 많은 리서쳐 / 엔지니어들이 본인들의 연구를 활용할 수 있도록 큰 도움을 줬습니다. 이 툴킷은 굉장히 잘 작성된 높은 수준의 코드로, 현재 자연어처리에서 가장 영향력이 높은 오픈소스 기업인 Huggingface에서도 내부 코드를 살펴보면 Fairseq의 코드를 가져다가 쓴 것을 종종 볼 수 있으며, 논문의 Official 코드여서 실제로 모델이 어떻게 작동하는지, 어떻게 학습됐는지를 살펴볼 수 있는 좋은 학습 자료였습니다.&lt;/p&gt;
&lt;h2&gt;LLaMA&lt;/h2&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/9da0cc81-19c7-4d6f-a58f-67f2bf1e5b0a&quot; width=&quot;600&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://ai.meta.com/llama/&quot;&gt;LLaMA&lt;/a&gt;는 Meta에서 공개한 LLM 모델입니다. 현재 가장 유명하고 좋은 성능을 가진 OpenAI의 ChatGPT나 GPT-4와 다르게, LLaMA-2는 모델 weight를 공개했으며, 상업적으로도 사용이 가능합니다. MAU 7억명 이상인 경우, Meta 측과 협의를 해야하지만, MAU 7억명이 쓸 정도의 서비스가 얼마나 있을까요? 😅 (그 정도 규모의 서비스라면 모델 자체 개발도 가능하지 않을까..)&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/fac535ca-8522-4549-92cb-d5acedd8991e&quot; width=&quot;700&quot;&gt;
&lt;p&gt;Meta는 LLaMA-1에 이어 2023년 7월 LLaMA-2를 공개했습니다. 모델 사이즈는 7B, 13B, 70B로 상당히 큰 사이즈의 모델들을 공개했습니다. LLM 시대의 시작을 알렸던 GPT-3가 175B이였던걸 감안하면, 70B이라는 크기는 상당한 사이즈입니다. (한국어 모델 중 가장 큰 사이즈의 사전학습 모델은 12.8B의 Polyglot-Ko 모델입니다.) Meta가 LLaMA-2 및 테크니컬 리포트까지 공개하면서 전세계 LLM 연구자들에게 많은 기회의 창을 열어주었습니다. LLaMA-2 공개 이후 국내외로 하루하루 새로운 모델과 논문이 쏟아져 나오고 있으며, 오픈소스 진영이 활활 불타오를 수 있는 기름 역할을 해줬습니다. 🔥🔥 (국내에는 준범님이 공개해준 LLaMA-2-Ko가 대표적입니다.) 이러한 Meta의 행보는 ChatGPT를 만든 OpenAI나 발빠르게 ChatGPT와 유사한 Bard, Gemini를 내놓은 Google의 행보와는 아주 대조적입니다. 🤔&lt;/p&gt;
&lt;h2&gt;그렇다면 Meta는 왜 LLaMA를 공개하기로 했을까?&lt;/h2&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/17ba722e-731c-42c8-a250-fce2645b9b5e&quot; width=&quot;550&quot;&gt;
&lt;p&gt;* 해당 부분은 개인적은 견해가 섞여있습니다.&lt;/p&gt;
&lt;p&gt;그렇다면, Meta는 왜? LLaMA를 공개했을까요?  1B짜리 모델을 pre-training하는데도 상당한 비용이 들며, 모델 사이즈가 커질수록 이 비용은 지수적으로 증가하게 됩니다. 하물며 70B 사이즈의 모델 학습을 위해서는 수백~수천억원의 학습 비용이 들게됩니다. 이러한 비용을 들여서 개발한 모델을, 왜 상업적으로도 이용이 가능하도록 공개했을까요? 저는 아래와 같은 이유들이 있다고 생각합니다.&lt;/p&gt;
&lt;h3&gt;1. 어차피 지금 Meta가 LLM 시장을 점유하기는 어렵다.&lt;/h3&gt;
&lt;p&gt;지금 LLM 시장은 큰 격차로 OpenAI가 단독 선두로 달리고 있다고 볼 수 있습니다. ChatGPT 등장전, Google, OpenAI, Meta, Microsoft가 비등비등한 상황이였다면, ChatGPT 등장 이후로는 아래와 같은 상황이 됐습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OpenAI : 단독 선두&lt;/li&gt;
&lt;li&gt;Microsoft : OpenAI에 투자. OpenAI의 최대주주. 사실상 최대 승리자.&lt;/li&gt;
&lt;li&gt;Google : Bard, Gemini를 내놓으며 OpenAI 따라잡기 진행중&lt;/li&gt;
&lt;li&gt;Meta : 포지션 애매..&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이러한 상황에서 사실상 Meta가 갑자기 Google과 OpenAI를 제치며 LLM 시장을 점유하는건 사실상 어려워보였습니다. 이미 커져버린 기술적 격차를 어떻게 해소할지에 대해 내부적으로 많은 고민이 있었을 것으로 보입니다.&lt;/p&gt;
&lt;h3&gt;2. LLaMA 시리즈를 공개함으로써, OpenAI의 독점을 막을 수 있다.&lt;/h3&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/52f804a9-b7a9-41b9-bf03-f5373ed22820&quot; width=&quot;350&quot;&gt;
&lt;p&gt;어차피 LLM 시장을 Meta가 먹지 못할것이라면, OpenAI와 Microsoft가 이 시장을 독점하지 못하도록 막는것이 최선일 수 있을 겁니다. Meta는 메타버스 세상을 꿈꾸고 있습니다. 만약 이대로 OpenAI가 LLM 시장을 독점하게 된다면, Meta는 본인들이 꿈꾸는 세상을 위해 필요한 LLM 기술을 OpenAI와 Microsoft에게 막대한 비용을 지불하고 사용해야 할 겁니다. 이건 미래의 Meta에게 큰 걸림돌이 되겠죠.&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/2cd2df63-bd47-4f21-983e-c2ac6b2a4b1a&quot; width=&quot;400&quot;&gt;
&lt;p&gt;지금 LLM 시장은 과거의 Desktop PC OS(Operating System) 시장을 보는 것 같기도 합니다. 현재 대표적인 Desktop PC OS 시스템은 Microsoft의 Windows, Apple의 OS X, 그리고 오픈소스 OS인 Linux가 있습니다. 2023년 1월 기준으로 Windows는 74%, OS X는 15%, Linux는 3% 정도를 점유하고 있습니다. 압도적으로 Windows가 장악하고 있는 만큼, Microsoft는 막대한 돈을 벌어들이고 있습니다. Meta 입장에서는 OpenAI가 LLM 시장을 이렇게 장악해버리길 원하지 않을겁니다. Meta가 오픈소스 LLM 진영에 LLaMA를 공개하며 힘을 실어줌으로써, OpenAI의 독주를 견제할 수 있다는 점도 Meta가 LLaMA-2를 공개한 큰 이유 중 하나일 것으로 보입니다. 마치 OS 시장에 오픈소스 OS인 리눅스가 있는 것처럼요.&lt;/p&gt;
&lt;h3&gt;3. 집단지성의 힘을 이용해서 OpenAI와의 기술적 격차를 해소한다.&lt;/h3&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/43a1c7c0-75bd-451b-a746-d3bd7bcdf6de&quot; width=&quot;300&quot;&gt;
&lt;p&gt;또한, LLaMA를 공개함으로써 Meta는 OpenAI와의 기술적 격차를 해소할 가능성을 높일 수 있습니다. 집단지성의 힘은 굉장합니다. 실제로 LLaMA 공개 이후 Alpaca, Vicuna, Guanaco 등 다양한 파생 모델이 빠르게 등장했으며, 최근에 핫한 Mistral-AI에서 공개한 Mistral, Mixtral도 LLaMA-2 아키텍처에 기반하여 만들어졌습니다. 이처럼 LLaMA-2를 공개함으로써 오픈소스 LLM 진영의 기술개발에 불이 붙었고, LLM 기술이 필요한 여러 기업들에게 LLaMA-2를 활용하는 선택지가 추가로 주어지게 됐습니다.&lt;/p&gt;
&lt;p&gt;실제로 오픈소스 진영의 약진은 무섭게 OpenAI 기술력을 따라잡고 있습니다. 이러한 집단지성의 힘을 이용하여 OpenAI와의 기술력 차이를 해소하고, 현재 상황을 뒤집을 기회를 노리고 있다고도 볼 수 있을 것 같습니다. 실제로 Meta에서 LLaMA를 활용한 연구들을 예의주시하며, 각종 연구 결과들을 참고하여 기술을 더 발전시켜나가고 있다고 합니다. 😎&lt;/p&gt;
&lt;h3&gt;4. 우수한 인력 확보&lt;/h3&gt;
&lt;p&gt;우수한 인력 확보는 기업에게 가장 중요한 일 중 하나입니다. 빅테크 기업들에서 오픈소스를 공개하는 가장 큰 이유가 인재 확보를 위해서라고 하죠. Meta 입장에서도 LLaMA와 같은 모델을 공개하며 오픈소스에 기여한다는 좋은 이미지를 가져감과 함께 OpenAI의 LLM 기술 독점에 불만을 가지고 있는 전세계의 우수한 리서쳐들에게 ‘Meta에 와서 OpenAI의 독점을 같이 막자!’와 같은 어필을 할 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;여기까지 메타가 왜 LLaMA를 오픈소스로 공개하는지에 대한 제 생각을 서술했습니다. 그렇다면 앞으로의 메타의 행보는 여전히 오픈소스를 향할까요? 🤔&lt;/p&gt;
&lt;h2&gt;LLaMA-3 학습중, 그리고 오픈소스 공개?!&lt;/h2&gt;
&lt;p&gt;몇일 전 메타 CEO인 마크 저커버그의 인터뷰에서 LLaMA-3에 대한 언급이 있었습니다. 내용을 정리하자면 아래와 같습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Meta가 AGI 전쟁에 뛰어든다고 합니다.&lt;/li&gt;
&lt;li&gt;LLaMA-3 학습을 시작했다고 합니다.&lt;/li&gt;
&lt;li&gt;LLaMA-3도 오픈소스로 공개할 예정이라고 합니다.&lt;/li&gt;
&lt;li&gt;AGI 전쟁에 뛰어들기 위해 34만대의 H100을 구매 예정이라고 합니다. (약 15조원..)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;34만대의 H100 구매는 정말 어메이징하네요.. 어쨌든 LLaMA-3를 오픈소스로 공개한다는걸 다시 한 번 확인해준건 아주 기쁜 소식입니다! 하루 빨리 공개돼서 다시 한 번 오픈소스 LLM 진영에 불을 붙여주면 좋겠네요 :)&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;여기까지 ‘Meta는 왜 LLaMA를 공개할까?‘라는 주제에 대해 제 생각을 써봤습니다. 위 내용은 제 개인적인 견해이며, 사실과는 많은 차이가 있을 수 있는 점 참고해주시면 감사하겠습니다. 😁&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2307.09288&quot;&gt;LLaMA-2 Paper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.axios.com/2024/01/18/zuckerberg-meta-llama-3-ai&quot;&gt;Meta begins training Llama 3, reshuffles AI responsibilities&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Atomic Habits (아주 작은 습관의 힘)]]></title><description><![CDATA[Atomic Habits (아주 작은 습관의 힘) 자기계발 서적중 스테디셀러인 ‘Atomic Habits…]]></description><link>https://sooftware.github.io/atomic_habits/</link><guid isPermaLink="false">https://sooftware.github.io/atomic_habits/</guid><pubDate>Sat, 06 Jan 2024 10:01:00 GMT</pubDate><content:encoded>&lt;h1&gt;Atomic Habits (아주 작은 습관의 힘)&lt;/h1&gt;
&lt;p&gt;자기계발 서적중 스테디셀러인 ‘Atomic Habits’을 드디어 읽었다. 습관이 중요하다는걸 모르는 사람이 있을까? 하지만 알면서도 지키기 어렵고 버리기 어려운게 습관이다. 이 작은 습관들이 모이면 얼마나 큰 힘이 되는지, 내 잠재력을 얼마나 끌어낼 수 있는지에 대해 나를 자극시켜보고자 읽게 됐다.&lt;/p&gt;
&lt;p&gt;이 책을 읽은 것 자체가 내 ‘Atomic Hatbits’ 중 하나이다. 출퇴근하며 책을 읽는 습관을 들였고, 지난 2달동안 출퇴근하며 10권의 책을 읽었다. 60일동안 10권을 읽었으니, 6일에 하나 꼴이므로 일주일에 하나 정도 읽었다. 2달동안 10권이면, 1년에는 60권, 10년이면 600권이라는 책을 읽을 수 있다. 그냥 기존처럼 출퇴근 시간을 자면서 보냈을때와 비교하면 10년 뒤에는 책 600권이라는 차이가 생기게 된다. 또한, 이 600권의 책이라는 결과도 중요하지만, 출근 퇴근할때 책을 읽으며 오늘도 좋은 습관을 통해 의미있는 시간을 보냈다는 생각에 그 날 하루에 대해 만족스러움을 느끼며 자존감도 올라간다.&lt;/p&gt;
&lt;p&gt;‘출퇴근할때 책을 읽는다’라는 습관 하나만으로도 10년이면 이렇게 큰 차이가 나는데, 다른 좋은 습관들이 더 모였을때 어떤 차이가 생길지 기대된다.&lt;/p&gt;
&lt;h2&gt;책 내용&lt;/h2&gt;
&lt;p&gt;저자는 이러한 습관의 중요성에 대해 강조하면서 습관을 어떻게 하면 더 쉽게 들일 수 있는지에 대해 서술한다.&lt;/p&gt;
&lt;p&gt;기억나는 하나를 꼽자면, ‘나는 담배를 끊는 중이야’라고 생각하는 것보다, ‘나는 담배를 안 피는 사람이야’와 같이 ‘나는 ~한 사람이다’라고 생각하면 더 쉽게 습관을 바꿀 수 있다고 저자는 말한다. 이는 습관을 단순한 행동의 변화로 보는 것이 아니라, 자아 정체성의 변화로 보는 관점이다. 우리가 자신을 어떻게 정의하느냐에 따라 우리의 행동이 크게 달라진다는 것이다.&lt;/p&gt;
&lt;p&gt;예를 들어, ‘나는 운동을 하는 사람이다’, ‘나는 건강한 음식을 먹는 사람이다’와 같은 생각을 가지면, 자연스럽게 운동을 하고 건강한 식습관을 유지하는 행동으로 이어진다. 저자는 이러한 정체성 기반의 습관 형성을 통해 장기적이고 지속 가능한 변화를 이룰 수 있다고 강조한다.&lt;/p&gt;
&lt;p&gt;이 책은 단순히 좋은 습관을 들이는 방법을 넘어서, 왜 우리가 습관을 유지하거나 바꾸기 어려운지에 대한 심리학적, 신경학적 논문 결과 등을 제시한다는 점에서 더 신뢰가 갔다. 신년인 만큼 이 책을 읽으며 ‘Atomic Habits’ 프로젝트 해보는걸 추천한다!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[팀장의 관점]]></title><description><![CDATA[팀장의 관점 김규철님이 쓰신 ‘팀장의 관점’이라는 책을 읽었다. 현재 회사에서 AI…]]></description><link>https://sooftware.github.io/leaders_perspective/</link><guid isPermaLink="false">https://sooftware.github.io/leaders_perspective/</guid><pubDate>Sat, 06 Jan 2024 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;팀장의 관점&lt;/h1&gt;
&lt;p&gt;김규철님이 쓰신 ‘팀장의 관점’이라는 책을 읽었다. 현재 회사에서 AI팀의 리더로써 있는만큼 리더의 무게를 점점 더 느끼고 있다. ‘나는 좋은 리더인가?‘라는 생각을 해보면 아직 부족하다고 느껴지는 부분이 너무 많기에, 어떤 부분을 개선할 수 있을지에 대해 도움을 받고자 읽어봤다.&lt;/p&gt;
&lt;p&gt;이 책에서는 리더라면 실무자와 다르게 나무가 아닌 ‘숲’을 보는 눈(Bird eye view)이 있어야 한다고 강조한다. 지난 시간들을 되돌아봤을때 내가 bird eye view로 바라보며 팀원들을 이끌어줬는가에 대해 회고해보며 많은 부분을 반성하게 됐다.&lt;/p&gt;
&lt;p&gt;사실 책에 있는 내용 자체는 이론적으로야 알고있는 부분이였지만, 그 부분에 대해 다시 한 번 읽고 생각해보며 내가 앞으로 리더로써 어떻게 해야하고, 어떤 부분을 보완해야하는지에 대해 생각해보게 해준 책이였다.&lt;/p&gt;
&lt;p&gt;학생일때나 신입 엔지니어였을때는 개발자는 코딩 잘하는게 최고라고 생각했지만, 시간이 지날수록 리더십의 중요함에 대해 체감하고 있다. 본인이 리더를 꿈꾼다면 실무적인 능력은 물론이고 버드아이뷰, 멘탈, 사람들을 이끄는 능력 등 더 많은 능력을 키워야하는데, 어떤 부분을 키워야할지에 대해 생각해볼 수 있게 해주는 책이다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[LLM Paper Abstract - 2023.12]]></title><description><![CDATA[LLM Paper Abstract - 2023.12 LLM…]]></description><link>https://sooftware.github.io/llm-abs-202312/</link><guid isPermaLink="false">https://sooftware.github.io/llm-abs-202312/</guid><pubDate>Fri, 05 Jan 2024 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;LLM Paper Abstract - 2023.12&lt;/h1&gt;
&lt;p&gt;LLM 관련해서 워낙 많은 논문들이 나와서, 최근에 읽은 논문들에 대해 간단하게 요약한 리스트입니다.&lt;br&gt;
아래 리스트중에는 가볍게 읽어본 논문들이 포함되어 있어서 요약에 틀린 내용이 있을 수 있습니다.&lt;/p&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;h3&gt;12월 4주차&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2312.15166&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;SOLAR 10.7B: Scaling Large Language Models with Simple yet Effective Depth Up-Scaling&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : Solar를 어떻게 만들었는지에 대한 논문. Depth up-scaling (DUS) 이라고 명명한 기술을 활용했다고 함. 2개의 모델을 처음 세트의 끝과 두번째 세트의 첫 레이어 부분들을 일정 부분 떼어내고 합쳐서 활용했다고 함.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;12월 3주차&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://huggingface.co/blog/moe&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Mixture of Experts Explained&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : Mixture of Experts (MoE)에 대해 자세히 설명한 글.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;12월 2주차&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2309.06180&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Efficient Memory Management for Large Language Model Serving with PagedAttention&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : &lt;a href=&quot;https://github.com/vllm-project/vllm&quot;&gt;vLLM&lt;/a&gt; 에 사용된 PagedAttention에 대한 논문. OS에서 쓰는 Paging 기법을 참고하여 적용함. 현재 State-Of-The-Art인 FasterTransformer, ORCA와 걑은 수준이라고 함.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://mistral.ai/news/mixtral-of-experts/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Mixtral of experts&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : Mistral 팀에서 sparse Mixture of Experts model (SMoE) 방법으로 내놓은 모델. GPT-4처럼 7B짜리 모델 8개로 구성되어 있음. Feed-forward network가 8개의 그룹 중 하나를 선택해서 추론하며, 총 46.7B 사이즈지만, 실제로 토큰당 사용되는 파라미터는 12.9B이라고 함. 몇 벤치마크서 LLaMA2 70B을 이겼다고..&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2312.06585&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Beyond Human Data: Scaling Self-Training for Problem-Solving with Language Models&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 리워드를 줄 수 있는 태스크에 대해서 RL/Self training을 하는 것으로 성능을 개선하는 방법에 대한 논문.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2312.00752&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Mamba: Linear-Time Sequence Modeling with Selective State Spaces&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 트랜스포머 아키텍처의 한계점, 그리고 이를 해결하기 위해 나왔던 수많은 아키텍처의 한계점을 개선하고자 나온 논문. Mamba 3B가 트랜스포머 3B 대비 우수한 성능을 보인다고 함.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;12월 1주차&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://storage.googleapis.com/deepmind-media/gemini/gemini_1_report.pdf&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Gemini: A Family of Highly Capable Multimodal Models&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 구글 &amp;#x26; 딥마인드에서 공개한 &lt;strong&gt;Gemini&lt;/strong&gt; 테크니컬 리포트. MMLU 벤치마크에서 32개 중 30개의 SOTA를 달성했으며, GPT-4를 능가했다고 함. 멀티모달 모델이여서 텍스트, 음성, 이미지, 비디오 모두 입력 가능한 형태..&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://storage.googleapis.com/deepmind-media/AlphaCode2/AlphaCode2_Tech_Report.pdf&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;AlphaCode 2 Technical Report&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : AlphaCode 2 테크니컬 리포트. 12.07 공개된 Gemini를 이용한 Code Generation 모델. 85%의 참가자들보다 더 나은 실력을 보여줬다고..&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2311.09198&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Never Lost in the Middle: Improving Large Language Models via Attention Strengthening Question Answering&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : ‘Lost in the Middle’ 현상을 완화하기 위한 방법을 제시한 논문.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2307.03172&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Lost in the Middle: How Language Models Use Long Contexts&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : QA와 같이 long context가 주어지는 태스크에서 관련 정보가 context의 앞쪽이나 뒤쪽에 있을때는 성능이 좋은데, ‘middle’에 있을 때 유독 성능이 떨어지는 현상을 관찰하고 분석한 논문. 이러한 현상을 ‘Lost in the Middle’이라고 표현&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.anthropic.com/index/claude-2-1-prompting&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Long context prompting for Claude 2.1&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 긴 문맥에서 관련 내용을 찾아내 답변해야할 때, “Here is the most relevant sentence in the context:“를 그림과 같이 마지막에 추가했더니 성능이 27%에서 98%로 크게 올랐다고 함.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Throwback 2023]]></title><description><![CDATA[Throwback 2023 어느덧 2023년이 가고 2024년을 맞이하게 됐습니다. 2020년 회고 글을 작성하고, 매년 회고글을 작성하려고 마음을 먹었는데, 202…]]></description><link>https://sooftware.github.io/2023/</link><guid isPermaLink="false">https://sooftware.github.io/2023/</guid><pubDate>Mon, 01 Jan 2024 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Throwback 2023&lt;/h1&gt;
&lt;p&gt;어느덧 2023년이 가고 2024년을 맞이하게 됐습니다. &lt;a href=&quot;https://sooftware.github.io/2020/&quot;&gt;2020년 회고 글&lt;/a&gt;을 작성하고, 매년 회고글을 작성하려고 마음을 먹었는데, &lt;a href=&quot;https://sooftware.github.io/2021/&quot;&gt;2021년 회고 글&lt;/a&gt;까지만 작성하고 작년에는 회고글을 작성하지 못했습니다. 😅 작년에는 ‘작성해야지.. 작성해야지..’ 하다가 시기를 놓쳐서 회고글을 작성하지 못했네요. 올해부터 다시 작성해보려고 합니다.&lt;/p&gt;
&lt;h2&gt;# ChatGPT의 등장&lt;/h2&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/051327e5-f17b-4a9e-a72b-d1b33dc125e4&quot; height=&quot;100&quot;&gt;
&lt;p&gt;작년 12월, ChatGPT가 세상에 공개되었고, 저희 같은 자연어처리 업계 뿐만 아니라 세계적으로 큰 임팩트를 남겼습니다. 전세계 사람들에게 AI에게 기대하는 기대치를 몇 단계는 높여주는 계기가 되었다고 생각합니다.&lt;/p&gt;
&lt;img alt=&quot;image&quot; src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/92f287fb-a8a7-43d8-b44a-8e41a4f3d133&quot; height=&quot;150&quot;&gt;
&lt;p&gt;영어는 말할것도 없고, 한국어 능력마저도 당시 그 어떤 한국어 모델들보다 뛰어난 성능을 보여줘서, 저도 처음에 써보면서 큰 벽을 만난 느낌이였습니다.&lt;/p&gt;
&lt;p&gt;ChatGPT의 파급력은 제 예상보다도 훨씬 커져서 출시 두달만에 MAU 1억 돌파라는 미친 기록을 써내려가기 시작했습니다. OpenAI는 API까지 공개하며 전세계적으로 ChatGPT 기반의 많은 서비스들이 등장하게 됐습니다. 이만큼 ChatGPT가 주는 충격은 AI 업계뿐만 아니라, 일반 대중들에게도 퍼지며 전세계 LLM(Large-scaled Language Model) 시장이 요동치게 됐습니다.&lt;/p&gt;
&lt;h3&gt;ChatGPT의 등장, 우린 뭘 해야 하는가&lt;/h3&gt;
&lt;img alt=&quot;image&quot; src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/845c1374-6504-4a51-abbd-9b5b99f016d5&quot; height=&quot;200&quot;&gt;
&lt;p&gt;많은 NLP 업계분들이 지난 1년간 이 생각을 많이 했을거라 생각됩니다. ChatGPT라는 게임체인저의 등장으로 이 상황에서 대기업 / 스타트업 할거 없이 ‘우리는 뭘 해야 하는가?‘라는 생각을 끊임없이 하게 만들었던 한 해라고 생각합니다.&lt;/p&gt;
&lt;p&gt;챗봇이라는 플랫폼 안에서 ChatGPT가 주지 못하는 경험을 사용자들에게 줘야하는데 어떤 경험을 제공해야 될지, 그 경험은 어떻게 제공할 수 있을지에 대해 많은 고민을 하게 됐습니다.&lt;/p&gt;
&lt;h3&gt;위기는 기회다&lt;/h3&gt;
&lt;img alt=&quot;image&quot; src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/895229f6-9396-44c8-bb5a-2f86201ddc7a&quot; height=&quot;200&quot;&gt;
&lt;p&gt;‘위기는 기회다’라는 말이 딱 적절한 상황이였다고 생각합니다. ChatGPT라는 게임체인저의 등장으로 많은 고민을 떠안게 됐지만, 이제 누구나 언어모델에 대해 얘기하면 이해할 수 있는 세상이 됐고, 관련 시장이 열리고 커졌습니다.&lt;/p&gt;
&lt;p&gt;또한, ChatGPT, GPT-4의 등장으로 Meta, Mistral AI 등 여러 기업 / 오픈소스 단체에서 수십 Billion 단위의 모델들까지 공개하기 시작했고, 기술 성장 속도에 불이 붙었습니다. 🔥🔥 저희도 이런 기술 성장에 힘입어 저희 자체 언어모델인 &lt;strong&gt;Cheetah&lt;/strong&gt;의 성능을 많이 개선했습니다. 2023년을 돌이켜보면 ChatGPT의 등장이 있었기 때문에 저희 서비스도 질적 개선이 가능했던 것 같습니다.&lt;/p&gt;
&lt;h2&gt;# Dearmate, 목표에 한 걸음 더&lt;/h2&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/63ca4bd4-8056-4ce3-9a92-524c16dcaabd&quot; height=&quot;320&quot;&gt;
&lt;p&gt;튜닙 창업 당시, AI 페르소나 챗봇 수십, 수백, 수천개를 찍어내고 “AI와 사람들이 같이 뒤노는 세상”이라는 비전을 가지고 시작했습니다. 2022년까지만 하더라도 저희는 ‘코코’, ‘마스’, ‘Bloony’ 이 3가지 챗봇만 있었고, 챗봇들의 대화 수준도 많이 아쉬웠습니다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/1a186b9c-a40d-409a-928d-f030296681c0&quot;&gt;
&lt;p&gt;2023년 들어서는, ‘어떻게 AI 챗봇을 공장처럼 팍팍 찍어낼 수 있을까?‘라는 주제로 많은 고민을 했습니다. 회사에서 밤늦게까지 머리를 맞대고 고민하기를 몇달째였는데, 어느 순간부터 점차 성과가 나오기 시작했고, 그 결과로 지금의 &lt;a href=&quot;https://dearmate.ai/&quot;&gt;Dearmate&lt;/a&gt; 서비스가 세상에 나올 수 있었습니다!&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/599939c1-5528-4108-8825-93c9e127692b&quot;&gt;
&lt;p&gt;Dearmate에는 현재 100여종이 넘는 AI 챗봇들과 일상을 공유하고, 댓글, DM 등을 통해 소통할 수 있습니다. 부산에 대해 소개해주는 부산 토박이 ‘부산갈매기’, 특정 주제에 대해 토론이 가능한 ‘민초송이’, N행시를 지어주는 ‘N군’ 등 각자 케릭터들의 고유한 성격과 세계관이 반영되어 있고, 이런 케릭터들이 포스트를 통해 일상을 공유하고 댓글과 DM으로 자유롭게 소통이 가능합니다!&lt;/p&gt;
&lt;p&gt;저희 AI팀은 지금도 대화 성능 개선을 위해서 매주 여러 실험을 진행하고 있으며 지금도 점차 성능이 개선되고 있습니다. 2023년도에 이룬 저희 팀의 기술적 성장은 창업 이후 그 어떤 때보다 많은 기술 성장을 이뤘다고 자부합니다. 😎&lt;/p&gt;
&lt;p&gt;2024년도에는 2023년도에 이룬 기술 성장보다 더 큰 개선이 있을거라는 확신이 들어서 2024년이 더더욱 기대가 되고, 이런 기술적 성장이 저희 튜닙에게 어떤 결과로 다가오게 될지 가슴이 뜁니다. 🔥🔥&lt;/p&gt;
&lt;h2&gt;# COVID-19 endemic&lt;/h2&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/9eced2cb-59e8-44fc-82d9-c45e8ed08694&quot; height=&quot;300&quot;&gt;
&lt;p&gt;코로나가 유행하고 3년만인 올해, 코로나 엔데믹을 선언했습니다. 코로나로 인해 정말 많은 부분이 일상에서 달라졌었는데요, 모든 사람들이 마스크를 쓰고 다니고, 재택근무가 성행하고 5인이상은 식당 같은 테이블에 앉을 수 없는 등 전에는 상상도 못할만한 일들이 일상에 자리 잡았었습니다.&lt;/p&gt;
&lt;img alt=&quot;image&quot; src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/5b63cd54-794c-4cbe-8d7a-2e3708f92d53&quot; height=&quot;150&quot;&gt;
&lt;p&gt;올해 코로나 엔데믹이 선언되면서, 다시 예전 일상을 점점 되찾아갔습니다. 저는 처음 직장에 들어갔을 때부터 코로나로 인해 재택근무로 시작하게 되면서 대면 근무보다는 재택근무가 익숙했습니다. 위 사진처럼 Gather Town이라는 서비스를 이용하며 재택근무 형태로 근무했고, 어쩌다 한 번씩 대면근무를 했을뿐 아예 대면근무로 전환이 돼서 근무한적은 없었는데, 코로나 엔데믹이 선언되면서 저희 튜닙도 근무 형태가 조금 달라지게 됐습니다.&lt;/p&gt;
&lt;img alt=&quot;image&quot; src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/73ebe070-4f10-4da7-98f3-cc648536e350&quot; height=&quot;230&quot;&gt;
&lt;p&gt;일주일에 3일은 출근하고, 2일은 재택근무를 하게 됐습니다. 이로 인해 제 라이프 사이클에도 많은 변화가 생겼습니다. 일주일에 3일은 하루 2시간 정도를 버스에서 보내게 됐고, 주로 업무하는 장소도 제 책상이 아닌 회사 사무실로 바뀌게 됐습니다. 그리고 노트북 화면으로만 보던 회사 사람들과도 직접 마주 앉아서 업무를 진행하게 됐습니다.&lt;/p&gt;
&lt;p&gt;처음에는 달라진 근무 형태가 익숙하지 않았지만, 지금은 출근 형태 근무에 익숙해져서 기존 풀 재택근무보다 더 만족하고 있습니다. 회사 사람들과도 더 친해지고, 의사소통면에서의 장점도 느끼고 있습니다. 2일은 재택근무를 하며 혼자서 해야하는 업무에 집중할 수도 있어서 여태 시행했던 근무형태 중 밸런스가 가장 좋다고 느끼며 크게 만족하고 있습니다!&lt;/p&gt;
&lt;h2&gt;# 3대 400 달성!&lt;/h2&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/b16dc0ee-be84-4af5-a7d0-316be6ed7243&quot;&gt;
&lt;p&gt;대학생때 하루하루 굉장히 상쾌하고, 힘이 넘치면서 몸이 가벼웠는데 졸업 이후 어느 순간부터는 그런 느낌을 통 느끼지를 못했습니다. 2021년부터 다시 운동을 본격적으로 시작하면서 점점 몸 컨디션을 끌어올렸는데, 올해 수행능력이 크게 좋아졌습니다!&lt;/p&gt;
&lt;p&gt;흔히 말하는 3대 운동(스쿼트, 데드리프트, 벤치프레스) 중량을 400KG을 달성했습니다! 🎉 💪&lt;/p&gt;
&lt;p&gt;2021년도랑 비교해서 몸무게는 약 10KG가 줄고, 근육량은 5KG 정도가 늘었습니다. 2021년도에 역대 최고 몸무게를 찍으면서 급격하게 살이 쪘었는데, 다시 예전 몸으로 복구 + 더 건강해져서 기쁩니다.&lt;/p&gt;
&lt;p&gt;21살 군입대때부터 운동을 시작해서 어느새 운동을 한지 꽤 됐었는데, 제 운동 수행능력 수준이 어느 정도인지가 항상 의문이였습니다. 3대 중량을 체크하기 시작하면서 객관적인 제 신체의 수행 능력을 알게됐고, 제 수행능력이 좋아지고 있는지, 퇴보하고 있는지 체크할 수 있는 중요한 척도가 됐습니다.&lt;/p&gt;
&lt;p&gt;그리고 무엇보다 신체능력이 좋아지면서 대학생때 느꼈던 몸이 가볍고 힘이 넘치는 느낌을 매일 받고 있습니다. 퇴근하고 헬스장에 가서 운동하고 나오면 스트레스도 풀리고, 하루를 보람차게 보냈다는 생각에 더 시너지가 생기는 것 같습니다.&lt;/p&gt;
&lt;p&gt;2024년에는 지방을 5KG 정도 빼고, 현재 수행능력을 유지하는게 목표입니다. 💪💪&lt;/p&gt;
&lt;h2&gt;# Atomic Habits Project&lt;/h2&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/09f40be0-9826-40ed-a35e-8940716939e7&quot; height=&quot;400&quot;&gt;
&lt;p&gt;최근 ‘좋은 습관 들이기’ + ‘나쁜 습관 없애기’ 프로젝트를 진행하고 있습니다.&lt;/p&gt;
&lt;p&gt;언제 일어나고, 일어나서 뭘 먹는지, 자기 전에는 어떤 행동을 하는지 등.. 한 사람은 정말 많은 습관들을 가지고 있습니다. 최근 습관의 중요성에 대해 느끼며 하루라도 젊었을때 좋은 습관들을 들여놔야지 복리처럼 저에게 큰 눈덩이로 불어난 좋은 결과들이 올거란 생각이 들었습니다. 그래서 제가 가지고 있는 안 좋은 습관들은 하나하나 없애고, 좋은 습관들을 하나씩 추가해보고 있습니다.&lt;/p&gt;
&lt;p&gt;2023년도에 가장 뿌듯한 결과는 아까웠던 하루 2시간 출퇴근 시간에 책 읽는 습관을 들였다는것, 그리고 시간이 나면 PC방 가던 버릇을 없애고 게임을 아예 끊었다는 것 입니다.&lt;/p&gt;
&lt;p&gt;출퇴근 시간에는 버스에서 유튜브를 보거나 노래를 들으며 잠을 청했었는데, 하루하루 시간이 쌓이며 이 시간이 너무 아깝다는 생각이 들었습니다. 꼭 출퇴근이 아니더라도 약속을 위해 버스나 지하철을 타는 시간이 많아서 이 시간을 잘 활용해보고 싶었는데, 이 시간에 책을 읽으며 올해에 꽤 많은 책을 읽었습니다.&lt;/p&gt;
&lt;p&gt;그리고 시간이 나면 PC방에 가서 축구게임을 즐기곤 했는데, 이 중독성이 생각보다 강해서 시간만 나면 PC방을 가고싶다는 생각이 들었습니다. 이대로는 안되겠다 싶어서 눈 딱 감고 제가 보유했던 비싼 선수들을 모두 방출해버렸습니다. 😇 제 구단 가치가 꽤 됐었기 때문에 아까웠지만, 게임 돈을 아까워할게 아니라 앞으로의 시간을 아까워해야할것 같아서 지금은 당시 결단내린것이 뿌듯합니다. 신기하게도 좋은 선수들을 다 방출해버리니 그 뒤로는 게임을 하고 싶은 마음이 들지 않더군요. 🤣&lt;/p&gt;
&lt;h2&gt;# Journey &amp;#x26; Hobby&lt;/h2&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/b86ece4b-1126-4397-ba2e-702ea00fcaa3&quot; height=&quot;300&quot;&gt;
&lt;p&gt;2022년도에는 필리핀 세부로 해외 여행을 다녀왔지만, 2023년도에는 해외여행은 다녀오지 못했습니다. 🥲&lt;/p&gt;
&lt;p&gt;그래도 시간을 내서 여자친구와 국내 여행 몇 곳을 다녀왔습니다. 올해 가장 기억에 남는 곳은 ‘울릉도’입니다! 여름에 국내여행을 어디를 갈까..하다가 국내에 특별한 곳을 다녀오고 싶어서 울릉도를 다녀왔는데, 저랑 여자친구 모두 국내 여행지 중 가장 만족하며 여행을 했습니다. 울릉도의 모든 풍경이 절경이였고, 울릉도 주민분들도 친절하셔서 여러 좋은 추억을 남겼습니다. 스노쿨링도 했는데, 여자친구는 오징어🦑 떼를 봤다는데, 저는 보지 못했습니다. 😭&lt;/p&gt;
&lt;p&gt;여행했을 당시에 태풍이 오는 중이여서 하루 일찍 섬에서 나오게 돼서 아쉬웠는데, 2025년도 공항 생기기 전에 한 번 다시 다녀올 생각입니다!&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/d6df2de7-0ada-4b2d-aaf9-cda0f48ee7a2&quot; height=&quot;280&quot;&gt;
&lt;p&gt;올해 쿠팡플레이의 초대로 아틀레티코 마드리드가 방한해서 K리그 올스타와 경기를 했습니다! ⚽️&lt;/p&gt;
&lt;p&gt;여자친구의 티켓팅 성공으로 같이 다녀올 수 있었는데, &lt;a href=&quot;https://namu.wiki/w/%EC%95%99%ED%88%AC%EC%95%88%20%EA%B7%B8%EB%A6%AC%EC%A6%88%EB%A7%8C&quot;&gt;앙투안 그리즈만&lt;/a&gt;이 뛰는 모습을 경기장에서 볼 수 있어서 너무 좋은 경험이였습니다. 그리고 한동안 안봤던 축구를 요즘 다시 보고 있습니다. 학생때는 좋아하는 선수 경기를 챙겨보곤 했는데, 바빠지면서부터는 통 챙겨보지를 않다가 최근에는 손흥민 선수가 뛰고 있는 토트넘을 응원하며 경기를 챙겨보고 있습니다. 현재 글을 작성하는 2024년 1/1일자에도 손흥민 선수가 본머스를 상대로 골을 기록하며 득점 2위로 올라섰는데, 손흥민 선수가 계속 활약해서 이번 시즌에 다시 한 번 EPL 득점왕을 하는 모습을 보고 싶습니다! 🔥&lt;/p&gt;
&lt;h2&gt;# 마치며..&lt;/h2&gt;
&lt;img alt=&quot;image&quot; src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/c949ba77-297b-4848-ade4-c8ae1d46c28e&quot; height=&quot;300&quot;&gt;
&lt;p&gt;2020년에 AI 엔지니어로 일을 시작하게 됐는데, 어느새 2024년이라는게 새삼 놀랍습니다. 26살이였던 저는 이제 30살이 됐고, 튜닙은 창업한지 3년이 됐습니다. 최근 경제가 불황이고, 스타트업 시장은 더더욱 힘들다는걸 체감하고 있습니다. 주위에서 들리는 안 좋은 소식들도 많고, 예정됐던 사업화지원금이 갑자기 큰 폭으로 축소되는 등 저희 역시 여러 상황이 바뀌고 있는걸 체감하고 있습니다.&lt;/p&gt;
&lt;p&gt;하지만 이런 위기속에서도 저희에게 나타나는 여러 지표 및 조짐들을 증거로 좋은 방향으로 나아가고 있다고 생각합니다. 2024년에는 이런 좋은 조짐들이 실제로 이뤄지는 2024년이길 바라며 저 개인적으로도 크게 성장하는 한 해가 됐으면 좋겠습니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[원씽 (THE ONE THING)]]></title><description><![CDATA[# 원씽 (THE ONE THING) 원씽(The One Thing)은 2013년에 나온 책이고, 아마존 베스트셀러…]]></description><link>https://sooftware.github.io/one-thing/</link><guid isPermaLink="false">https://sooftware.github.io/one-thing/</guid><pubDate>Tue, 26 Dec 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;# 원씽 (THE ONE THING)&lt;/h1&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/bebb1d79-3e43-401d-8240-74713ca8dc4f&quot; width=&quot;300&quot;&gt;
&lt;p&gt;원씽(The One Thing)은 2013년에 나온 책이고, 아마존 베스트셀러 1위 도장이 쾅! 찍혀있는 유명한 베스트셀러이다. 책 이름에서 유추할 수 있듯이, 중요한 ‘한 가지’에 집중하라는 말을 내내 강조한다. 책 제목만큼 단순한 디자인이였지만, 서점에서 지나가며 볼때마다 눈길을 끌어서 이번 기회에 읽어봤다.&lt;/p&gt;
&lt;h2&gt;# 원씽(The One Thing) 내용 요약&lt;/h2&gt;
&lt;p&gt;‘원씽’은 사람들에게 목표에 집중하고, 그 목표를 달성하기 위한 우선순위 1순위인 &lt;strong&gt;단 하나의 일&lt;/strong&gt;에 집중하라! 라는 메세지를 던진다. 그러기 위해 본인의 인생의 목표는 뭔지, 정말 이 목표를 달성했을때 본인이 행복한지에 대해 충분히 고민하고, 확신이 든다면 이 목표를 달성하기 위해 하나의 길로 열심히 달려나갈 것을 제안하고, 이를 위한 조언들을 제공한다.&lt;/p&gt;
&lt;p&gt;이러한 메세지를 위해 책에서는 총 3섹션으로 나누어서 서술하고 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;첫 번째 섹션 : 성공에 관한 여섯 가지 거짓말&lt;/li&gt;
&lt;li&gt;두 번째 섹션 : 나의 단 하나를 어떻게 찾을 것인가&lt;/li&gt;
&lt;li&gt;세 번째 섹션 : 단 하나를 위한 실행, 그리고 위대한 결과&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 3섹션 모두 흥미로웠다. 그 중 저자가 생각하는 성공에 대한 거짓말 6가지가 흥미로웠다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;모든 일이 다 중요하다&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;멀티태스킹은 곧 능력이다&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;성공은 철저한 자기관리에서 온다&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;의지만 있다면 못할 일은 없다&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;일과 삶에 균형이 필요하다&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;크게 벌이는 일은 위험하다&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;몇 가지는 소제목만 봐도 ‘꼭 그렇지는 않지’란 생각이 들며 저자의 의견에 동의했지만, 몇 가지는 ‘이건 맞는거 아닌가?‘라는 생각이 들었고, 이런 생각을 토대로 저자의 생각을 읽다보니 내가 생각 못한 부분에 대해 지혜로운 사람의 의견을 듣는 느낌이였다.&lt;/p&gt;
&lt;p&gt;두 번째 섹션과 세 번째 섹션에서는, ‘나의 원씽’을 어떻게 찾고, 이를 어떻게 실행할건지에 대해 서술된다. 읽으면서 ‘나의 원씽’은 뭘지, 이를 위해서 어떤 일을 해야하고, 어떤 계획을 세워야하고, 어떤 습관을 가지는게 좋을까? 와 같은 생각이 쭉 들었다.&lt;/p&gt;
&lt;h2&gt;# 나의 원씽&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;내가 원하는 인생 목표가 뭘까?&lt;/strong&gt;&lt;/em&gt; 에 대해 생각해보게 됐다.&lt;/p&gt;
&lt;p&gt;어렴풋이 머리로 그리고는 있지만, 이거를 문장으로 구체적으로 표현하기는 어려웠다. 책을 일고 내 인생 목표부터 정의를 명확히 해야겠다는 생각이 들었다. 책을 다 읽은 날, 혼자 동네 목욕탕에 가서 내가 그리는 미래에 대해 눈을 감고 쭉 상상해봤다. 그러려면 어떤게 필요한지, 어떤 단기 목표를 세워야할지에 대해 그려보며 아래와 같은 형태로 계획을 세워봤다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;## 내가 원하는 삶

1. ~~~
2. ~~~
3. ~~~
4. ~~~
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;- 내가 원하는 삶, 그리고 그걸 위한 One Thing
- 내가 원하는 삶을 이루기 위한 5년의 목표, 그걸 위한 One Thing
- 내가 원하는 삶을 이루기 위한 5년의 목표를 위한 1년의 목표, 그걸 위한 One Thing
...
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;구체적인 내용은 내 일기장에 썼고, 아직은 충분히 구체화되지는 않은 것 같아서 한 번씩 업데이트를 계속 하고 있다. 그리고 이번달 나의 ‘원씽’은 &lt;strong&gt;좋은 습관 들이기&lt;/strong&gt;였고, 앞으로 몇 달간은 좋은 습관 들이기와 나쁜 습관 없애기가 &lt;strong&gt;나의 원씽&lt;/strong&gt;이 될 예정이다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;일어나면 사과와 견과류, 단백질 음료를 먹는다.&lt;/li&gt;
&lt;li&gt;일어나면 이불을 개고 자기전까지는 들어가지 않는다.&lt;/li&gt;
&lt;li&gt;신발장을 정리하는 등 집을 깨끗하게 유지하기 위한 노력을 한다.&lt;/li&gt;
&lt;li&gt;출퇴근하는 버스에서 책을 읽는다.&lt;/li&gt;
&lt;li&gt;점심시간에 잠깐이라도 햇빛을 보며 산책을 한다.&lt;/li&gt;
&lt;li&gt;일주일에 4일 이상 운동을 한다.&lt;/li&gt;
&lt;li&gt;일기를 다시 꾸준히 쓴다.&lt;/li&gt;
&lt;li&gt;블로그 포스팅을 꾸준히 한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;지금 12월이 다 끝나가는데, 다행히 위에 목표로한 습관들을 유지하고 있다. 행동이 습관으로 자리잡는데는 66일이 걸린다고 한다. 이제 한 달 정도 됐으니 조금 더 노력해서 이 습관들을 자리잡게하고, 내년에는 더 많은 좋은 습관과 더 적은 나쁜 습관을 가질 수 있도록 해보려고 한다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[What is MoE? (Mixture of Experts)]]></title><description><![CDATA[What it MoE? (Mixture of Experts) 현존 최강 LLM인 GPT-4에서 “MoE (Mixture of Experts)” 방식을 채택하여 사용하고 있다고 알려졌는데요, 최근 AI계의 뜨거운 감자 Mistral AI…]]></description><link>https://sooftware.github.io/moe/</link><guid isPermaLink="false">https://sooftware.github.io/moe/</guid><pubDate>Fri, 22 Dec 2023 01:11:55 GMT</pubDate><content:encoded>&lt;h1&gt;What it MoE? (Mixture of Experts)&lt;/h1&gt;
&lt;p&gt;현존 최강 LLM인 GPT-4에서 “MoE (Mixture of Experts)” 방식을 채택하여 사용하고 있다고 알려졌는데요, 최근 AI계의 뜨거운 감자 Mistral AI에서 &lt;a href=&quot;https://huggingface.co/mistralai/Mistral-7B-v0.1&quot;&gt;Mistral-7B&lt;/a&gt;라는 좋은 성능의 모델을 오픈소스로 공개한지 몇 달이 채 되지 않았는데 몇일 전, Mixtral이라는 46.7B 모델을 오픈소스로 공개했습니다!&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/40a24753-386e-4271-bf4b-eb7ab90e8dbe&quot; height=&quot;140&quot;&gt;
&lt;p&gt;모델 사이즈도 사이즈지만, Mixtral이 “MoE” 방식을 채택해서 사용했으며, LLaMA-2 70B를 상회하는 성능을 보여서 더욱 주목을 받고 있습니다. (Inference 속도는 6배나 빠르다고 합니다 🫢)&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/cafd232f-c846-4502-b185-3db1ad06d21a&quot; height=&quot;270&quot;&gt;
&lt;p&gt;Mixtral은 총 46.7B개의 파라미터 사이즈를 가지고 있찌만, 실제 인퍼런스할때는 12.9B의 추론 속도를 보여준다고 하는데요, 이게 어떻게 가능한 걸까요? 🤔&lt;/p&gt;
&lt;p&gt;이를 이해하기 위해서는 “MoE” 개념을 이해해야 합니다!&lt;/p&gt;
&lt;h2&gt;MoE (Mixture of Experts)&lt;/h2&gt;
&lt;p&gt;모델 파라미터 수가 많을수록, 모델 성능이 올라간다는 것은 이미 여러 연구를 통해 Scaling-Law가 입증되었습니다. 그래서 모델의 성능을 파악할때 파라미터 수는 가장 중요한 요소중 하나입니다. 하지만 모두가 OpenAI, Google, Meta 같은 빅테크 기업들처럼 컴퓨팅 자원을 자유롭게 사용할수는 없기에, 현실적으로 제한된 컴퓨팅 자원으로 모델 학습/서빙을 해야합니다.&lt;/p&gt;
&lt;p&gt;모델 사이즈가 커질수록 학습/서빙 비용은 늘어날 수 밖에 없는데, MoE는 학습/서빙 비용은 유지하면서도 모델 사이즈를 키울 수 있는 방법입니다!&lt;/p&gt;
&lt;p&gt;그럼 이제 본격적으로 MoE에 대해 살펴보겠습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sparse MoE Layers&lt;/strong&gt; : 기존 트랜스포머의 feed-forward network (FFN) 레이어를 N개의 &lt;code class=&quot;language-text&quot;&gt;expert&lt;/code&gt;로 나눠서 사용하는 개념입니다. 이 &lt;code class=&quot;language-text&quot;&gt;expert&lt;/code&gt;는 FFN이지만, 특정 &lt;strong&gt;토큰&lt;/strong&gt;들을 담당한다고 생각하면 됩니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Gate Network (Router)&lt;/strong&gt; : 각 토큰이 어떤 &lt;code class=&quot;language-text&quot;&gt;expert&lt;/code&gt;에 소속되는지를 결정하는 network.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/72ea18a1-d0b9-4d06-ace7-78c013658136&quot; height=&quot;350&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2101.03961&quot;&gt;Switch Transformer&lt;/a&gt;에 아주 좋은 예씨 Figure가 있어서 가져왔습니다. 위 그림처럼 Transformer Block은 Attention -&gt; Add + Norm -&gt; FFN -&gt; Add + Norm과 같은 형태로 이루어져 있습니다. (순서는 아키텍처마다 다를 수 있습니다만 여기서는 넘어가겠습니다.) 여기서 MoE는 &lt;strong&gt;FFN&lt;/strong&gt;에 해당하는 layer를 기존과 다르게 사용하는데요, 그림에서처럼 “More”라는 토큰 하나가 들어왔을 때, 이 토큰을 Gate Network (Router)를 거쳐서 N번째 &lt;code class=&quot;language-text&quot;&gt;expert&lt;/code&gt;에 할당되면, 해당 토큰은 다른 &lt;code class=&quot;language-text&quot;&gt;experts&lt;/code&gt;은 제외한 할당된 &lt;code class=&quot;language-text&quot;&gt;expert&lt;/code&gt;에 해당하는 FFN을 통과하게 됩니다. (밑에서 살펴보겠지만, 위 예시에서는 1개의 &lt;code class=&quot;language-text&quot;&gt;expert&lt;/code&gt;만을 할당받았지만, 실제로는 2개 이상의 &lt;code class=&quot;language-text&quot;&gt;expert&lt;/code&gt;도 보낼 수 있습니다. 😎)&lt;/p&gt;
&lt;h3&gt;Sparsity&lt;/h3&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/d207e623-2e89-4791-a7b3-55d6da7c2bfa&quot; height=&quot;140&quot;&gt;
&lt;p&gt;여기서 &lt;strong&gt;Sparsity&lt;/strong&gt;에 대해 보고 넘어가겠습니다. 일반적인 트랜스포머 모델은 dense한 모델입니다. (모든 입력에 대해 모든 입력이 사용되는 모델) 반면에 Sparsity한 모델이란, 모델 파라미터의 일부만 사용할 수 있는 모델을 의미합니다. 즉, 이 MoE 아키텍처는 Sparsity하다고 할 수 있겠죠!&lt;/p&gt;
&lt;h3&gt;1개가 아닌 K개의 Expert에게 보내려면 어떻게 해야할까?&lt;/h3&gt;
&lt;p&gt;위에서 &lt;code class=&quot;language-text&quot;&gt;Expert&lt;/code&gt;를 2개 이상에 보낼수도 있다고 했습니다. Mixtral도 1개가 아닌 2개의 &lt;code class=&quot;language-text&quot;&gt;Expert&lt;/code&gt;에 보내는 방식으로 학습되었는데요, 어떻게 동작하는지 살펴보겠습니다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/e6c0e658-f46f-4b40-859c-2c9c13ca731a&quot; height=&quot;100&quot;&gt;
&lt;p&gt;총 8개의 &lt;code class=&quot;language-text&quot;&gt;Expert&lt;/code&gt;가 있고, 여기서 1개의 &lt;code class=&quot;language-text&quot;&gt;Expert&lt;/code&gt;로 보내는 문제를 먼저 보겠습니다. 굉장히 간단한 &lt;strong&gt;Classification&lt;/strong&gt; 문제죠. PyTorch 코드로 구현한다면 아래와 같겠네요.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nn &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; nn

&lt;span class=&quot;token comment&quot;&gt;# inputs는 dim 차원을 가진 tensor&lt;/span&gt;
dim&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; num_experts &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;512&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;
gate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Linear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dim&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; num_experts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
nth_expert &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; F&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;softmax&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gate&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;inputs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dim&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;argmax&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이렇게 위와 같이 Linear layer + Softmax 조합으로 간단하게 &lt;code class=&quot;language-text&quot;&gt;Expert&lt;/code&gt;를 특정할 수 있고, 해당 토큰은 특정된 &lt;code class=&quot;language-text&quot;&gt;Expert&lt;/code&gt;로 포워딩해주면 됩니다.&lt;/p&gt;
&lt;p&gt;그렇다면, 만약에 1개 이상의 K개의 &lt;code class=&quot;language-text&quot;&gt;Expert&lt;/code&gt;에게 gating을 해주고 싶다면 어떻게 해야할까요? 🤔&lt;/p&gt;
&lt;p&gt;여러 방법이 있겠지만, Mixtral에서 사용한 Top-k Gating 방식을 소개드리겠습니다. gate network의 linear layer를 H(x)라고 하고, K개의 &lt;code class=&quot;language-text&quot;&gt;Expert&lt;/code&gt;에게 보내고 싶다면, 아래와 같은 수식으로 표현할 수 있습니다.&lt;/p&gt;
&lt;img height=&quot;70&quot; alt=&quot;image&quot; src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/68702730-e153-4a7d-b39f-5eb7c6606f01&quot;&gt;
&lt;p&gt;(이해를 위해 K=2를 예시로 들겠습니다.) Linear layer의 결과로 나온 logits에 top 2개의 logits을 뽑고 이 2개의 logits에 대해서 Softmax 함수를 적용합니다. 그럼 이 2개의 expert에 대한 weight 값이 나오게 됩니다!&lt;/p&gt;
&lt;p&gt;A라는 Expert에게 0.7, B라는 Expert에게 0.3과 같은 식으로 말이죠. 이렇게 나온 weight를 A와 B Expert를 거쳐서 나온 결과값에 곱해서 사용하게 됩니다.&lt;/p&gt;
&lt;p&gt;아래는 실제 Mixtral에 사용된 MoE Layer의 구현 코드입니다. 해당 코드에 제가 위에 설명한 내용들에 대해 주석으로 달아놨으니 참고하면서 하나하나 이해해보시는걸 추천드립니다!&lt;/p&gt;
&lt;p&gt;(참고) MoE 구현체는 &lt;a href=&quot;https://github.com/mistralai/mistral-src/blob/main/mistral/moe.py&quot;&gt;이곳&lt;/a&gt;에서 확인 가능합니다. 그리 길지 않아서 코드를 바로 가져왔습니다.&lt;/p&gt;
&lt;h3&gt;MoE Implementation (by Mistral)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; dataclasses
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; typing &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; List

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;functional &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; F
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; simple_parsing&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;helpers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Serializable
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; torch &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; nn


&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@dataclasses&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataclass&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MoeArgs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Serializable&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    num_experts&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;
    num_experts_per_tok&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;


&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MoeLayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Module&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; experts&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; List&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Module&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; gate&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Module&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; moe_args&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; MoeArgs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__init__&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;experts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;experts &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ModuleList&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;experts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; gate
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;args &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; moe_args

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; inputs&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Tensor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# Step 1 : Expert로 보내기 위한 gate linear layer 통과&lt;/span&gt;
        gate_logits &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gate&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;inputs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# Step 2 : gate logits에 대해 Top-K개 Expert 뽑기&lt;/span&gt;
        weights&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; selected_experts &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;topk&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gate_logits&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;num_experts_per_tok&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# Step 3 : Top-K개의 experts에 대한 weights 구하기 (by softmax)&lt;/span&gt;
        weights &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; F&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;softmax&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;weights&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dim&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dtype&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;inputs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dtype&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        results &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros_like&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;inputs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;# N개의 experts 돌면서 순회&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; expert &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;experts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;# Step 4 : i_th expert에 해당하는 tokens 뽑기&lt;/span&gt;
            batch_idx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nth_expert &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;where&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;selected_experts &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;# Step 5 : i_th expert에 해당하는 token들 i_th expert에 통과&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;# Step 6 : 통과된 결과값에 expert weight 반영&lt;/span&gt;
            results&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;batch_idx&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; weights&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;batch_idx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nth_expert&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; expert&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
                inputs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;batch_idx&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; results&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;게이트가 여러 &lt;code class=&quot;language-text&quot;&gt;Expert&lt;/code&gt;에게 라우팅하는 방법을 학습하게 하기 위해서 이렇게 2개 이상의 &lt;code class=&quot;language-text&quot;&gt;Expert&lt;/code&gt;에게 보내도록 학습을 시켰다고 합니다.&lt;/p&gt;
&lt;p&gt;최근에 나온 여러 아키텍처들이 이 MoE 방식에 기반하여 만들어지고 있습니다! 그런만큼 MoE에 대한 이해가 중요한데, 이 포스팅이 도움이 됐으면 좋겠습니다!&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://mistral.ai/news/mixtral-of-experts/&quot;&gt;https://mistral.ai/news/mixtral-of-experts/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://huggingface.co/blog/moe&quot;&gt;https://huggingface.co/blog/moe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/mistralai/mistral-src&quot;&gt;https://github.com/mistralai/mistral-src&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[당신의 뇌는 최적화를 원한다]]></title><description><![CDATA[…]]></description><link>https://sooftware.github.io/brain-hormone/</link><guid isPermaLink="false">https://sooftware.github.io/brain-hormone/</guid><pubDate>Sun, 10 Dec 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;# 당신의 뇌는 최적화를 원한다&lt;/h1&gt;
&lt;img src=&quot;https://img1.daumcdn.net/thumb/R1280x0/?fname=http://t1.daumcdn.net/brunch/service/user/2h9I/image/1AZWCB5hx7M5T6I4QK70FF3yqDM.jpg&quot; width=&quot;300&quot;&gt;
&lt;p&gt;대학생때 시험전날 새벽에 공부하다가 더 이상 머리에 새로운 지식이 들어가지 않을때, 친구들과 밖에 나가서 산책 한 번 다녀오면 머리가 맑아지고 말료 표현하기 어려운 기분좋은 느낌을 느낀적이 몇 번 있다. 운동을 끝내고 시원한 밤 바람을 맞을때, 적당한 온도의 목욕탕에서 눈 감고 몸에 힘을 빼고 쉴때 등 원인은 모르겠지만 경험적으로 ‘이럴때 기분이 좋다’라는 데이터를 가지고 있다.&lt;/p&gt;
&lt;p&gt;‘오늘따라 머리가 잘 돌아간다’, ‘오늘따라 일이 잘 안 되네’와 같은 경험들이 다들 있을거다. 그래서 이러한 내 컨디션, 기분들이 왜 그런지 알 수만 있다면 나라는 사람을 더 효율적으로 활용할 수 있을거란 생각이 든 적이 있었다. 이번에 읽은 가바사와 시온이 쓴 ‘당신의 뇌는 최적화를 원한다’ 이 책이 이러한 부분에 대해서 과학적으로 여러 힌트를 줬다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;도파민 (의욕과 열정의 행복물질)&lt;/li&gt;
&lt;li&gt;노르아드레날린 (집중력과 기억력을 끌어올려야 할 때)&lt;/li&gt;
&lt;li&gt;아드레날린 (신체능력과 몰입 에너지가 필요할 때)&lt;/li&gt;
&lt;li&gt;세로토닌 (스트레스 줄이는 치유물질)&lt;/li&gt;
&lt;li&gt;멜라토닌 (완벽하게 재충전시켜주는 수면물질)&lt;/li&gt;
&lt;li&gt;아세틸콜린 (영감과 아이디어가 필요할 때)&lt;/li&gt;
&lt;li&gt;엔도르핀 (효율을 2배 높이는 뇌 내 마약)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 책에서는 7가지 ‘신경전달물질’에 대해 소개하면서, 이 ‘신경전달물질’이 우리 몸과 마음에 어떤 영향을 미치고, 이러한 특징을 어떻게 활용할 수 있는지를 알려준다.&lt;/p&gt;
&lt;p&gt;좋았던점은, ‘달걀덮밥과 두부 된장국이 영감을 준다’와 같이 너무 구체적으로 찝어서 예시를 들어준게 좋았다. 결국 이 책을 읽고 내가 얻어갈 수 있는건 내 뇌를 최적화하기 위해 좋은 습관들이 뭔지 알고 실천하는거일텐데, 저자가 구체적인 예시를 주니 ‘이런 습관을 가지면 좋겠다!’하고 바로 연계해서 생각할 수 있었다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;점심 시간에 꼭 햇빛받으며 산책하기&lt;/li&gt;
&lt;li&gt;역시나 꾸준한 운동이 뇌도 건강하게 만든다&lt;/li&gt;
&lt;li&gt;유튜브, 웹툰을 보는건 쉬는게 아니다. 눈 감고 몸에 힘을 빼고 명상을 해보자&lt;/li&gt;
&lt;li&gt;아침을 꼭 먹자. 씹어먹는걸로.&lt;/li&gt;
&lt;li&gt;시간대에 따라 잘할 수 있는 일이 다르다.
&lt;ul&gt;
&lt;li&gt;오전에는 결단력, 논리력이 필요한 일 (글쓰기, 복잡한 계산, 결단)&lt;/li&gt;
&lt;li&gt;오후, 밤에는 상상력, 창의적인 일&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이번에 책을 읽고 실천해보기로 한 리스트다. 더 많은 팁들이 나오지만, 당장 나에게 문제 없다고 생각되는 부분이나 실천하기 어려운 부분들에 대해서는 일단 미뤄뒀다. 이제 곧 2024년이 오는데 새해맞이로 좋은 습관을 만들고 싶은 사람들은 지금 딱 읽어보면 좋을 책이다. 추천한다!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Welcome to the Gemini Era]]></title><description><![CDATA[Welcome to the Gemini Era Google이 드디어 OpenAI에 대한 반격을 시작한걸까요? 구글이 ‘Gemini’라는 이름의 초거대 모델을 갑작스럽게 공개했습니다. MMLU 벤치마크에서 GPT-4를 넘으며, 32개 중 3…]]></description><link>https://sooftware.github.io/gemini/</link><guid isPermaLink="false">https://sooftware.github.io/gemini/</guid><pubDate>Thu, 07 Dec 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Welcome to the Gemini Era&lt;/h1&gt;
&lt;p&gt;Google이 드디어 OpenAI에 대한 반격을 시작한걸까요?&lt;/p&gt;
&lt;p&gt;구글이 ‘Gemini’라는 이름의 초거대 모델을 갑작스럽게 공개했습니다. MMLU 벤치마크에서 GPT-4를 넘으며, 32개 중 30개에서 SOTA를 달성했다고 하네요.&lt;/p&gt;
&lt;p&gt;그리고 멀티모달 모델이여서 텍스트뿐만 아니라 음성, 이미지, 비디오까지 입력이 가능한 형태라고 합니다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://storage.googleapis.com/deepmind-media/gemini/gemini_1_report.pdf&quot;&gt;Gemini의 테크니컬 리포트&lt;/a&gt; 를 보면 아래와 같은 이미지가 나옵니다.&lt;/p&gt;
&lt;img width=&quot;600&quot; alt=&quot;image&quot; src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/02b0c26f-5f05-46b8-a7aa-26bd6b7eb7ea&quot;&gt;
&lt;p&gt;단순 텍스트 뿐만 아니라, 이미지도 입력이 가능하다보니 위와 같은 형태의 프롬프트가 가능하네요. 이렇게 되면 OCR 같은 기술들이나 이미지 캡셔닝이 따로 필요하지 않을 것 같습니다.&lt;/p&gt;
&lt;p&gt;예견된 미래였지만, 텍스트든, 이미지든, 음성이든, 비디오든 AI의 입력 및 출력에 자유자재로 사용되는 세상이 생각보다도 역시나 더 빠르게 다가왔네요.&lt;/p&gt;
&lt;p&gt;또 Gemini를 이용해서 AlphaCode =&gt; AlphaCode2로 강화했다고 하는데, 무려 85%의 사람보다 코딩을 잘한다고 합니다. 이렇게 되면 AlphaCode2와 같은 코드 생성 AI를 활용 잘하는 사람 한 명의 생산성이 크게 늘어날테니 개발자들 일자리가 많이 줄어들 것 같네요.&lt;/p&gt;
&lt;p&gt;이제는 꼭 AI 쪽 개발자가 아니더라도 프롬프트 엔지니어링을 잘하는 개발자일수록 생산성이 늘어나고 경쟁력이 높아질 것 같습니다 :)&lt;/p&gt;</content:encoded></item><item><title><![CDATA[LLM Paper Abstract - 2023.11]]></title><description><![CDATA[LLM Paper Abstract - 2023.11 LLM…]]></description><link>https://sooftware.github.io/llm-abs-202311/</link><guid isPermaLink="false">https://sooftware.github.io/llm-abs-202311/</guid><pubDate>Tue, 05 Dec 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;LLM Paper Abstract - 2023.11&lt;/h1&gt;
&lt;p&gt;LLM 관련해서 워낙 많은 논문들이 나와서, 최근에 읽은 논문들에 대해 간단하게 요약한 리스트입니다.&lt;br&gt;
아래 리스트중에는 가볍게 읽어본 논문들이 포함되어 있어서 요약에 틀린 내용이 있을 수 있습니다.&lt;/p&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;h3&gt;11월 4주차&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2311.11045&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Orca 2: Teaching Small Language Models How to Reason&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 마이크로소프트에서 공개한 Orca-2 모델 관련 논문. 7B, 13B 모델의 reasoning 능력을 개선해보려는 시도와 결과에 대해 리포트 함.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2311.14904&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;LLM-ASSISTED CODE CLEANING FOR TRAINING ACCURATE CODE GENERATORS&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 코드 생성 AI를 학습시킬때, 리팩토링을 통해 코드 가독성을 높인 코드로 학습시키면 모델 성능이 크게 좋아진다는 논문.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2311.16989&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;ChatGPT’s One-year Anniversary: Are Open-Source Large Language Models Catching up?&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : ChatGPT 1주년 기념으로, 오픈소스 LLM들이 ChatGPT, GPT4들을 얼마나 따라잡았는지를 평가한 논문&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.nature.com/articles/s41586-023-06735-9&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Scaling deep learning for materials discovery&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : Google DeepMind 논문에서 신소재 검색을 위한 AI 모델 ‘GNoME’을 통해 38만개의 신소재를 발견했다는 논문. 그동안 인류가 발견했던 2만개와 비교하면 20배에 달하는 능력이라고..&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;11월 3주차&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2311.09277&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Contrastive Chain-of-Thought Prompting&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : CoT의 한계를 지적한 논문. CoT가 비록 논리적인 추론에 대해서 중요한 부분이긴 하지만, 프롬프트 작성 시에 잘못 작성 했을 시에 대해 피할 수 없고, 이에 따라 많은 오류를 발생시킴. 따라서 instruction에 대한 negative sample과 positive sample을 동시에 입력으로 넣어 contrastive한 방식으로 추론할 수 있는 기법을 만들어낸 논문.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;11월 2주차&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2311.09210&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Chain-of-Note: Enhancing Robustness in Retrieval-Augmented Language Models&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : Retrieval-augmented language models에서 정확한 정보를 retrieval해도 아직 부족한 점이 많다는 점에서 나온 논문. Chain-of-Noting(CoN)이라는 방식을 활용하여서 retrieval된 도큐먼트에 대한 순차적인 읽기를 생성해서 질문과의 연관성을 평가하여 최종 답변을 도출한다는 논문. RAG 분야 성능을 높이려고 노력한 논문.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2311.00871&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Pretraining Data Mixtures Enable Narrow Model Selection Capabilities in Transformer Models&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 추론 시 사전학습된 데이터의 distribution과 너무 차이가 나는 prediction은 잘 하지 못한다는 내용의 논문. 즉 in-context learning은 학습 데이터와 많이 차이 나지 않는 distribution 범위에서만 가능하다는 논문.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2306.15895&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Large Language Model as Attributed Training Data Generator: A Tale of Diversity and Bias&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : ChatGPT와 같은 LLM을 데이터 생성에 사용하는 법에 관련한 논문. 다양성과 편향에 대해서도 같이 다룸.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2311.02462&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Levels of AGI: Operationalizing Progress on the Path to AGI&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 구글, 딥마인드에서 AI 능력을 5단계로 구분하고 레벨을 매겨 AGI로 가는 길에 대해 제시한 논문. 내용 자체는 뻔한 내용. ChatGPT를 1단계로 설정.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2311.01906&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;SIMPLIFYING TRANSFORMER BLOCKS&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 트랜스포머 구조를 단순화하여 15%의 학습 속도 개선과 15%의 파라미터를 줄이는 방향으로 개선안을 제안한 논문.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2306.04563&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;ChatGPT is fun, but it is not funny! Humor is still challenging Large Language Models&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : ChatGPT의 Joke에 관련한 논문. ChatGPT가 Joke를 잘하는듯 보이지만, 사실 ChatGPT가 하는 대부분(90%)의 joke가 25개의 joke에 한정되어있다고 함.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2308.04948&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;EXTRAPOLATING LARGE LANGUAGE MODELS TO NON-ENGLISH BY ALIGNING LANGUAGES&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : LLaMA에서 non-english 능력을 이끌어내기 위한 방법에 대해 제시한 논문. 번역 태스크로 instruction 튜닝을 하는 등의 방법을 사용함.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2311.03285v2&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;S-LORA: SERVING THOUSANDS OF CONCURRENT LORA ADAPTERS&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : LoRA Adapter가 여러개일 때 서빙하는 방법에 대한 논문.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2311.04205&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Rephrase and Respond: Let Large Language Models Ask Better Questions for Themselves&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : LLM에게 질문을 rephrase 시키고 답변시켰을 때 더 좋은 결과가 있었다는 논문.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;11월 1주차&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2309.00071&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;YaRN: Efficient Context Window Extension of Large Language Models&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : YaRN(Yet another RoPE extensioN method)이라는 Rotary Embedding을 개선한 버전을 제안한 논문. 기존 pre-training시 사용한 max length보다 더 길게 확장할 수 있음을 보임 (LLaMA를 128k 토큰까지 확장)&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Self Branding]]></title><description><![CDATA[Self Branding…]]></description><link>https://sooftware.github.io/self-branding/</link><guid isPermaLink="false">https://sooftware.github.io/self-branding/</guid><pubDate>Sat, 25 Nov 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Self Branding&lt;/h1&gt;
&lt;p&gt;‘나라는 브랜드를 설계하라’라는 책을 읽었다. 이 책에 대한 리뷰 겸, 셀프 브랜딩에 대한 내 생각을 적어보려고 한다.&lt;/p&gt;
&lt;p&gt;최근 사회에서 과연 능력만으로 다른 사람과 차별을 둘 수 있는 사람이 얼마나 있을까? 압도적인 재능을 가지고 있거나 남들과 격이 다른 노력을 한 사람이라면 본인의 능력만으로도 충분히 좋은 커리어를 쌓아나갈 수 있겠지만, 그런 사람이 많지는 않을 것이다. 그리고 충분한 능력을 가졌다고 해도, 그걸 표현하지 못하는 사람들이 너무나 많다.&lt;/p&gt;
&lt;p&gt;나는 셀프 브랜딩에 큰 관심을 가진 1인이다. 그렇기 때문에 이런 블로그도 운영하고, 현재는 좀 뜸하지만 과거에 오픈소스 사이트인 깃허브 활동도 열심히 했다. 셀프 브랜딩에 대해 혼자서 고민도 많이 해보고, 이 고민의 결과를 실적(?)으로도 내봤다. 이런 내 경험을 공유해보려고 한다.&lt;/p&gt;
&lt;h2&gt;Sooftware&lt;/h2&gt;
&lt;p&gt;가끔 AI 업계 사람들을 만나면 꽤 자주 듣는 얘기가 있다. “오 sooftware님 반갑습니다!”, “수환님 깃허브 아이디가 기억에 잘 남는다” 등의 말들을 많이 듣는다. (심지어 깃허브에서는 외국인들에게도 아이디가 Awesome하다는 말을 꽤 듣는다! 😎)&lt;/p&gt;
&lt;p&gt;sooftware는 내가 인터넷 상에서 쓰는 닉네임이다. (블로그명, 오픈소스 커뮤니티 GitHub 아이디 등)&lt;/p&gt;
&lt;p&gt;내 이름인 Soohwan과 software를 합친 내가 만든 합성어다. 대학교 2학년때 공부 블로그를 운영해야겠다고 마음 먹고, 몇일동안 블로그 이름을 뭘로할지 고심한 끝에 🤔 나온 결과물이다. (지금까지 굉장히 만족하고 있다!)&lt;/p&gt;
&lt;p&gt;흔한 한국 사람들 아이디처럼 자기 이름 initial + 생년월일 조합으로 아이디를 만들고 싶지 않았고, 내 블로그 아이덴티티를 표현하는 독특한게 뭐가 있을지 고민해서 만들게 됐다. 지금와서 돌이켜보니 이 ‘sooftware’라는 독특한 닉네임에 내 블로그나 깃허브를 방문한 사람들에게는 내 블로그명/깃허브 아이디와 내 이름을 더 잘 기억하게 해주는 효과가 있었던 것 같다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/4de8ddff-676f-45cf-b845-f569c18aeadf&quot; height=&quot;200&quot;&gt;
&lt;p&gt;지금은 이 &lt;strong&gt;sooftware&lt;/strong&gt;라는 닉네임이 나에게는 큰 상징성을 가진 닉네임이 됐다. 구글에 김수환, Soohwan Kim을 검색하면 나와 관계없는 자료들만 나오지만, 구글에 sooftware를 치면 내 블로그와 깃허브 사이트 및 내가 작성한 여러 블로그 글과 내 사진까지 나온다. 인터넷 상에서 특정 키워드가 나를 가르킨다는 것만으로도 흥분되는 일이다. 이러한 이유로 나는 내 지인들에게도 블로그 혹은 깃허브 아이디 같은 경우는 기억에 잘 남고, 독특한 아이디를 고민해보는 것을 추천하곤 한다. IT 시대인만큼 내 ‘인터넷 이름’도 필요한 것 아닐까? 심지어 내 이름은 내가 태어나기 전에 결정되지만, ‘인터넷 이름’은 내가 결정할 수 있다.&lt;/p&gt;
&lt;h2&gt;KoSpeech&lt;/h2&gt;
&lt;p&gt;KoSpeech는 내 대학교 졸업 프로젝트였다. ‘한국어 음성 인식’을 주제로 한 오픈소스 프로젝트였는데, 이 프로젝트의 원래 이름은 ‘Korean-speech-recognition’이였다. 다소 심심한 이름이였는데, 오픈소스 프로젝트인만큼 깃허브에서 Star를 몇개받느냐가 이 프로젝트가 얼마나 성공적이였는지를 나타내주는 지표라고 생각했다. (깃허브에서는 스타가 많을수록 많은 개발자들의 관심을 받은거라고 보면 된다)&lt;/p&gt;
&lt;p&gt;하지만 당시에 겨우 8개 정도의 Star만 받고는 한참 정체되어 있었던 기억이 난다. 기능적으로 봤을때 나는 더 많은 스타를 받을 수 있다고 생각했고, 어떻게 하면 이 프로젝트를 더 알릴 수 있을까 고민한 끝에 프로젝트 설명란에 검색에 더 잘 걸릴 수 있도록 사용한 기술인 ‘PyTorch’와 음성인식 오픈소스쪽에서 많이 검색되는 키워드인 ‘End-to-End’를 추가해서 ‘Open-Source Toolkit for End-to-End Korean Automatic Speech Recognition leveraging PyTorch and Hydra.‘로 설명을 수정했다. 그리고 프로젝트명을 더 짧고 기억에 남으면서도 어떤 프로젝트인지는 표현이 되도록 ‘KoSpeech’라는 이름으로 변경했다. 그리고 유입된 개발자들을 놓치지 않기 위해 프로젝트 설명을 쓰는 README.md를 최대한 흥미를 끌도록 여러번 고치며 개선했다.&lt;/p&gt;
&lt;img height=&quot;80&quot; alt=&quot;image&quot; src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/5443d336-0164-4082-9b6e-1d5f17a2e722&quot;&gt;
&lt;p&gt;결과는 성공적이였다!&lt;/p&gt;
&lt;p&gt;🌟가 하나 둘 찍히기 시작했고, 졸업할때쯤에는 200개를 넘기며 한국어 음성인식 오픈소스 중에는 가장 많은 🌟를 기록했다. (심지어 네이버에서 공개한 음성인식 오픈소스보다 더 많았다!)&lt;/p&gt;
&lt;p&gt;그리고 이 프로젝트를 본 당시 선망하던 회사의 선망하던 팀인 카카오브레인 NLP 팀에서 인턴 제의를 했고, 내 커리어 시작을 순조롭게 할 수 있었으니, 굉장히 큰 기회를 만들어줬다고 볼 수 있다. 내가 당시에 ‘기능’에만 초점을 맞추고 개발에만 집중했다면, 어쩌면 이런 기회가 없을수도 있지 않았을까?&lt;/p&gt;
&lt;h2&gt;나라는 브랜드를 설계하라&lt;/h2&gt;
&lt;p&gt;앞에 설명한 내 경험처럼, 이 책에서는 실력도 중요하지만, ‘셀프 브랜딩’을 해야 현재 사회에서 살아남을 수 있고, 더 많은 기회를 얻을 수 있다고 주장한다.&lt;/p&gt;
&lt;p&gt;브랜드가 된 CEO(일론 머스크)와 브랜드가 되지 못한 CEO, 브랜드가 된 의사(오은영)와 브랜드가 되지 못한 의사 등, 브랜드가 된 사람은 더 많은 기회를 얻을 확률이 높다.&lt;/p&gt;
&lt;p&gt;셀프 브랜딩을 잘하기 위해서는 전략이 필요하고, 저자는 총 10가지 전략을 제시한다.&lt;/p&gt;
&lt;p&gt;혁신가, 리더, 이단아 등 10가지 유형의 대표적인 브랜딩 전략을 소개해주는데, 읽으면서 나는 어디에 가장 적합할까? 라는 생각을 하며 읽는 재미가 있었다. 결과적으로는 이 10가지 유형 대부분 맞는거 같은 부분도 있고, 아닌거 같은 부분도 있어서 딱 이거다! 싶은 유형은 찾지 못했다.&lt;/p&gt;
&lt;p&gt;하지만 이 책에서 중요한 부분은 이 10가지 유형보다도, 내 강점이 어디에 있는지를 내가 알아야하고, 브랜딩을 할 대상(취업하고 싶은 회사 등)이 원하는게 뭔지를 알아야 한다는 것, 때로는 관점을 바꿔서 전혀 상관없을 것 같던 일을 엮어서 어필할 수 있다는 점 등이 중요했던 포인트라고 생각한다.&lt;/p&gt;
&lt;h2&gt;앞으로 내 브랜드는 어떻게 설계해야할까?&lt;/h2&gt;
&lt;p&gt;책을 읽으면서 계속 생각이 들었던 질문이다. 나는 어떤 강점이 있고, 어떤 대상에게 브랜딩을 해야할지, 그리고 어떤 방법이 효율적일지, 나를 브랜딩했을때 얻을 수 있는 효과는 뭔지 등에 대해 생각해보게 됐다.&lt;/p&gt;
&lt;p&gt;아래는 객관적으로 생각해봤을 때 내가 어필할 수 있는 포인트들을 정리해봤다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;나는 20대의 젊은 나이의 창업가다.&lt;/li&gt;
&lt;li&gt;나는 스타트업의 A.I. team leader로써 Dearmate라는 AI 챗봇 서비스를 운영하고 있고, 이건 굉장히 독특하고 희귀한 경험이다.&lt;/li&gt;
&lt;li&gt;나는 GitHub에서 많은 Follower와 Star를 가지고 있다.&lt;/li&gt;
&lt;li&gt;나는 흔히 말하는 ‘네카라쿠배’ 출신의 엔지니어다.&lt;/li&gt;
&lt;li&gt;나는 안정적인 대기업에서 스타트업 공동 창업이라는 도전을 했다.&lt;/li&gt;
&lt;li&gt;나는 여러 컴피티션에서 좋은 성과를 거뒀다.&lt;/li&gt;
&lt;li&gt;나는 하루 수백명이 방문하는 블로그를 운영하는 블로거다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;앞으로 어떤 방향을 더 발전시키고, 어떤 포인트들을 추가해야할지에 대해서도 생각을 해봐야 될 것이고, 지금 가지고 있는 경험들 중에 어떤 부분을 내가 놓치고 있는지도 한 번 돌이켜봐야겠다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Open AI CEO Sam Altman join Microsoft]]></title><description><![CDATA[Open AI CEO Sam Altman join Microsoft 저번 주말부터 오늘(23.11.20)까지 충격적인 소식이 AI 업계를 강타했다. MAU 1억+명의 사용자를 보유한 ChatGPT를 만든 OpenAI의 CEO Sam Altman…]]></description><link>https://sooftware.github.io/altman/</link><guid isPermaLink="false">https://sooftware.github.io/altman/</guid><pubDate>Sat, 18 Nov 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Open AI CEO Sam Altman join Microsoft&lt;/h1&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/04cfd1e2-af0a-4955-afd7-9efd8b5369db&quot; height=&quot;120&quot;&gt;
&lt;p&gt;저번 주말부터 오늘(23.11.20)까지 충격적인 소식이 AI 업계를 강타했다. MAU 1억+명의 사용자를 보유한 ChatGPT를 만든 OpenAI의 CEO Sam Altman이 OpenAI에서 해고되었다는 것이다.&lt;/p&gt;
&lt;p&gt;이 소식이 전세계적으로 화제가 되어서 시간 단위로 새로운 뉴스가 업데이트 되며 오픈 AI에서 내부적으로 어떤 일이 있었는지, 앞으로 어떻게 전개되는지에 대해 세간의 관심이 쏠렸다.&lt;/p&gt;
&lt;p&gt;업계 사람들이 많이 사용하는 트위터, 페이스북만 해도 샘 올트만의 해임 소식에 대해서 도배가 될 정도였으니, 얼마나 큰 이슈인지 새삼 체감하게 됐다.&lt;/p&gt;
&lt;p&gt;워낙 많은 사람들이 관심을 가지다보니 어느정도 일의 윤곽이 잡혔는데, 정리하면 아래와 같은 것 같다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;OpenAI에서는 오래전부터 (아마 ChatGPT 상용화시점) 내부적으로 갈등이 있었다. (AI의 서비스화 및 빠른공개 vs 철저한 AI의 안전성 검증) (Anthropic도 이러한 이유로 나왔다고..)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;AI 안전성 검증에 확고한 의지를 가진 오픈AI 공동창업자 Ilya sutskever는 칼을 빼들었고 이사진에서 Sam Altman을 CEO 직위에서 해임하기로 결정&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;오픈AI 직원들 다수 퇴사 희망, 마이크로소프트 CEO의 대노&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;오픈AI, 마이크로소프트 등 대화를 통해 샘과 그렉(오픈AI 2인자) 등 Microsoft로 합류&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;샘 올트만이 한순간에 마이크로소프트로 합류하게 된 것도 놀라웠지만, 오픈AI 내부에서 AI의 안전성에 대해 얼마나 크게 신경쓰고 있는지에 대해서도 알 수 있었던 사건이였다. 한편으로는, 찌라시로 돌고있는, 이미 오픈AI는 AGI 수준에 달하는 인공지능을 이미 개발했다는 말도 있는데 어느정도 수준일지, 이 찌라시가 사실일지도 궁금하다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/0a60849b-6bde-4bb9-9cb5-8ab129fe22f8&quot; height=&quot;250&quot;&gt;
&lt;p&gt;지금 상황으로 봐서는 오픈AI는 초기 설립목적에 맞게 AI의 안전성에 대해 더 신경쓰는 연구를 계속하게 될 것 같고, 마이크로소프트는 샘 올트만의 필두로 ChatGPT와 같은 AI의 서비스화쪽으로 힘을 더 쏟을 것 같다. 마이크로소프트의 자본에 오픈AI의 두뇌가 합쳐지면 아마 엄청난 시너지가 나오지 않을까 싶고, 오픈AI 같이 탑클래스 연구기관에서 AI의 안전성 및 위협에 대한 연구에 힘써준다는것도 전세계적으로보면 좋은 일이라고 (개인적으로) 생각한다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[더 마인드 (The Mind)]]></title><description><![CDATA[# 더 마인드 (The Mind…]]></description><link>https://sooftware.github.io/the-mind/</link><guid isPermaLink="false">https://sooftware.github.io/the-mind/</guid><pubDate>Fri, 17 Nov 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;# 더 마인드 (The Mind)&lt;/h1&gt;
&lt;p&gt;흔히 말하는 ‘끌어당김의 법칙’에 대한 책이다. 이 ‘끌어당김의 법칙’이 참 말이 많은 주제인데 이 책은 이 법칙을 완전히 지지하는 입장의 책이다.&lt;/p&gt;
&lt;p&gt;‘하와이 대저택’이라는 유튜버가 쓴 책인데, 책을 읽게 되면서 해당 채널을 처음 알게 되었다. 구독자 40만명 정도의 규모가 큰 채널이다. 사실 책을 살때만해도 해외에서 쓴 책인줄 알았는데, 국내 유튜버가 쓴 책이여서 더 흥미로웠다.&lt;/p&gt;
&lt;p&gt;책에서 강조하는건 ‘무의식을 최대한 활용해야 된다’라는 점인다. 내가 계속 내가 원하는 미래를 상상하고, 나는 성공한다고 다짐하면서 그 의지를 무의식속에 키우다보면 내 뇌(?)가 그 목표를 이루도록 에너지를 내게한다는 것이다.&lt;/p&gt;
&lt;p&gt;이 ‘끌어당김의 법칙’에 대해서는 실제로 존재한다는 의견도 많고, 말도안되는 말이라는 의견도 많은데, 어쨌든 직업이 과학에 기반을 둔 사람으로써, 개인적으로는 이 법칙에 대해서 회의적이다.&lt;/p&gt;
&lt;p&gt;특히 이 법칙을 무조건적으로 믿으며 다른 어떤 노력보다도 이 ‘끌어당김의 법칙’만 믿는건 잘못됐다고 본다. 하지만 그래도 습관적으로 긍정적인 상상을 하고, 내 목표를 구체화하고, 나는 성공한다와 같은 생각을 되뇌이는 습관을 가지게 되면 내 목표를 더 확실시하는데에 도움이 된다고는 생각한다.&lt;/p&gt;
&lt;p&gt;책에서 ‘무의식’을 활용하는 팁 같은것도 나오는데, 이런 부분은 너무 짜잘한 부분이라고 생각하고, 결국 핵심은 내가 진짜로 원하는 삶의 목적을 구체적으로 정하고, 원하는 삶을 이루려면 어떤 미래가 펼쳐져야 하는지를 구체적으로 상상하고, 계산해보며 목적지를 정하고 그러한 미래가 펼쳐지도록 강한 의지를 가져야한다는 것이 이 책에서 그나마 가져갈만한 내용인 것 같다.&lt;/p&gt;
&lt;p&gt;개인적으로 아쉬웠던 점은 너무 ‘무의식’이나 ‘끌어당김의 법칙’이 ~한 결과를 만들어줬다고 너무 그 부분에만 초점을 맞춘 느낌이 들었다. 100일 동안 매일 ‘나는 성공한다’를 100번씩 글씨로 쓸 정도의 강한 의지가 있고, 본인의 목표가 명확한 사람이라면 당연히 좋은 결과가 따르지 않을까? 무의식을 활용한게 도움이 됐겠지만, 이게 꼭 ‘무의식’을 활용했기 때문만이 아닐텐데, 너무 그 부분에만 초점을 맞춰서 서술한다는 생각이 들었다.&lt;/p&gt;
&lt;p&gt;그리고 책을 보면 저자가 자기계발 서적 수천권을 읽었다고 하는데, ‘정말 그랬을까?‘라는 의문이 들면서 신뢰도가 많이 줄어들었다. 하루에 책을 한 권씩 읽어도, 천 권을 읽으려면 3년을 꼬박 실행해야하고, 수천권이면 그 이상인데.. 휴일도 없이 직장에서 일하셨다는 분이 어떻게 수천권의 자기계발 서적을 읽을 수 있었는지 의문이 든다.&lt;/p&gt;
&lt;p&gt;그래도 이 책을 읽고 얻어갈만한건, 내 미래에 대한 목표를 더 구체적으로, 더 자주 상상하며 에너지를 얻어봐야겠다는 생각이 든다.&lt;/p&gt;
&lt;p&gt;추천은 안 한다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[부의 추월차선 (The Millionaire Fastlane)]]></title><description><![CDATA[# 부의 추월차선 (The Millionaire Fastlane…]]></description><link>https://sooftware.github.io/millionaire-fastlane/</link><guid isPermaLink="false">https://sooftware.github.io/millionaire-fastlane/</guid><pubDate>Thu, 16 Nov 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;# 부의 추월차선 (The Millionaire Fastlane)&lt;/h1&gt;
&lt;p&gt;엄청 유명한 책이라 전부터 한 번 읽어봐야지 했다가 드디어 읽어봤다. 전에 읽었던 &lt;a href=&quot;https://sooftware.github.io/leverage/&quot;&gt;레버리지&lt;/a&gt; 와 비슷한 내용이 많았다. 비슷한 내용이지만 집중적으로 말하고 싶은 내용이 레버리지는 책 제목처럼 ‘레버리지(leverage)를 해라!’라면, ‘부의 추월차선’은 좀 더 ‘부’에 초점을 맞춰서 얘기하는 느낌이다.&lt;/p&gt;
&lt;p&gt;그런데 이 ‘부’에 대해 얘기할때 본인의 경험담을 토대로 너무 자신있게 광범위한 사람들에게 난사하는 느낌을 받았다. 읽다보면, 직장인들에게 ‘너의 삶을 틀렸어!’라고 말하는 듯했고, 마치 ‘부’를 이루기 위한 공식이 있으니 이 공식만 따르면 돼!라고 말하는 듯했다.&lt;/p&gt;
&lt;p&gt;물론 이 책에 나온 방법을 실천해서 원하는 부를 얻은 사람도 있겠지만, 사업을 하다가 본인의 능력이 부족해서든, 시기를 잘못만났든 여러 상황속에서 안 좋은 케이스도 있을텐데 어떻게 6년 정도 주 7일동안 열심히 일하면 엄청난 성공이 당연하게 따라온다고 확신해서 말할 수 있는지도 의문이다. 지금 스타트업 공동창업자로써 3년 정도 지났는데, 이 3년동안 주위에 없어진 스타트업도 많고, 성공가도를 달리다가도 팍 꺾여서 생존에 위협을 받는 기업들도 많이 보고있다. 과연 6년동안 주 7일 하루 12~16시간 일에 매진하면서 번아웃이 오지 않는 사람이 얼마나 있을까? 세상에는 많은 케이스가 있는데, 본인의 케이스를 모두에게 적용하려고 하는 듯했다.&lt;/p&gt;
&lt;p&gt;책 제목부터 ‘부의 추월차선’으로, 모든 사람이 이 내용을 알면 부자가 될 수 있다는 듯이 말하지만, 개인적으로는 그저 저자가 부자가 된 방법을 모두에게 ‘이렇게 해라!’라고 말하는 듯 하다.&lt;/p&gt;
&lt;p&gt;그리고 가장 별로인 점은 세상 모든 직장인들을 마치 ‘바보’ 취급하는 듯 하다는 점이였다. 이 외에도 여러모로 실망스러운 책이다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[LLM Paper Abstract - 2023.10]]></title><description><![CDATA[LLM Paper Abstract - 2023.10 LLM…]]></description><link>https://sooftware.github.io/llm-abs-202310/</link><guid isPermaLink="false">https://sooftware.github.io/llm-abs-202310/</guid><pubDate>Sun, 05 Nov 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;LLM Paper Abstract - 2023.10&lt;/h1&gt;
&lt;p&gt;LLM 관련해서 워낙 많은 논문들이 나와서, 최근에 읽은 논문들에 대해 간단하게 요약한 리스트입니다.&lt;br&gt;
아래 리스트중에는 가볍게 읽어본 논문들이 포함되어 있어서 요약에 틀린 내용이 있을 수 있습니다.&lt;/p&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;h3&gt;10월 4주차&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2307.11760&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Large Language Models Understand and Can be Enhanced by Emotional Stimuli&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : LLM 프롬프트에 감정적인 요소(Ex. 이건 내 커리어에 중요한 일이야)를 추가하면 답변 품질이 좋아진다고 하는 논문.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2310.06825&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Mistral 7B&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : Mistral 7B 모델 테크니컬 리포트. 7B 모델로 LLaMA2 13B 모델을 모든 벤치마크에서 이겼다고 함. 눈에 띄는 정보는 Sliding Window Attention인데, 어텐션 레이어마다 N토큰씩 나눠서 보게 함으로써 메모리 사용량을 줄였다는 점.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2308.11432&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;A Survey on Large Language Model based Autonomous Agents&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : LLM을 이용한 Autonomous Agent에 대한 서베이 논문. 특별한 방법보다는 여태까지 제안된 방법들에 대한 소개와 이러한 방법들로 만든 시스템의 성능들에 대해 써져있음.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2310.18313&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;FP8-LM: Training FP8 Large Language Models&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : FP8 training에 관한 논문.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs//2310.11511&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 기존의 RAG 방식은 retrieval을 할 때, 연관되지 않은 doc도 retrieval하고 부분적으로 연관된 doc도 retrieval하기 떄문에 이런 부분을 self-rag를 활용하여 개선했다는 내용의 논문. 생성을 할 시에 retrieval이라는 스페셜 토큰을 활용하여 계속 retrieval을 할지 말지 고려한다는 내용의 논문이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2310.16944&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Zephyr: Direct Distillation of LM Alignment&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : Mistral 7B를 foundation모델로 하여 gpt4로 생성한 데이터를 활용하여 distillation했다는 내용의 논문. 방법론은 gpt4로 sft 데이터를 생성하여, sft, dpo 방식을 활용함. AlpacaEval 성능지표에서 LLaMA2-70B-chat을 이겼다는 논문.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2309.06275&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Re-Reading Improves Reasoning in Language Models&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 문제를 두 번 읽게하면 성능이 오른다는 논문&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2209.11895&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;In-context Learning and Induction Heads&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : Induction heads([A][B] … [A] → [B]와 같은 작업을 수행하는 attention heads)가 in-context learning의 주요 매커니즘이라고 주장 및 간접적인 증거를 제시하는 논문. 트랜스포머 모델 학습에 대해 굉장히 디테일하게 잘 분석한 논문.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2308.02773&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;EduChat: A Large-Scale Language Model-based Chatbot System for Intelligent Education&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 교육용 챗봇을 만드는 방법 및 오픈소스에 관한 논문. 질문에 대해 바로 답하기보다는 Socratic하게 답변하는 방법으로 만들었다고 함. 나중에 교육용 챗봇 만들때 참고해보면 좋을 것 같음.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2310.16789&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;DETECTING PRETRAINING DATA FROM LARGE LANGUAGE MODELS&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 어떤 데이터에 대해서 LLM의 프리트레이닝에 사용됐는지 확인하는 방법을 제안한 논문. Ground Truth에 해당하는 토큰들에 대해 LLM이 예측한 확률들이 K를 넘냐 안 넘냐로 판단하는 방법.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2305.15255&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Spoken Question Answering and Speech Continuation Using Spectrogram-Powered LLM&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : Pre-trained LM (Decoder)와 Spectrogram을 인풋으로 하는 Speech Encoder를 결합해서 end-to-end로 ASR, LM, TTS를 학습하는 방법론을 제시함.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;10월 3주차&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2310.06692&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Meta-CoT: Generalizable Chain-of-Thought Prompting in Mixed-task Scenarios with Large Language Models&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 기존의 CoT(Chain of Thought)의 방식은 task별로 demonstration과 같은 few shot sample들을 입력해줘야 한다. 하지만 이러한 방식은 generalization에서의 gap이 생겨서, 본 논문에서는 Meta-CoT라는 방식으로 task specific하지 않고, generalization을 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2305.04533&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Prompted LLMs as Chatbot Modules for Long Open-domain Conversation&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : MPC(Modular Prompted Chatbot)이라는 개념으로 파인튜닝 없이도 long-term consistency와 flexibility를 유지할 수 있다는 논문. 여기서 핵심 개념은 단순히 프롬프팅만으로 챗봇을 만드는 것이 아니다. 유저가 input을 입력하면 LLM 입장에서 모호하지 않게 문장을 바꿔주는 clarifier, clarifier의 output과 이전에 대화 히스토리에서 쌓아놨던 memory pool에서의 memory들을 DPR을 활용하여 추출한다. 이렇게 추출된 문장들을 CoT(Chain of Thought)를 활용한 Memory Processor를 이용하여 한 문장으로 나타낸다. 마지막으로 이렇게 추출된 문장을 활용해 챗봇의 페르소나로 활용하여 utterance를 생성한다. 그리고 생성된 대화들을 모아서 요약하여 다시 memory pool에 주입한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2310.01889&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Ring Attention with Blockwise Transformers for Near-Infinite Context&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 16M 토큰까지 확장 가능한 어텐션을 제안한 논문.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2310.05915&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;VeRA: Vector-based Random Matrix Adaptation&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : LoRA보다 학습 파라미터수를 1/10으로 줄이면서 성능은 유지했다는 논문.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2310.05915&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;FIRE ACT: TOWARD LANGUAGE AGENT FINE-TUNING&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : Prompting보다 fine-tuning이 효과적이고, 파인튜닝 데이터 및 태스크가 다양할수록 성능이 개선된다고 주장하는 논문.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2310.04408&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;RECOMP: IMPROVING RETRIEVAL-AUGMENTED LMS WITH COMPRESSION AND SELECTIVE AUGMENTATION&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : RAG가 LLM에서 많이 사용되고 있는데, 긴 document가 그대로 프롬프트에 들어가는건 computational cost 측면에서 비효율적임. 이런 부분을 보완하고자 2개의 compressor를 사용하여 프롬프트에 들어가는 토큰 수를 줄이는데, 하나는 필요한 정보를 선택하고, 나머지 하나는 필요한 정보들을 모아서 요약하는 역할을 수행한다. 이 2가지 추가 모듈로 RAG를 더 효율적으로 적용함.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2310.07064&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;LARGE LANGUAGE MODELS CAN LEARN RULES&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 2진수에서 1+1=10 인것 같이 일반적인 상식(1+1=2)과 다른 문제를 풀 때, hallucination이 일어나기 쉬운데 이를 방지 및 더 잘 풀게 하기 위해 Induction, Deduction 두 스테이지로 나눠서 풀었을 때 성능이 좋아졌다는 논문. Induction은 예제를 보여주고 (1+1=10, 10+1=11, 11+1=100, …) 이 예제에서 Rule을 찾아보라고 LLM에게 시켜보는 단계고, Deduction은, 이 Rule을 프롬프트에 넣어서 문제를 풀게하는 단계. 이렇게 나눠서 풀게했을 때, 바로 풀게했을때보다 성능이 좋아졌다고 함. 구글에서 낸 논문.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/pdf/2308.09597.pdf&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;ChatHaruhi: Reviving Anime Character in Reality via Large Language Model&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : RAG를 사용한 Role-playing 챗봇에 대한 논문. 해리포터, 빅뱅이론, 영화, 드라마, 애니 등 32개의 다양한 캐릭터들을 챗봇으로 만들었음. 대사 스크립트 등을 크롤링 또는 STT를 사용해서 텍스트 DB로 변환하고 RAG 방식으로 실제 대사를 검색하여 프롬프트에 넣고 대답을 생성하는 방식을 적용. &lt;a href=&quot;https://huggingface.co/spaces/chengli-thu/ChatHaruhi-OpenAI?fbclid=IwAR0CIKSR6CAd1ITxsP1pKue-kaOJDwa6uIDbAh160G90XI8lbl3Q_nJQp8Q&quot;&gt;&lt;em&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/LC1332/Chat-Haruhi-Suzumiya?fbclid=IwAR0z45dQewr07iOmleAjNlEKTBsXGHVRu1KNIsjuOWGOqFrpwgo4SNH3uIY&quot;&gt;&lt;em&gt;&lt;strong&gt;:octocat: GitHub&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;10월 2주차&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2305.10601&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Tree of Thoughts: Deliberate Problem Solving with Large Language Models&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : LLM은 다양한 문제를 해결해주지만, 모델 구조상 토큰 레벨로, 왼쪽부터 오른쪽으로 추론하는 방식만 사용할 수 있다. 여기서 많은 문제점이 발생할 가능성이 있어서, 이 부분을 해결하고자 Tree of Thoughts라는 해결 방식을 본 논문에서는 제시한다. 창의적 글짓기나, Mini Crossword 게임 등에서 많은 성능 향상을 이끌어냈다. 토큰 단위가 아닌 사고 과정 단위로 끊어서 BFS, DFS 등으로 최적의 사고 흐름을 찾는 느낌이다.&lt;a href=&quot;https://github.com/princeton-nlp/tree-of-thought-llm&quot;&gt;&lt;em&gt;&lt;strong&gt;:octocat: GitHub&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2309.13339&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Enhancing Zero-Shot Chain-of-Thought Reasoning in Large Language Models through Logic&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : LLM은 많은 지식을 그 모델 안에 내포하고 있지만, 이것을 일관적인 사고 과정으로 꺼내 쓰지는 않는다. 본 논문에서는 zero-shot chain-of-thought 추론 성능을 향상 시키기 위해 Logical Chain-of-Thought(LogiCoT) 방법론을 제시한다. 단순 Chain-of-Thought가 아닌 생성된 output의 검증 과정을 하나 더 넣은 과정으로 보인다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2304.08177&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Efficient and Effective Text Encoding for Chinese LLaMA and Alpaca&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : ChatGPT나 GPT-4와 같은 LLM은 close source로 운영하기에 academic한 연구를 하기에는 어려움이 많다. LLAMA와 같은 모델들이 open source로 풀렸지만 영어 이외의 언어에 대해서는 사용성이 떨어져서 본 논문을 통해 LLAMA가 중국어 text를 이해하고, 중국어 instruction을 따를 수 있도록 하기 위한 방법론을 제시한다. &lt;a href=&quot;https://github.com/ymcui/Chinese-LLaMA-Alpaca&quot;&gt;&lt;em&gt;&lt;strong&gt;:octocat: GitHub&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2309.03409&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;LARGE LANGUAGE MODELS AS OPTIMIZE&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : LLM이 직접 더 좋은 프롬프트를 찾아주게하는 시도를 한 논문. 잘 알려진 &lt;code class=&quot;language-text&quot;&gt;Let&apos;s think step by step&lt;/code&gt; 보다 LLM이 제안한 &lt;code class=&quot;language-text&quot;&gt;Take a deep breath and work on thie problem step-by-step&lt;/code&gt;로 문제를 풀었을 때 더 나은 결과를 보임. by deepmind.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2305.11206&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;LIMA: Less Is More for Alignment&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : LLM에 대해 너무 많은 데이터로 파인튜닝하는것보다 오히려 적은 데이터로 학습하는게 더 좋았다는 논문. 단 1,000개의 파인튜닝 데이터로 좋은 성능을 보임.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;10월 1주차&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2310.03025v1&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Retrieval meets Long Context Large Language Models&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : LLM을 파인튜닝하는거나 긴 컨텍스트 모델을 사용하는것보다 RAG를 잘 사용하는것이 좋다고하는 논문. 엔비디아에서 냄.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2310.03214v1&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;FreshLLMs: Refreshing Large Language Models with Search Engine Augmentation&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 최신 지식이 필요한 질문에 대하여 구글 검색결과를 그대로 스크래핑해서 프롬프트에 넣었더니, 28.6 =&gt; 75.6으로 점수가 크게 상승했다는 논문. OpenAI, Google이 참여한 것치고 간단한 방법.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2309.07124&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;RAIN: Your Language Models Can Align Themselves without Finetuning&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : LLM을 align하기 위해 일반적으로 human preference data와 RL, instruction tuning 방식을 활용하곤 한다. 하지만 본 논문에서는 self-evaluation과 rewind 메커니즘만으로도 human preference response를 생성할 수 있다고 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2309.12307&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;LONGLORA: EFFICIENT FINE-TUNING OF LONGCONTEXT LARGE LANGUAGE MODELS&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 일반적으로 long context를 학습하는데 매우 많은 계산 비용이 드는데, 본 논문에서는 이를 가속화하려고 한다. 추론시에는 dense global attention이 필요한데, FT시에는 shift short attention(sparse local attention)을 활용하고, LoRA를 활용하여, 계산 효율적이면서도 정확성을 유지하고자 한다. &lt;a href=&quot;https://github.com/dvlab-research/LongLoRA&quot;&gt;&lt;em&gt;&lt;strong&gt;:octocat: GitHub&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2310.02226&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Think before you speak: Training Language Models With Pause Tokens&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 사람이 고민하고 답변을 내는 것처럼, &lt;code class=&quot;language-text&quot;&gt;&amp;lt;PAUSE&gt;&lt;/code&gt; 토큰이라는 것을 만들어서 인퍼런스시에 프롬프트 이후에 K 스텝의 아웃풋을 무시하고 그 뒤부터 생성 결과를 활용하는 방식으로 했을 때, QA 태스크에서 성능 향상이 있었다는 논문 (프리트레이닝도 &lt;PAUSE&gt; 토큰에 대한 학습이 필요함)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2309.17453&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Efficient Streaming Language Models with Attention Sinks&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : Backbone 모델의 &lt;code class=&quot;language-text&quot;&gt;max_length&lt;/code&gt;는 한정되어 있다는 단점이 있는데, 이를 Key와 Value의 initial token의 어텐션 스코어가 과도하게 높은 경향이 있는 점을 이용하여 해당 토큰들만 포함하여 어텐션을 수행하는 방식으로 추가적인 fine-tuning 없이 최대 토큰 길이를 infinite하게 늘린 방법론에 대한 논문 (성능이 괜찮다고 함) &lt;a href=&quot;https://github.com/mit-han-lab/streaming-llm&quot;&gt;&lt;em&gt;&lt;strong&gt;:octocat: GitHub&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2307.09288&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Llama 2: Open Foundation and Fine-Tuned Chat Models&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : Meta에서 공개한 LLaMA2 모델 학습 관련한 테크니컬 리포트 (7B, 13B, 70B 모델 공개)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[그들은 왜 최후의 승자가 되지 못했나]]></title><description><![CDATA[…]]></description><link>https://sooftware.github.io/game-theory/</link><guid isPermaLink="false">https://sooftware.github.io/game-theory/</guid><pubDate>Tue, 31 Oct 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;# 그들은 왜 최후의 승자가 되지 못했나&lt;/h1&gt;
&lt;p&gt;서점에서 책 이름을 봤을 때부터 흥미로웠다. ‘게임이론’이라는 개념을 역사속 인물 중 끝이 좋지 못했던(항우, 도요토미 히데요시, 한신 등) 인물들이 어째서 그렇게 됐는가에 대해 분석해보고 어떤 선택을 했다면 끝이 좋아졌을까? 하는 게임이론 기반하에 상상의 나래를 펼쳐보는 책이다.&lt;/p&gt;
&lt;p&gt;원래 역사를 좋아했고, 특히 초한지의 모든 전쟁에서 승리하는 ‘한신’을 어렸을적에 좋아했는데, 그 똑똑했던 한신이 어째서 토사구팽을 당했는지에 대해 게임이론 전문가가 분석했다는 점에서 꼭 보고 싶다는 생각이 들어 읽게 되었다.&lt;/p&gt;
&lt;p&gt;책을 읽으며 게임이론에서 관계의 가장 중요한 요소 중 하나는 ‘미래의 이해득실’이라고 느껴졌다. 한신도 유방을 위해 초나라의 항우를 포함한 여러 적들을 모두 굴복시켰지만, 전쟁이 끝난 후에는 전쟁에 탁월한 능력을 가진 한신은 필요가 없고, 오히려 이 능력이 자신에게 향할까 두려워한 유방은 결국 한신을 처형시켰다. 말그대로 토사구팽 당한것인데, 현대 사회로 접목해보자면 스타트업 초기에 A라는 사람이 엄청난 컨트리뷰션을 해서 스타트업을 몇 배나 성장시키는데 큰 공헌을 했는데, 이제는 A라는 사람이 없어도 사업이 잘 돌아갈 뿐만 아니라 오히려 이러한 공헌에 대해 큰 상을 요구하는 A에게 권고사직을 요구하는 상황일 것 같다.&lt;/p&gt;
&lt;p&gt;관련해서 예전에 대학교 교수님께서 들려주셨던 재밌는 얘기가 떠올랐다. 교수님께서 회사에 다니실때 같은 팀 엔지니어 분 중에 코드를 짤 때 변수명을 특이한 규칙으로 짓는 분이 계셨다고 한다. 첫 번째 변수명은 &lt;code class=&quot;language-text&quot;&gt;i&lt;/code&gt;, 두 번째 변수명은 &lt;code class=&quot;language-text&quot;&gt;ii&lt;/code&gt;, 세 번째 변수명은 &lt;code class=&quot;language-text&quot;&gt;iii&lt;/code&gt;, … 와 같이 누가봐도 보기 어렵게 코드를 짜는 분이 계셨는데, 이 분이 짠 코드가 회사의 핵심 소프트웨어에 들어갔고 이 코드 유지보수를 위해서 회사는 IMF때도 그분을 절대 짜를 수 없었다는 썰이였다. 당시에는 웃고 넘긴 얘기였지만 지금 생각해보면 이 엔지니어분이 게임이론의 고수가 아닐까 싶다.&lt;/p&gt;
&lt;p&gt;이 외에도 ‘쥐도 궁지에 몰리면 고양이를 문다’라는 속담에 해당하는 상황, 후계자 임명에 대한 상황 등 여러 역사속 사건에 대한 게임이론적 평가를 보며 역사적 사건을 통해 현실속 상황에 대입해보며 어떤 판단을 하는게 나에게 유리한지에 대해서 생각해보는 좋은 계기가 되었다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[레버리지 (LEVERAGE)]]></title><description><![CDATA[# 레버리지 (LEVERAGE…]]></description><link>https://sooftware.github.io/leverage/</link><guid isPermaLink="false">https://sooftware.github.io/leverage/</guid><pubDate>Tue, 31 Oct 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;# 레버리지 (LEVERAGE)&lt;/h1&gt;
&lt;p&gt;전부터 유명했던 ‘레버리지’, ‘부자 아빠 가난한 아빠’, ‘부의 추월차선’ 등의 책을 읽어봐야겠다고 생각했는데, 이번에 레버리지를 완독했고, 지금은 ‘부의 추월차선’을 읽고 있다.&lt;/p&gt;
&lt;p&gt;지금 읽고있는 ‘부의 추월차선’과 비슷한 내용이 많이 나오는데, 두 책 모두 ‘젊을 때 열심히 모아서 은퇴하고 나서 마음 편히 사는 삶’보다는 ‘젋을 때도 돈에 대한 걱정 없이 주체적으로 사는 삶’을 추구하고, 그러기 위한 방법을 제시한다. 레버리지에서는 ‘주기적으로 은퇴하는 삶’이라고 표현하는데, 개인적으로 이 표현이 마음에 와 닿았다. (은퇴에 대해 더 주체적인 느낌)&lt;/p&gt;
&lt;p&gt;일반적으로 레버리지라고하면 대출쪽에서 많이 사용되는 말이다. ‘현재 1억이라는 돈이 있는데, 3억짜리 집을 사기 위해 2억을 대출받아서 3억짜리 집을 산다’와 같은 경우에 흔히 쓰이는 용어인데, 이 책에서 의미하는 레버리지는 내 시간, 내 노력 등을 최소로 투자해서 가장 큰 부가가치를 내게하는 부자가 되기 위해 알아야하는 ‘법칙’ 같은 의미로 사용됐다.&lt;/p&gt;
&lt;p&gt;예를 들어서 출퇴근하는 시간에 직접 운전하기보다는 기사를 두고 그 시간에는 책을 읽거나 스마트폰으로 업무를 처리한다던가, 내가 잘 못하거나 시간을 투자하기 어려운 일(청소, 일정관리, 요리 등)에 대해서는 이러한 일을 해주는 사람을 고용함으로써 내 에너지를 온전히 최고의 효율을 낼 수 있는 부분에 투자한다던가와 같은 경우 ‘레버리지 했다’ 라고 책에서는 표현하고 있다.&lt;/p&gt;
&lt;p&gt;책에 많은 얘기들이 나오지만 결국 &lt;strong&gt;한정적인 시간을 최대 효율이 나오는 곳에 투자&lt;/strong&gt;하고, 나머지 &lt;strong&gt;비교적 중요하지 않은 일들은 인력, 돈, 자동화 시스템 등으로 레버리지&lt;/strong&gt;해야된다는게 중요 포인트였다고 생각한다.&lt;/p&gt;
&lt;p&gt;책을 읽으며 내가 봤던 능력있는 사람들을 떠올리며 ‘이 사람이 이런 부분에서 레버지리했구나’라는 생각이 드는 점도 재밌었던 포인트였다.&lt;/p&gt;
&lt;p&gt;책을 모두 읽고, 내 삶에서 어떤 시간들이 낭비되고 있고, 어떤 부분을 레버리지할 수 있는지에 대해 돌아보게 됐다.&lt;/p&gt;
&lt;p&gt;가장 아까운 시간은 아무래도 출퇴근 시간인데, 이 시간을 활용하기 위해 요즘 책을 가지고 다니며 버스에서 읽거나 피곤하면 유튜브로 영어 오디오북이라도 듣고 있다. 그리고 그동안 낭비했던 시간들에 대해 반성하며 하나하나 줄여나가보려고 노력중이다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Findings of EMNLP 2023 Accept]]></title><description><![CDATA[Findings of EMNLP 2023 - Accept 공동 1저자로 참여한 “A Korean News Comments Dataset with Target-Specific Offensiveness Ratings” 논문이
Findings of…]]></description><link>https://sooftware.github.io/emnlp_2023/</link><guid isPermaLink="false">https://sooftware.github.io/emnlp_2023/</guid><pubDate>Wed, 11 Oct 2023 12:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Findings of EMNLP 2023 - Accept&lt;/h1&gt;
&lt;img src=&quot;https://2023.emnlp.org/assets/images/logos/emnlp-2023-logo.png&quot; height=&quot;150&quot;&gt;
&lt;p&gt;공동 1저자로 참여한 “A Korean News Comments Dataset with Target-Specific Offensiveness Ratings” 논문이
Findings of EMNLP 2023에 억셉되었습니다!&lt;/p&gt;
&lt;p&gt;해당 연구는 저희 튜닙과 숭실대 HUMANE Lab과 공동연구한 작업물입니다.&lt;/p&gt;
&lt;p&gt;제가 리서쳐보다는 엔지니어 성향이 강하고, 하는 일도 엔지니어 역할을 많이 하고 있어서 논문 writing과는 거리가 좀
있는데, 21년도에 오픈소스 관련 논문 이후로 연구 관련으로는 첫 논문입니다 :)&lt;/p&gt;
&lt;p&gt;이 논문은 저희 Safety Check라는 서비스를 만들며 고민한 내용이 반영된 데이터셋 논문입니다.&lt;/p&gt;
&lt;p&gt;인터넷상에 존재하는 많은 혐오/차별적인 발언에 대해 저희가 정의한 11가지의 클래스와 각 클래스 별로 &lt;code class=&quot;language-text&quot;&gt;없음 (0)&lt;/code&gt; / &lt;code class=&quot;language-text&quot;&gt;주의 (1)&lt;/code&gt; / &lt;code class=&quot;language-text&quot;&gt;명백 (2)&lt;/code&gt; / &lt;code class=&quot;language-text&quot;&gt;심함 (3)&lt;/code&gt; 과 같이 Likert 척도로 구분하여 라벨링했으며,
해당 혐오의 대상에 대한 라벨링까지 되어 있는 데이터셋입니다.&lt;/p&gt;
&lt;p&gt;현재 공개된 많은 데이터셋들이 바이너리하게 1, 0으로 구분되어 혐오를 표현하는데, 문맥에 따라
혐오 표현이 될 수도/안 될수도 있는 상황도 있고, 그 정도가 심한 경우와 그렇지 않은 경우에 대해서도 구분이 된다면
실제 서비스 단에서 사용할 때 보다 유연하게 적용이 가능하다는 장점이 있습니다.&lt;/p&gt;
&lt;p&gt;이러한 저희의 고민에 대한 연구가 좋은 학회에 게재되게되어 해당 연구의 유종의 미를 거두게 된 것 같습니다.&lt;/p&gt;
&lt;p&gt;논문은 공개 가능한 시점에 바로 링크 달아 놓겠습니다!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[RECORD] 개인 운동 기록 - 2023.10.11]]></title><description><![CDATA[개인 운동 기록 - 2023.10.11 오랜만의 운동 기록이다. 다행히 운동은 꾸준히 하고 있고, 몸도 많이 좋아졌고 수행능력도 좋아졌다. 운동 시작하기로 마음 먹은지…]]></description><link>https://sooftware.github.io/weight_training3/</link><guid isPermaLink="false">https://sooftware.github.io/weight_training3/</guid><pubDate>Wed, 11 Oct 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;개인 운동 기록 - 2023.10.11&lt;/h1&gt;
&lt;p&gt;오랜만의 운동 기록이다.&lt;/p&gt;
&lt;p&gt;다행히 운동은 꾸준히 하고 있고, 몸도 많이 좋아졌고 수행능력도 좋아졌다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/aac8f9bf-114c-4efb-a3c5-4fe2e8a0165c&quot; height=&quot;100&quot;&gt;
&lt;p&gt;운동 시작하기로 마음 먹은지 2년 반 정도의 경과이다. 이렇게 인바디 앱으로 보니까 조금 더 체감이 된다.&lt;/p&gt;
&lt;p&gt;체지방률은 12% 정도 줄이고, 골격근량은 4키로 정도 늘었다. 체지방률은 정상 체중으로 돌아왔고
근육량은 표준이상이 되어 인바디상에서 비만형에서 과체중 강인형이 됐다. 💪 💪&lt;/p&gt;
&lt;p&gt;대학교 4학년부터 취업, 창업까지 앉아서 컴퓨터만 하면서 운동은 멀리하다보니 급격하게 살이 많이 쪘었는데,
오래걸렸지만 꾸준히 건강한 몸으로 돌아와서 다행이다!&lt;/p&gt;
&lt;p&gt;최종적으로는 의도치않게 대학생때 몸에서 근육 벌크업을 하게 됐다 ㅋㅋ&lt;/p&gt;
&lt;p&gt;요즘은 1RM도 무리가 안 가는 선에서 한 번씩 체크하는데, 스쿼트 140, 데드리프트 170, 벤치프레스 90으로
3대 400을 달성했다. 얼마전까지는 벤치 100까지는 비교적 쉽게 들었는데 몸무게가 빠지고, 왼쪽 팔꿈치에 부상이 좀 생기면서
현재는 90정도까지만 들게 되었다. 😭&lt;/p&gt;
&lt;p&gt;주 4-5회 정도로 운동 꾸준히 하면서 먹고싶은건 먹고, 술도 먹고 하면서 스트레스 받지 않으면서
즐기며 만든 몸이라 더 보람차다. 물론 그만큼 오래는 걸렸지만, 개인적으로는 이렇게 천천히 변화해가는걸 선호한다.&lt;/p&gt;
&lt;p&gt;앞으로도 꾸준히 더 해서 살도 더 빼고, 수행능력도 올려서 언젠가는 삼대 오백을 달성하는 날이 오기를 🫡&lt;/p&gt;</content:encoded></item><item><title><![CDATA[자체 LLM으로 제작한 챗봇 서비스, Dearmate]]></title><description><![CDATA[자체 LLM으로 제작한 챗봇 서비스, Dearmate 최근 제가 하고 있는 일에 대해서 소개드리고 싶어 글을 적게 됐습니다. 저는 튜닙 이라는 자연어처리 테크 스타트업의 공동창업자이자, AI 엔지니어로써 일하고 있습니다. 21년…]]></description><link>https://sooftware.github.io/dearmate/</link><guid isPermaLink="false">https://sooftware.github.io/dearmate/</guid><pubDate>Sat, 22 Jul 2023 12:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;자체 LLM으로 제작한 챗봇 서비스, Dearmate&lt;/h1&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/7aa6cb0a-60e9-4558-bfbd-91eb8e8771fe&quot; height=&quot;400&quot;&gt;
&lt;p&gt;최근 제가 하고 있는 일에 대해서 소개드리고 싶어 글을 적게 됐습니다.&lt;/p&gt;
&lt;p&gt;저는 &lt;a href=&quot;https://www.tunib.ai/&quot;&gt;튜닙&lt;/a&gt; 이라는 자연어처리 테크 스타트업의 공동창업자이자, AI 엔지니어로써 일하고 있습니다.&lt;br&gt;
21년 3월에 법인을 설립하고 어느덧 창업한지 2.5년이라는 시간이 지났습니다.&lt;/p&gt;
&lt;p&gt;창업했을 당시에, 미래에 저희가 만들어낼 다양한 페르소나의 챗봇들을 상상하며 꿈꿨는데,
최근 저희 &lt;a href=&quot;https://dearmate.ai/&quot;&gt;Dearmate&lt;/a&gt; 라는 이름의 서비스로 그 꿈이 시작이 되고 있습니다. 😎&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/f50359b5-2cc4-4cbb-b83f-bf68357395e1&quot; height=&quot;300&quot;&gt;
&lt;p&gt;Dearmate 서비스가 나오기 전까지는 한국어 챗봇인 코코, 마스와 영어 여행 챗봇인 Bloony 정도가 서로 다른 플랫폼에서 서비스가 됐었는데,
이제는 Dearmate라는 하나의 서비스에 함께 탑재되어 있으며, 코코, 마스, 블루니 외에도 60여가지가 넘는 챗봇이 존재하며,
빠른 속도로 다양한 페르소나를 추가해나가고 있습니다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/sooftware/sooftware.io/assets/42150335/bdea6bf5-577a-44bc-a1fe-f45c5db80813&quot; height=&quot;150&quot;&gt;
&lt;p&gt;전에 한참 바이럴을 탔던 ‘인공지능 N행시’ 혹시 아시나요?&lt;/p&gt;
&lt;p&gt;이 서비스도 저희 팀에서 만든 서비스입니다 😁 해당 케릭터도 현재 디어메이트에서 만나보실 수 있습니다!&lt;/p&gt;
&lt;p&gt;현재 N군이라는 이름으로 N행시를 만들어주는 케릭터부터, 부산에 대해 설명해주는 부산갈매기, 사자성어로 대답하는
사자성어봇, 공감력이 뛰어난 왕공감, 잡학다식한 고양이 Baron, 죄를 심판해주는 염라대왕 등 다양한 케릭터들이 준비되어 있습니다!&lt;/p&gt;
&lt;div class=&quot;gatsby-resp-iframe-wrapper&quot; style=&quot;padding-bottom: 56.25%; position: relative; height: 0; overflow: hidden; margin-bottom: 1rem&quot; &gt; &lt;iframe src=&quot;https://www.youtube.com/embed/UmI14JEyxD4&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot; style=&quot; position: absolute; top: 0; left: 0; width: 100%; height: 100%; &quot;&gt;&lt;/iframe&gt; &lt;/div&gt;
&lt;p&gt;위 유튜브는 실제로 저희 염라대왕 봇과의 대화 내용으로 구성한 Shorts 입니다.&lt;/p&gt;
&lt;p&gt;재밌지 않나요? 😁 😁&lt;/p&gt;
&lt;p&gt;최근 ChatGPT가 엄청난 인기를 끌면서, 해당 API를 이용해서 많은 서비스들이 나오고 있습니다.
저희 Dearmate는 대부분의 챗봇이 자체 LLM으로 제작한 챗봇으로써, 저희의 기술력이 녹아들어가 있습니다.&lt;/p&gt;
&lt;p&gt;물론 아직 부족한 점이 많지만, 빠른 속도로 부족한 부분을 채우며 대화 성능을 높이고 있습니다.&lt;/p&gt;
&lt;p&gt;제 블로그를 보시는 분들은 AI쪽에 관심이 있는 분들일텐데, 자체 LLM으로 제작한 챗봇들이 어떤지
한 번 살펴보시면 어떨까요? 😙&lt;/p&gt;
&lt;p&gt;저희 디어메이트는 &lt;a href=&quot;https://demo.dearmate.ai/&quot;&gt;웹데모&lt;/a&gt; 사이트에서도 이용 가능하고,
&lt;a href=&quot;https://play.google.com/store/apps/details?id=ai.tunib.dearmate&amp;#x26;hl=ko&quot;&gt;Dearmate Play Store&lt;/a&gt;, &lt;a href=&quot;https://apps.apple.com/kr/app/dearmate-%EC%B1%97%EB%B4%87-%EC%B9%9C%EA%B5%AC%EB%93%A4%EA%B3%BC%EC%9D%98-%EA%B3%B5%EA%B0%90-%EB%8C%80%ED%99%94/id6444549452&quot;&gt;Dearmate App Store&lt;/a&gt;
스마트폰 Application으로도 이용 가능합니다! (안드로이드, iOS 모두 지원합니다.)&lt;/p&gt;
&lt;p&gt;저희 팀에서 열심히 만든 서비스니 많은 관심 부탁드립니다!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[LLaMA2]]></title><description><![CDATA[LLaMA2 Meta(전 Facebook)가 이번 7월 18일에 LLaMA2를 공개했습니다. 🎉 LLaMA2 관련 내용이 담긴 논문 과 함께 7B, 13B, 70B 모델을 공개했습니다. 이전 LLaMA와 다르게 LLaMA…]]></description><link>https://sooftware.github.io/llama2/</link><guid isPermaLink="false">https://sooftware.github.io/llama2/</guid><pubDate>Fri, 21 Jul 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;LLaMA2&lt;/h1&gt;
&lt;p&gt;Meta(전 Facebook)가 이번 7월 18일에 LLaMA2를 공개했습니다. 🎉&lt;br&gt;
LLaMA2 관련 내용이 담긴 &lt;a href=&quot;https://arxiv.org/abs/2307.09288&quot;&gt;논문&lt;/a&gt; 과 함께 7B, 13B, 70B 모델을 공개했습니다.&lt;/p&gt;
&lt;p&gt;이전 LLaMA와 다르게 LLaMA2는 상업적 이용이 가능합니다!&lt;br&gt;
한국어 성능이 좋았다면 정말 좋은 소식이겠지만, 아쉽게도 학습에 사용된 한국어는 겨우 0.06% 밖에 되지 않아서, 한국어 성능이
크게 좋지는 않은 것 같습니다. (영어가 약 90%로 대다수를 차지했습니다.)&lt;/p&gt;
&lt;p&gt;기존 LLaMA보다 40% 가량 더 많은 데이터로 학습했다고 합니다.&lt;br&gt;
약 80페이지에 이르는 논문인지라 다 살펴보지는 못했지만, 크게 아래의 내용들을 논문에서 다루고 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pretraining&lt;/li&gt;
&lt;li&gt;Fine-tuning&lt;/li&gt;
&lt;li&gt;Safety&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;개인적으로 잘 학습된 사전학습을 어떻게 하면 더 좋게 사용할 수 있을까를 고민하는 사람으로써, Chapter 3에 해당하는
Fine-tuning 기법 위주로 살펴봤습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Supervised Fine-Tuning (SFT)&lt;/li&gt;
&lt;li&gt;Reinforcement Learning with Human Feedback (RLHF)&lt;/li&gt;
&lt;li&gt;System Message for Multi-Turn Consistency&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Fine-tuning 챕터는 위의 3 주제를 다루고 있습니다.&lt;/p&gt;
&lt;h3&gt;Supervised Fine-Tuning (SFT)&lt;/h3&gt;
&lt;p&gt;SFT 쪽에서는 특별한 내용보다는 하이퍼파라미터 공유, &lt;strong&gt;유저 프롬프트쪽은 loss를 0로 주고 response에 해당하는 부분만
backpropagation을 수행했다는 점&lt;/strong&gt; 등의 디테일한 내용을 담고 있습니다.&lt;/p&gt;
&lt;p&gt;그냥 pre-training 때와 똑같이 학습하게 된다면, 프롬프트 내의 토큰들을 생성하는 것까지 모두 학습하게 되는데,
생각해보면 굳이 파인튜닝 단계에서 프롬프트쪽 토큰 생성을 배울 필요는 없습니다.&lt;/p&gt;
&lt;p&gt;실제로 유저들이 사용할때 필요한 LLM의 능력은 어떠한 프롬프트가 주어졌을 때, 그 뒤의 토큰을 적절하게 생성하는 능력이 필요한 것이기 때문이죠.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Example&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;이모지로만 대답하시오.&amp;lt;|SPECIAL_TOKEN|&gt;유저:안녕?&amp;lt;|SPECIAL_TOKEN|&gt;LLaMA2:👋&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위의 예시 데이터에서 ‘이모지로만 대답하시오.&amp;#x3C;|SPECIAL_TOKEN|&gt;유저:안녕?&amp;#x3C;|SPECIAL_TOKEN|&gt;LLaMA2:’ 이 부분을 조건으로 줬을 때,
👋을 생성하는걸 배워야 하는거지, ‘이모지로만 대답하시오.&amp;#x3C;|SPECIAL_TOKEN|&gt;유저:안녕?&amp;#x3C;|SPECIAL_TOKEN|&gt;LLaMA2:👋’ 전체를 생성하는걸 배워야
하는건 아니니깐요.&lt;/p&gt;
&lt;h3&gt;RLHF&lt;/h3&gt;
&lt;p&gt;RLHF를 총 5번 진행했다고 하는데, preference data로 reward model을 학습하고, 학습된 모델로 RLHF를 진행하고,
RLHF 모델로 새로운 데이터를 수집하는 것을 반복하는 과정을 거쳤습니다.&lt;/p&gt;
&lt;p&gt;매번 PPO를 진행하지는 않고, 마지막 iteration에 대해서만 PPO를 진행했다고 합니다.&lt;/p&gt;
&lt;p&gt;이 외에도 내용이 많은데, 이쪽 파트는 꽤나 자세하게 설명되어 있어서, Allignment 관련해서 디테일하게 살펴볼 수 있다는 의미가 있는 것 같습니다.&lt;/p&gt;
&lt;h3&gt;System Message for Multi-Turn Consistency&lt;/h3&gt;
&lt;p&gt;여기서 핵심은 멀티턴 상황에서 프롬프트에 대해 일관되게 답변을 하도록 하기 위해 &lt;strong&gt;GAtt&lt;/strong&gt;라는 방법을 적용했다는 건데,
일관성 유지를 위해 프롬프트에 들어가는 (instruction, user utterance, bot utterance) 이것들을 어떻게 조합하는지에 대해 다룬 것 같습니다.
(아직 이 부분에 대해서 정확하게 이해를 했다고 생각은 되지 않아서 일단 스킵하겠습니다.)&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;제가 관심있던 부분은 위 내용 정도여서 일단 이 정도까지만 정리하겠습니다. 😁&lt;/p&gt;
&lt;h3&gt;Reference&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2307.09288.pdf&quot;&gt;LLaMA2 Paper&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/facebookresearch/llama-recipes&quot;&gt;LLaMA2 Recipe GitHub&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[GPT-NeoX - DeepSpeed Inference]]></title><description><![CDATA[GPT-NeoX - DeepSpeed Inference DeepSpeed Inference를 사용하면 간단하게 모델 추론 성능을 끌어올릴 수 있다. Tensor Parallel…]]></description><link>https://sooftware.github.io/neox_injection/</link><guid isPermaLink="false">https://sooftware.github.io/neox_injection/</guid><pubDate>Wed, 24 May 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;GPT-NeoX - DeepSpeed Inference&lt;/h1&gt;
&lt;p&gt;DeepSpeed Inference를 사용하면 간단하게 모델 추론 성능을 끌어올릴 수 있다.&lt;br&gt;
Tensor Parallel 등의 최적화를 쉽게 제공하는데, &lt;code class=&quot;language-text&quot;&gt;injection&lt;/code&gt;이라는 기능을 사용하면 더욱 빠르게 할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;replace_with_kernel_inject=True&lt;/code&gt;로 넣어주면 Bert, GPT2, GPT-Neo and GPT-J 모델들은 알아서 최적화를 해주는데,
NeoX는 아직 자동으로 최적화가 안 된다.&lt;/p&gt;
&lt;p&gt;그래서 조금 커스텀하게 다음과 같이 적용해서 사용 가능하다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; deepspeed
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; transformers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; AutoModelForCausalLM&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; GPTNeoXLayer

&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; deepspeed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnDevice&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dtype&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;float16&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; device&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;cuda&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AutoModelForCausalLM&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;EleutherAI/polyglot-ko-5.8b&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; torch_dtype&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;float16&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cache_dir&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/data/.cache&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; deepspeed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_inference&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    mp_size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    dtype&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;float16&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    injection_policy&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;GPTNeoXLayer&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;attention.dense&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mlp.dense_4h_to_h&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;module&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[sshpass]]></title><description><![CDATA[Sshpass…]]></description><link>https://sooftware.github.io/sshpass/</link><guid isPermaLink="false">https://sooftware.github.io/sshpass/</guid><pubDate>Sat, 13 May 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Sshpass&lt;/h2&gt;
&lt;p&gt;원격 서버에 접속하거나 파일을 주고 받을 때 &lt;code class=&quot;language-text&quot;&gt;ssh&lt;/code&gt;나 &lt;code class=&quot;language-text&quot;&gt;scp&lt;/code&gt; 명령어로 처리할 일이 많은데,
패스워드를 필요로 하는 원격 서버의 경우 매번 패스워드를 넣어줘야 하는 불편함이 있다.&lt;/p&gt;
&lt;p&gt;자주 쓰는 서버의 경우 쉘스크립트로 하나 정의해두고 &lt;code class=&quot;language-text&quot;&gt;./server.sh&lt;/code&gt; 이런 식으로 사용을 하곤 하는데,
매번 메모장에 있는 패스워드를 치기가 꽤 귀찮아서 방법을 찾았다.&lt;/p&gt;
&lt;h3&gt;Install&lt;/h3&gt;
&lt;p&gt;맥북에서는 homebrew를 이용하면 쉽게 설치가 가능하다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;brew install hudochenkov/sshpass/sshpass&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Usage&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;접속&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;sshpass -p $PASSWORD ssh -p $PORT $ID@$IP&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;파일 전송&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;sshpass -p $PASSWORD scp -r -P $PORT \
$LOCAL_PATH \
$SERVER_PATH&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Huggingface PEFT (Parameter-Efficient Fine-Tuning)]]></title><description><![CDATA[Huggingface PEFT (Parameter-Efficient Fine-Tuning) 허깅페이스에서 나온 PEFT라는 라이브러리인데 LoRA, Prefix Tuning, P-Tuing, Prompt Tuning…]]></description><link>https://sooftware.github.io/peft/</link><guid isPermaLink="false">https://sooftware.github.io/peft/</guid><pubDate>Fri, 31 Mar 2023 15:11:55 GMT</pubDate><content:encoded>&lt;h1&gt;Huggingface PEFT (Parameter-Efficient Fine-Tuning)&lt;/h1&gt;
&lt;p&gt;허깅페이스에서 나온 &lt;a href=&quot;https://github.com/huggingface/peft&quot;&gt;PEFT&lt;/a&gt;라는 라이브러리인데 &lt;a href=&quot;https://arxiv.org/pdf/2106.09685.pdf&quot;&gt;LoRA&lt;/a&gt;, &lt;a href=&quot;https://aclanthology.org/2021.acl-long.353/&quot;&gt;Prefix Tuning&lt;/a&gt;, &lt;a href=&quot;https://arxiv.org/pdf/2103.10385.pdf&quot;&gt;P-Tuing&lt;/a&gt;, &lt;a href=&quot;https://arxiv.org/pdf/2104.08691.pdf&quot;&gt;Prompt Tuning&lt;/a&gt;
과 같은 기법들을 쉽게 사용하도록 나온 라이브러리다. P-Tuning, Prefix Tuning, Prompt Tuning은 처음 나왔을때 직접 논문 보면서 구현해서 적용했었는데 이렇게 쉽게 가능하니 감회가 새롭다.&lt;/p&gt;
&lt;p&gt;특히 최근 각광받는 LoRA를 쉽게 사용 가능하다는 점에서 굉장히 좋다.&lt;/p&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; transformers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; AutoModelForCausalLM
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; peft &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; get_peft_config&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; get_peft_model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; LoraConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; TaskType
model_name_or_path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bigscience/mt0-large&quot;&lt;/span&gt;
tokenizer_name_or_path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bigscience/mt0-large&quot;&lt;/span&gt;

peft_config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; LoraConfig&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    task_type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;CAUSAL_LM&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; inference_mode&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lora_alpha&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lora_dropout&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AutoModelForCausalLM&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model_name_or_path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; get_peft_model&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; peft_config&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;print_trainable_parameters&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# output: trainable params: 2359296 || all params: 1231940608 || trainable%: 0.19151053100118282&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 코드로 PEFT 모델로 변경해준 뒤 사용하면 된다.&lt;br&gt;
그리고 모델을 저장하면 base_model 파라미터를 제외한 Adapter 부분만 저장이 된다.&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/huggingface/peft&quot;&gt;https://github.com/huggingface/peft&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[ast - literal_eval 에러 기록]]></title><description><![CDATA[ast - literal_eval 에러 기록 ast의 literal_eval…]]></description><link>https://sooftware.github.io/ast-error-record/</link><guid isPermaLink="false">https://sooftware.github.io/ast-error-record/</guid><pubDate>Sat, 25 Mar 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;ast - literal_eval 에러 기록&lt;/h1&gt;
&lt;p&gt;ast의 literal_eval을 사용하면 문자열 형태의 자료형을 파이썬 자료형으로 바꿔줄 수 있다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; ast &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; literal_eval
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; test_dict &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;{&apos;a&apos;: 1, &apos;b&apos;: 2}&quot;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; literal_eval&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;test_dict&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;a&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;b&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;오늘 &lt;code class=&quot;language-text&quot;&gt;ValueError: malformed node or string: &amp;lt;ast.Name object at 0x7f2a381c2fd0&gt;&lt;/code&gt; 이 에러가 났다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;{..., &apos;is_self&apos;:false, ...}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이런 구조였는데, 왜 에러가 나는지 몰랐는데 &lt;code class=&quot;language-text&quot;&gt;literal_eval&lt;/code&gt;말고 &lt;code class=&quot;language-text&quot;&gt;json.loads&lt;/code&gt;를 사용하면 에러 없이 동작한다.&lt;/p&gt;
&lt;p&gt;이유는 literal_eval과 json의 포맷이 달라서 그러는데 위 예시에서 false를 False로 수정해주면 literal_eval로도 동작한다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Docker - GPU 할당]]></title><description><![CDATA[Docker - GPU 할당 도커에서 GPU를 할당하는 방법]]></description><link>https://sooftware.github.io/docker-gpu/</link><guid isPermaLink="false">https://sooftware.github.io/docker-gpu/</guid><pubDate>Sat, 25 Mar 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Docker - GPU 할당&lt;/h1&gt;
&lt;p&gt;도커에서 GPU를 할당하는 방법&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker run -it --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=1,2,3 $IMAGE_NAME&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Docker - 공유 디렉토리 연결 (mount)]]></title><description><![CDATA[Docker - 공유 디렉토리 연결 (mount) 도커를 쓰다보면 코드상에서 뭔가를 저장한다거나 어떤 데이터를 읽어와야 한다던가 하는
상황이 있는데, 이때 공유 디렉토리를 연결해서 run하면 편하다. 나  옵션을 이용하면 쉽게 가능하다.]]></description><link>https://sooftware.github.io/docker-mount/</link><guid isPermaLink="false">https://sooftware.github.io/docker-mount/</guid><pubDate>Tue, 14 Mar 2023 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Docker - 공유 디렉토리 연결 (mount)&lt;/h1&gt;
&lt;p&gt;도커를 쓰다보면 코드상에서 뭔가를 저장한다거나 어떤 데이터를 읽어와야 한다던가 하는
상황이 있는데, 이때 공유 디렉토리를 연결해서 run하면 편하다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;-v&lt;/code&gt;나 &lt;code class=&quot;language-text&quot;&gt;-volume&lt;/code&gt; 옵션을 이용하면 쉽게 가능하다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker run -it -v $HOST_SYSTEM_DIR:$CONTAINER_DIR $IMAGE_NAME&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[2022 인공지능 그랜드 챌린지 (정책 지원 AI) 3위]]></title><description><![CDATA[2022 인공지능 그랜드 챌린지 - 정책지원 3위 2022 인공지능 그랜드 챌린지 (정책 지원 AI)에서…]]></description><link>https://sooftware.github.io/2022_ai_grand_challenge/</link><guid isPermaLink="false">https://sooftware.github.io/2022_ai_grand_challenge/</guid><pubDate>Fri, 30 Dec 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;2022 인공지능 그랜드 챌린지 - 정책지원 3위&lt;/h1&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/210176650-0297b98d-8cef-4a7b-b391-2700c9c00235.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;2022 인공지능 그랜드 챌린지 (정책 지원 AI)에서 3위를 차지했습니다. 🎉 🎉&lt;br&gt;
그랜드 챌린지는 몇 년째 이어져오고 있는 국내에서 가장 큰 인공지능 컴피티션입니다.&lt;br&gt;
정부에서 주관하는 대회로 대표적으로 인공지능 온라인 경진대회와 그랜드 챌린지가 있는데, 작년에 이어 올해도
두 대회 모두 참여하게 됐습니다. 결과는.. 작년과 동일하게 온라인 경진대회 1위, 그랜드 챌린지 3위로 마무리했습니다 (나아진게 없네요 😂)&lt;/p&gt;
&lt;p&gt;다만 나아진게 있다면, 작년에는 3위를 했지만 마지막 4단계 대회여서 오직 1위만이 사업화 지원금을 받을 수 있었지만,
올해는 첫 번째로 시행되는 태스크여서 총 6개의 우수팀을 선발해서 과학기술정보통신부 장관상 및 2년간 연 10억원의 사업화지원금을
지원받게 됩니다. 연 10억원씩 2번이니 20억원에 해당하는 큰 금액입니다. 🤑 🤑&lt;/p&gt;
&lt;p&gt;1위를 못한 점은 아쉽지만, 20억에 해당하는 사업화지원금을 얻게 되어서 회사에 도움이 됐기에 기쁜 마음입니다.&lt;/p&gt;
&lt;p&gt;해당 대회가 내년에도 열리게 되는데, 내년에는 꼭 1위를 해보겠습니다 :)&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Serving - Kernl]]></title><description><![CDATA[Sooftware Serving - Kernl ELS-RD (Lefebvre Dalloz Services) 라는 단체에서 Kernl 이라는 좋은
Inference Enginer을 내주었습니다! PyTorch 기반의 Transformer…]]></description><link>https://sooftware.github.io/kernl/</link><guid isPermaLink="false">https://sooftware.github.io/kernl/</guid><pubDate>Sun, 30 Oct 2022 15:11:55 GMT</pubDate><content:encoded>&lt;h1&gt;Sooftware Serving - Kernl&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ELS-RD&quot;&gt;ELS-RD (Lefebvre Dalloz Services)&lt;/a&gt; 라는 단체에서 &lt;a href=&quot;https://github.com/ELS-RD/kernl&quot;&gt;Kernl&lt;/a&gt; 이라는 좋은
Inference Enginer을 내주었습니다! PyTorch 기반의 Transformer 모델들의 인퍼런스를 최적화해주는 라이브러리입니다.
&lt;a href=&quot;https://openai.com/blog/triton/&quot;&gt;Open AI Triton&lt;/a&gt; 기반으로 짜여져 있다고 하네요.&lt;/p&gt;
&lt;img src=&quot;https://github.com/ELS-RD/kernl/raw/main/resources/images/speedup.png&quot; width=&quot;550&quot;&gt;
&lt;p&gt;위 그림을 보면, 상당히 빨라 보입니다. 많이 쓰이는 ONNX보다는 모든 상황에서 더 빠르고, TensorRT나 DeepSpeed와 비교했을 때는
상황에 따라 엎치락뒤치락 하는 것 같습니다.&lt;/p&gt;
&lt;p&gt;애증의 TensorRT라고 부를 정도로, 속도는 빠르지만 환경설정이 어렵기로 유명한데, 이 라이브러리가 적절한
대안이 됐으면 좋겠네요.&lt;/p&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; transformers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; AutoModel
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; kernl&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model_optimization &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; optimize_model

model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AutoModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model_name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
optimized_model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; optimize_model&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

inputs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;inference_mode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;amp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;autocast&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    outputs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; optimized_model&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;**&lt;/span&gt;inputs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위의 Usage를 보시다싶이, 사용법이 간단합니다.&lt;br&gt;
많이들 쓰시는 Huggingface의 Transformers와 쉽게 연동되는 점이 큰 강점인 것 같네요.&lt;br&gt;
또한 유저들이 편하게 커스터마이징 가능하도록 코드를 최대한 쉽고 짧게 짰다고 합니다.&lt;/p&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;pip install torch==1.12.1 -U --extra-index-url https://download.pytorch.org/whl/cu116
git clone https://github.com/ELS-RD/kernl &amp;amp;&amp;amp; cd kernl
pip install -e .&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;설치 커맨드입니다. 주의사항으로, 파이썬 3.9 이상의 버젼만 지원된다고 합니다.&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Kernl: &lt;a href=&quot;https://github.com/ELS-RD/kernl&quot;&gt;https://github.com/ELS-RD/kernl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ELS-RD: &lt;a href=&quot;https://github.com/ELS-RD&quot;&gt;https://github.com/ELS-RD&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Open AI Triton: &lt;a href=&quot;https://openai.com/blog/triton/&quot;&gt;https://openai.com/blog/triton/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[RECORD] 개인 운동 기록 - 2022.10.30]]></title><description><![CDATA[개인 운동 기록 - 2022.10.30 한 달하고 3주만의 기록이다. 안타깝게도, 수행능력은 이전 기록과 동일한 것 같다. 그래도 좋은 소식은
한 달동안 근육량은 유지한채, 지방만 3kg정도 빠졌다. 1년 반동안 멈췄던 운동을 다시 시작하면서…]]></description><link>https://sooftware.github.io/weight_training2/</link><guid isPermaLink="false">https://sooftware.github.io/weight_training2/</guid><pubDate>Sun, 30 Oct 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;개인 운동 기록 - 2022.10.30&lt;/h1&gt;
&lt;p&gt;한 달하고 3주만의 기록이다. 안타깝게도, 수행능력은 이전 기록과 동일한 것 같다. 그래도 좋은 소식은
한 달동안 근육량은 유지한채, 지방만 3kg정도 빠졌다. 1년 반동안 멈췄던 운동을 다시 시작하면서
9월까지 근육량 +2kg, 지방 -7kg 정도로 천천히 그래도 꾸준하게 살이 빠졌는데, 더 이상 빠지질 않아서
식단 조절을 조금 했다. 무조건 배고픈거 참아가며 안 먹는건 내 성향과 맞지 않아서
먹는 양은 유지하되, 깨끗한걸 최대한 먹기 위해 집 앞 Salady를 애용하고 있다.&lt;/p&gt;
&lt;img src=&quot;https://mblogthumb-phinf.pstatic.net/MjAyMTAzMTNfMTUz/MDAxNjE1NjIyMzA0NTA1.TIYcS3zIWDNuIOuugfT2KZ5HPOeVlb3pCnp8w3cd7DUg._ACGX6Pna2z6kMSPszUg1GCoTdu0I0csGdg-yUnwQn0g.JPEG.foxyland96/SE-03d1fcbe-7804-45da-a2ac-9898d01a0354.jpg?type=w800&quot; width=&quot;400&quot;&gt;
&lt;p&gt;그랬더니 한달만에 지방 -3kg가 되었다. 살 빼는건 먹는걸 조절하는게 제일인 것 같다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Serving - Huggingface Optimum]]></title><description><![CDATA[Sooftware Serving - Huggingface Optimum 허깅페이스에서 나온 Transformers의 Extension 라이브러리이다. 목적은 모델 학습 및 인퍼런스를 더욱 빠르게 해주기 위한 라이브러리이다. Exporting…]]></description><link>https://sooftware.github.io/huggingface_optimum/</link><guid isPermaLink="false">https://sooftware.github.io/huggingface_optimum/</guid><pubDate>Wed, 05 Oct 2022 15:11:55 GMT</pubDate><content:encoded>&lt;h1&gt;Sooftware Serving - Huggingface Optimum&lt;/h1&gt;
&lt;p&gt;허깅페이스에서 나온 Transformers의 Extension 라이브러리이다. 목적은 모델 학습 및 인퍼런스를 더욱 빠르게 해주기 위한 라이브러리이다.&lt;/p&gt;
&lt;h2&gt;Exporting Transformers models to ONNX&lt;/h2&gt;
&lt;p&gt;모델 서빙을 위해서는 많이들 Transformers 모델을 ONNX로 컨버팅하곤 한다.&lt;br&gt;
ONNX(Open Neural Network Exchange)는 쉽게 말하면, Tensorflow, PyTorch와 같이 서로 다른 딥러닝 프레임워크 환경에서 만들어진 모델들을
서로 호환해서 사용할 수 있도록 도와주는 오픈소스이다.&lt;/p&gt;
&lt;p&gt;원래 Transformers 모델을 ONNX로 모델로 컨버팅하는게 마냥 간단하지만은 않았는데, 이 Optimum 라이브러리로 아래 코드로 쉽게 컨버팅 가능해졌다.
아마 Optimum을 가장 많이 쓰게되는 이유일 것 같다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; optimum&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onnxruntime &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; ORTModelForSequenceClassification

pretrain_model_name_or_path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;pretrain_model_name_or_path&quot;&lt;/span&gt;
save_directory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;tmp/onnx/&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Load a model from transformers and export it to ONNX&lt;/span&gt;
ort_model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ORTModelForSequenceClassification&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pretrain_model_name_or_path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; from_transformers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Save the onnx model&lt;/span&gt;
ort_model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;save_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;save_directory&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Quantization&lt;/h2&gt;
&lt;p&gt;Model Quantization도 이 라이브러리로 쉽게 가능하다! Huggingface 만세!&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; optimum&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onnxruntime&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;configuration &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; AutoQuantizationConfig
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; optimum&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onnxruntime &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; ORTQuantizer

&lt;span class=&quot;token comment&quot;&gt;# Define the quantization methodology&lt;/span&gt;
qconfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AutoQuantizationConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;arm64&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;is_static&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; per_channel&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
quantizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ORTQuantizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ort_model&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Apply dynamic quantization on the model&lt;/span&gt;
quantizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;quantize&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;save_dir&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;save_directory&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; quantization_config&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;qconfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Example of how to load an ONNX Runtime model and generate predictions with Optimum 🤗:&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; optimum&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onnxruntime &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; ORTModelForSequenceClassification
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; transformers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; pipeline&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; AutoTokenizer

model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ORTModelForSequenceClassification&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;save_directory&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; file_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;model_quantized.onnx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
tokenizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AutoTokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;save_directory&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

cls_pipeline &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pipeline&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;text-classification&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; tokenizer&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;tokenizer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

results &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cls_pipeline&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;I love burritos!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Graph Optimization&lt;/h2&gt;
&lt;p&gt;Graph Optimization을 통해 모델 인퍼런스를 더욱 빠르게도 가능하다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; optimum&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onnxruntime &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; ORTModelForSequenceClassification&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ORTOptimizer

ort_model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ORTModelForSequenceClassification&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pretrain_model_name_or_path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; from_transformers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
optimizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ORTOptimizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ort_model&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Optimize the model&lt;/span&gt;
optimizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;optimize&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;save_dir&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;save_directory&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; optimization_config&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;optimization_config&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이렇게 라이브러리를 통해 간단하게, Quantization, Optimization이 가능해졌다. 정말 가뭄의 단비같은 라이브러리다.&lt;/p&gt;
&lt;h2&gt;Training&lt;/h2&gt;
&lt;p&gt;인퍼런스 용도 외에도, ONNX를 이용하여 학습에도 적용 가능하다고 한다. 개인적으로는 Transformers에서 제공하는 Trainer를 잘
사용하진 않는데, Transformers의 Trainer를 사용하는 코드라면 적용해보고 학습 속도를 비교해보고 싶다.&lt;/p&gt;
&lt;img width=&quot;440&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/42150335/193879406-6b86724b-98de-4bf0-8346-33cd497d82ac.png&quot;&gt;
&lt;h3&gt;Reference&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Optimum github: &lt;a href=&quot;https://github.com/huggingface/optimum&quot;&gt;https://github.com/huggingface/optimum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ONNX: &lt;a href=&quot;https://github.com/onnx/onnx&quot;&gt;https://github.com/onnx/onnx&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sooftware Serving - Terminology]]></title><description><![CDATA[Sooftware Serving - Terminology NLP…]]></description><link>https://sooftware.github.io/serving_term/</link><guid isPermaLink="false">https://sooftware.github.io/serving_term/</guid><pubDate>Tue, 04 Oct 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Sooftware Serving - Terminology&lt;/h1&gt;
&lt;p&gt;NLP 모델 서빙 관련해서 계속 마주치는 용어들을 정리하는 페이&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Load Balancer&lt;/code&gt;: 서버에 가해지는 부하(로드)를 분산시켜주는 장치 또는 기술.&lt;/li&gt;
&lt;/ul&gt;
&lt;img width=&quot;400&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/42150335/193868360-da7a4c4c-2a3b-4cd6-ac1b-ee9172451e5b.png&quot;&gt;  
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Load Balancing - Round Robin Method&lt;/code&gt;: 서버에 들어온 요청을 순서대로 돌아가며 배정하는 방식&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Load Balancing - Weighted Round Robin Method&lt;/code&gt;: 각 서버마다 가중치를 매기고 가중치가 높은 서버에 클라이언트 요청을 우선적으로 배분하는 방식&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Load Balancing - IP Hash Method&lt;/code&gt;: 클라이언트의 IP 주소를 특정 서버로 매핑하여 요청을 처리하는 방식&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Load Balancing - Least Connection Method&lt;/code&gt;: 요청이 들어온 시점에 가정 적은 연결상태를 보이는 서버에 우선적으로 트래픽을 배분하는 방식&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Load Balancing - Least Response Time Method&lt;/code&gt;: 서버의 현재 연결 상태와 응답시간을 모두 고려하는 방식. 가장 적은 연결 상태와 가장 짧은 응답시간을 보이는 서버에 우선적으로 배분&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Health Check&lt;/code&gt;: 로드밸런싱 서비스를 제공하는 다수의 서버의 상태를 점검하기 위해 사용되는 기술로, 서버의 상태를 주기적으로 체크하여&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;서버의 상태가 통신이 불가능할 경우 서버를 서비스에서 제외하여 서비스를 원활하게 제공하기 위해 이용되는 방법&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Stress Test&lt;/code&gt;:  어플리케이션에 각종 리소스(CPU, RAM, Disk 등)의 허용하는 한도를 넘어서서 비정상적인 높은 부하를 발생시켜보는 테스트.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;한도를 넘어서는 부하가 걸렸을 때의 버그 등을 찾기 위함&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Load Test&lt;/code&gt;: 적절한 부하를 발생시켜 통계적으로 의미있는 수치를 측정하는 테스트. 1. 장시간 서비스 가능 여부를 확인하는 신뢰성 테스트, 2. 성능 테스트 (Performance Test).&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;TPS (Transaction Per Second)&lt;/code&gt;: 초당 트랜잭션의 갯수. 서비스 성능의 기준.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Saturation Point&lt;/code&gt;: TPS가 더 이상 증가하지 않는 시점.&lt;/li&gt;
&lt;/ul&gt;
&lt;img width=&quot;400&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/42150335/193871571-f78af74b-eac1-4381-8dda-e55069a34054.png&quot;&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;WSGI (Web Server Gateway Interface)&lt;/code&gt;: Python 어플리케이션이 웹 서버와 통신하기 위한 인터페이스. 웹 서버에서의 요청을 파싱하여 Python 어플리케이션 쪽으로 넘기는 역할을 수행&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Uvicorn&lt;/code&gt;: uvloop 및 httptools를 사용하는 *ASGI Web Server
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ASGI (Asynchronous Server Gateway Interface)&lt;/code&gt;: 비동기 Python 웹 서버&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Asyncio&lt;/code&gt;:  Asyncio는 async / await 구문을 사용하여 비동기(Asynchronous) 코드를 작성하는 라이브러리. &lt;strong&gt;non-blocking&lt;/strong&gt;하게 처리함.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;uvloop&lt;/code&gt;: asyncio를 대체하기 위해 만들어진 라이브러리. Cython으로 작성되었음. 기타 Python 비동기 프레임워크보다 2배 이상 빠름.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Gunicorn&lt;/code&gt;: Python WSGI로 Web Server(Nginx)로부터 요청을 받으면 서버 어플리케이션으로 전달해주는 역할을 수행.&lt;/li&gt;
&lt;/ul&gt;
&lt;img width=&quot;500&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/42150335/193873850-f25635a4-6863-4da9-ad97-7fbcb67c91e6.png&quot;&gt;  
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;NGINX&lt;/code&gt;: 가벼우면서도 강력한 프로그램을 목표로 개발된 오픈소스 웹 서버 프로그램. Apache보다 동작이 단순하고, 전달자 역할만 하기 때문에 동시접속 처리에 특화되어 있다.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sooftware Serving - Triton Inference Server]]></title><description><![CDATA[Sooftware Serving - Triton Inference Server Triton Inference Server는 인공지능 모델의 인퍼런스를 도와주는 오픈소스 소프트웨어다. 다양한 프레임워크(TensorRT, TensorFlow…]]></description><link>https://sooftware.github.io/triton/</link><guid isPermaLink="false">https://sooftware.github.io/triton/</guid><pubDate>Tue, 20 Sep 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Sooftware Serving - Triton Inference Server&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Triton Inference Server는 인공지능 모델의 인퍼런스를 도와주는 오픈소스 소프트웨어다.&lt;/li&gt;
&lt;li&gt;다양한 프레임워크(TensorRT, TensorFlow, PyTorch ,ONNX, 등)를 지원한다.&lt;/li&gt;
&lt;li&gt;해당 내용은 &lt;a href=&quot;https://github.com/triton-inference-server/server/tree/main/docs&quot;&gt;Triton Inference Server Docs&lt;/a&gt; 를 공부하며 적은 내용으로,&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;대부분의 내용이 해당 문서와 유사합니다.&lt;/p&gt;
&lt;h2&gt;Quickstart&lt;/h2&gt;
&lt;p&gt;Triton 사용시에는 pre-built 된 &lt;a href=&quot;https://catalog.ngc.nvidia.com&quot;&gt;Docker image&lt;/a&gt;를 사용하는게 좋다.&lt;br&gt;
이번 Quickstart에서 다룰 내용:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creating a Model Repository&lt;/li&gt;
&lt;li&gt;Launching Triton&lt;/li&gt;
&lt;li&gt;Send an Inference Request&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Model Repository&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;가장 먼저 Model Repository를 구성해야 한다.&lt;/li&gt;
&lt;li&gt;Model Repository에는 체크포인트와 입출력 configuration 파일이 포함되어야 한다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;tritonserver --model-repository=경로&lt;/code&gt;와 같이 실행할 때 경로를 지정해준다.&lt;/li&gt;
&lt;li&gt;Model Repository 구조&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;model_repository/
    |
    |___model1/
    |     |___config.pbtxt
    |     |___version/
    |     |     |___model-files
    |     |___version/
    |     |     |___model-files
    |     |___...
    |___model2/
    |     |___config.pbtxt
    |     |___version/
    |     |     |___model-files
    |     |___version/
    |     |     |___model-files
    |     |___...
    |___...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Model Repository 주의할
&lt;ul&gt;
&lt;li&gt;모델명 폴더 아래에 버젼으로 된 폴더가 존재해야한다. (버젼은 반드시 INT여야 함)&lt;/li&gt;
&lt;li&gt;버젼 폴더 아래에 모델의 체크포인트 및 관련 파일이 위치한다.&lt;/li&gt;
&lt;li&gt;모델 체크포인트는 &lt;code class=&quot;language-text&quot;&gt;model.***&lt;/code&gt;여야 한다. (***은 bin 등 플랫폼에 따라 상이)점&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;code class=&quot;language-text&quot;&gt;config.pbtxt&lt;/code&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;모델 관련된 설정을 저장한다.&lt;/li&gt;
&lt;li&gt;트리톤 서버에서 이 정보를 기반으로 모델을 서빙한다.&lt;/li&gt;
&lt;li&gt;예시&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;name: &quot;simple&quot;
platform: &quot;tensorflow_graphdef&quot;
max_batch_size: 8
input [
  {
    name: &quot;INPUT0&quot;
    data_type: TYPE_INT32
    dims: [ 16 ]
  },
  {
    name: &quot;INPUT1&quot;
    data_type: TYPE_INT32
    dims: [ 16 ]
  }
]
output [
  {
    name: &quot;OUTPUT0&quot;
    data_type: TYPE_INT32
    dims: [ 16 ]
  },
  {
    name: &quot;OUTPUT1&quot;
    data_type: TYPE_INT32
    dims: [ 16 ]
  }
]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Parameters:
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;platform&lt;/code&gt;: 모델 플랫폼 (tensorrt, onns, pytorch, tensorflow 등)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;max_batch_size&lt;/code&gt;: 최대 배치사이즈&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;input (list[dict])&lt;/code&gt;: 입력 텐서들의 정보
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;name (str)&lt;/code&gt;: 입력 이름&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;data_type (enum)&lt;/code&gt;: 타입 정보
&lt;ul&gt;
&lt;li&gt;타입정보는 &lt;a href=&quot;https://github.com/triton-inference-server/server/blob/main/docs/model_configuration.md#datatypes&quot;&gt;https://github.com/triton-inference-server/server/blob/main/docs/model_configuration.md#datatypes&lt;/a&gt; 여기서 확인.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;dims (list[int])&lt;/code&gt;: 텐서 쉐입
&lt;ul&gt;
&lt;li&gt;다이내믹 차원인 경우는 -1로 기록.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;output&lt;/code&gt;: 출력 텐서들의 정보
&lt;ul&gt;
&lt;li&gt;입력텐서와 동일한 구조이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;유용한 기능들&lt;/h2&gt;
&lt;p&gt;(작성중)&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/triton-inference-server/server/tree/main/docs&quot;&gt;Triton Inference Server Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[RECORD] 개인 운동 기록 - 2022.09.07]]></title><description><![CDATA[개인 운동 기록 - 2022.09.07 21살에 해병대 면접에 붙기 위해 팔굽혀펴기를 연습하던 때부터 전역 후 몇년간은 맨몸운동 위주의 운동을 꾸준히 했었는데,
대학교…]]></description><link>https://sooftware.github.io/weight_training1/</link><guid isPermaLink="false">https://sooftware.github.io/weight_training1/</guid><pubDate>Wed, 07 Sep 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;개인 운동 기록 - 2022.09.07&lt;/h1&gt;
&lt;p&gt;21살에 해병대 면접에 붙기 위해 팔굽혀펴기를 연습하던 때부터 전역 후 몇년간은 맨몸운동 위주의 운동을 꾸준히 했었는데,
대학교 4학년때부터 학부연구생 인턴, 카카오브레인 인턴, 정규직 전환, 창업 등의 바빴던 일정 때문에
1년 정도를 운동에 손을 떼고 재택근무하며 배달음식을 먹고 다녔더니 약 15KG 이상이 확 쪄버렸었다.
구체적으로 비교해보진 않았지만, 운동을 안하면서 쪘으니 근육이 줄은걸 감안하면 지방은 훨씬 더 쪘을 것 같다.&lt;/p&gt;
&lt;p&gt;인생 최대 몸무게를 찍고 도저히 안되겠어서 작년 5월부터 다시 헬스장을 다니기 시작했다. 몇달간은
가다 안가다를 반복했지만, 언젠가부터는 주 4-5회 정도는 꾸준히 가고 있다.
짧은 기간 내에 살을 확 빼는거는 내 성향과 맞지 않아서 그냥 운동 꾸준히 하고, 집에서 혼자 먹던
맥주를 끊었다. 운동도 기존의 맨몸운동 위주에서 웨이트 트레이닝 위주의 운동으로 스타일을 바꿨다.&lt;/p&gt;
&lt;p&gt;웨이트 트레이닝 위주의 운동 덕인지, 맥주를 끊은 덕인지 모르겠지만 작년 5월과 비교해서 지방은 10kg 정도가 빠졌고,
근육은 3kg 정도가 늘었다. 워낙에 많이 쪘어서 그전 몸 상태로 돌아가려면 아직 더 빼야하지만, 이대로 꾸준히 운동한다면
내년 이맘때쯤은 한참 좋았던 대학생때의 몸상태로 돌아갈 수 있지 않을까 기대하고 있다.&lt;/p&gt;
&lt;p&gt;그런데 최근에 좀 막힌 느낌이 들어서 목표를 잡고 블로그에 개인 운동 기록을 주기적으로 해보려고 한다.
흔히들 목표로 잡는 3대 500 같은 경우 1RM(딱 한 번 들 수 있는 최대 무게)을 기준으로 하는데,
괜히 1RM 측정하다가 다칠까봐 5RM(5번 반복 가능한 최대 무게)을 기준으로 목표를 설정해볼까 한다.&lt;/p&gt;
&lt;h2&gt;현재 수행 능력&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;스쿼트 (Squat) - 5RM: 110kg&lt;/li&gt;
&lt;li&gt;데드리프트 (Deadlift) - 5RM: 130kg&lt;/li&gt;
&lt;li&gt;벤치 프레스 (Bench press) - 5RM: 90kg&lt;/li&gt;
&lt;li&gt;3대 5RM: 330kg&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;※ 데드리프트는 스트랩 있어야 함 😂&lt;/p&gt;
&lt;h2&gt;목표 수행 능력 (1차)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;스쿼트 (Squat) - 5RM: 130kg&lt;/li&gt;
&lt;li&gt;데드리프트 (Deadlift) - 5RM: 150kg&lt;/li&gt;
&lt;li&gt;벤치 프레스 (Bench press) - 5RM: 100kg&lt;/li&gt;
&lt;li&gt;3대 5RM: 380kg&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[2022 AI 온라인 경진대회 장관상 수상]]></title><description><![CDATA[2022 AI 온라인 경진대회 장관상 수상 2022 인공지능 경진대회 - 기계독해 태스크에서 1위를 차지하고, 사업화 부문에서 인정받으며
자연어 부문 1위를 했습니다! 상으로 과학기술정보통신부 장관상을 수상했습니다. 튜닙 소속으로 받은…]]></description><link>https://sooftware.github.io/2022_msit/</link><guid isPermaLink="false">https://sooftware.github.io/2022_msit/</guid><pubDate>Fri, 02 Sep 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;2022 AI 온라인 경진대회 장관상 수상&lt;/h1&gt;
&lt;p&gt;2022 인공지능 경진대회 - 기계독해 태스크에서 1위를 차지하고, 사업화 부문에서 인정받으며
자연어 부문 1위를 했습니다! 상으로 &lt;strong&gt;과학기술정보통신부 장관상을 수상&lt;/strong&gt;했습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/188196242-692821e1-e6f1-4649-a404-bfbae1983f37.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;튜닙 소속으로 받은 3번째 상(정보통신산업진흥원장상, 정보통신기획평가원장상, 과학기술정보통신부장관상)이자, 첫 장관상입니다!&lt;br&gt;
이번 인공지능 온라인 경진대회에 역대 최다팀인 526팀이 참가했다고 하는데, 그중 3팀만 받는 장관상을 수여하게 되어 대단히 영광스럽습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/188196293-fd51ee17-6b18-4198-a44a-1600a151af4d.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;점점 좋은 상을 받고 있으니, 다음에는 대통령상을 노려보겠습니다! 😎&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Mecab 설치 & 사용자 정의 사전 추가]]></title><description><![CDATA[Mecab 설치 & 사용자 정의 사전 추가 Mecab은 대표적인 형태소 분석기입니다. 한국어 형태소 분석기로 유명합니다만,
Mecab은 본래 일본의 Taku Kudo…]]></description><link>https://sooftware.github.io/mecab/</link><guid isPermaLink="false">https://sooftware.github.io/mecab/</guid><pubDate>Sat, 20 Aug 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Mecab 설치 &amp;#x26; 사용자 정의 사전 추가&lt;/h1&gt;
&lt;p&gt;Mecab은 대표적인 형태소 분석기입니다. 한국어 형태소 분석기로 유명합니다만,
Mecab은 본래 일본의 Taku Kudo라는 분이 알고리즘은 개발해서 일본어 형태소 분석기로 만들어졌습니다.
이 알고리즘에 한국어를 적용한 버젼이 여러분이 잘 아시는 Mecab입니다.&lt;/p&gt;
&lt;p&gt;근데 이 Mecab이 널리 사용되는데, 설치가 잘 되지 않기로 유명합니다. 특히 윈도우 환경을 쓰시는
분들중에 Mecab을 사용하시려는 분들이 꽤나 고생하시는 것으로 알고 있습니다.&lt;/p&gt;
&lt;p&gt;C++로 된 프로그램을 파이썬에 바인딩해서 사용하다보니, 아무래도 설치가 쉽지는 않습니다.&lt;/p&gt;
&lt;p&gt;그래서 개인적인 기록겸, Mecab 설치 커맨드와 Mecab에 사용자 정의 사전 추가하는 방법을 포스팅하려 합니다.&lt;/p&gt;
&lt;h2&gt;◾️ Mecab 설치 커맨드 (for Linux)&lt;/h2&gt;
&lt;p&gt;가장 쉽게 Mecab을 설치하는 방법은 아래 커맨드를 이용하는 겁니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ pip install -v python-mecab-ko==1.0.9&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/jonghwanhyeon/python-mecab-ko&quot;&gt;python-mecab-ko&lt;/a&gt; 는 mecab을 파이썬에 바인딩해놓은 패키지입니다.&lt;/p&gt;
&lt;p&gt;이 패키지 덕분에 mecab 설치가 한결 간편해졌는데, 1.0.10 버젼 이후로는 Mac OS 이외에는
빌드가 되지 않는 &lt;a href=&quot;https://github.com/jonghwanhyeon/python-mecab-ko/issues/5#issuecomment-913127321&quot;&gt;이슈&lt;/a&gt; 가 있어서
버젼을 낮춰서 설치하는 것을 권장드립니다.&lt;/p&gt;
&lt;p&gt;그냥 &lt;code class=&quot;language-text&quot;&gt;pip install -v python-mecab-ko&lt;/code&gt;로 설치시, &lt;code class=&quot;language-text&quot;&gt;pybind11::init(): factory function returned nullptr&lt;/code&gt;라는 에러가 발생한다고 하네요.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;But&lt;/strong&gt;, 버젼을 낮춰서 설치했는데도 &lt;code class=&quot;language-text&quot;&gt;TypeError: pybind11::init(): factory function returned nullptr&lt;/code&gt; 에러가 발생하는 경우가 있습니다.&lt;/p&gt;
&lt;p&gt;이런 경우는 아래 커맨드를 실행해주면 해결됩니다. (환경에 따라 아닐수도 있음)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ bash &amp;lt;(curl -s https://raw.githubusercontent.com/konlpy/konlpy/master/scripts/mecab.sh)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;📚 사용자 정의 사전 추가&lt;/h2&gt;
&lt;p&gt;Mecab에 사용자 정의 사전을 추가해야 하는 경우가 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; mecab
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; m &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mecab&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MeCab&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pos&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;쪽바리&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;쪽&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;MAG&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;바리&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;NNG&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위와 같이 &lt;code class=&quot;language-text&quot;&gt;쪽바리&lt;/code&gt;를 그냥 mecab으로 분절하게 되면, &lt;code class=&quot;language-text&quot;&gt;[(&apos;쪽&apos;, &apos;MAG&apos;), (&apos;바리&apos;, &apos;NNG&apos;)]&lt;/code&gt;와 같이 2개로 분절됩니다.
그런데 내가 &lt;code class=&quot;language-text&quot;&gt;쪽바리&lt;/code&gt;를 &lt;code class=&quot;language-text&quot;&gt;[(&apos;쪽바리&apos;, &apos;NNG&apos;)]&lt;/code&gt;와 같이 하나로 분절되게 하고 싶다면 어떻게 해야 할까요?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;쪽바리&lt;/code&gt;를 사용자 정의 사전에 추가하면 됩니다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;사용자 정의 사전에 추가하기 위해서는 mecab 폴더 위치를 찾아야 하는데, 환경마다 경로가 달라서
이 위치를 찾는데 애를 먹는 경우가 있습니다. 그래서 이를 좀 더 간단하게 하기 위해 아래 커맨드로
Mecab을 설치합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;wget https://bitbucket.org/eunjeon/mecab-ko/downloads/mecab-0.996-ko-0.9.2.tar.gz
tar xzvf mecab-0.996-ko-0.9.2.tar.gz
cd mecab-0.996-ko-0.9.2
./configure
make
sudo make install

wget https://bitbucket.org/eunjeon/mecab-ko-dic/downloads/mecab-ko-dic-2.1.1-20180720.tar.gz
tar xvfz mecab-ko-dic-2.1.1-20180720.tar.gz
cd mecab-ko-dic-2.1.1-20180720
./configure
make
sudo make install

pip install -v python-mecab-ko==1.0.9
bash &amp;lt;(curl -s https://raw.githubusercontent.com/konlpy/konlpy/master/scripts/mecab.sh)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 커맨드가 정상적으로 실행됐다면 &lt;code class=&quot;language-text&quot;&gt;mecab-0.996-ko-0.9.2&lt;/code&gt; 폴더가 생성되어 있을겁니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ cd mecab-0.996-ko-0.9.2/mecab-ko-dic-2.1.1-20180720&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 명령어를 통해 폴더를 이동해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;ls&lt;/code&gt; 명령어를 쳐보면 많은 파일과 폴더가 보일겁니다. 여기서 사용자 정의 사전 추가를 위해서는
&lt;code class=&quot;language-text&quot;&gt;user-dic/nnp.csv&lt;/code&gt;를 수정해줘야 합니다. 파일을 열어보면 다음 같은 형식으로 되어 있습다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;대우,,,,NNP,*,F,대우,*,*,*,*,*
구글,,,,NNP,*,T,구글,*,*,*,*,*&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;쪽바리&lt;/code&gt;를 하나로 잘리게 하려면 아래와 같이 추가해주면 됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;대우,,,,NNP,*,F,대우,*,*,*,*,*
구글,,,,NNP,*,T,구글,*,*,*,*,*
쪽바리,,,0,NNP,*,F,쪽바리,*,*,*,*,*&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;대우, 구글처럼 형식은 맞춰주되, 우선순위에 해당하는 4번째 컬럼은 0(최우선순위)으로 바꿔줍니다.&lt;/p&gt;
&lt;p&gt;그리고 나서는 다음 커맨드를 실행해주면 됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ mecab-ko-dic-2.1.1-20180720/tools/add-userdic.sh
$ make install&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;잘 설치가 됐다면 아래 파이썬 코드로 테스트해보면 아래와 같이 하나로 잘리는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; mecab
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; m &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mecab&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MeCab&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pos&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;쪽바리&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;쪽바리&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;NNP&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;+)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;./configure: line 1696: syntax error near unexpected token `mecab-ko-dic,&apos;
./configure: line 1696: `AM_INIT_AUTOMAKE(mecab-ko-dic, 2.0.0)&apos;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;에러 발생시&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;./autogen.sh
make
sudo make install&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jonghwanhyeon/python-mecab-ko&quot;&gt;python-mecab-ko&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jonghwanhyeon/python-mecab-ko/issues/15&quot;&gt;python-mecab-ko issue #15&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/hyunwoongko/kss/issues/26&quot;&gt;kss issue #26&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[N행시를 지어주는 인공지능이 있다?! TUNiBridge N행시 서비스!]]></title><description><![CDATA[N행시를 지어주는 인공지능이 있다?! TUNiBridge N행시 서비스! 한국 사람이라면 누구나 한 번쯤은 N행시를 만들어본 경험이 있을겁니다. 예능에서도 많이 등장하고, 회사에서, 군대에서, 혹은 연인 이름으로 N…]]></description><link>https://sooftware.github.io/nverse/</link><guid isPermaLink="false">https://sooftware.github.io/nverse/</guid><pubDate>Fri, 19 Aug 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;N행시를 지어주는 인공지능이 있다?! TUNiBridge N행시 서비스!&lt;/h1&gt;
&lt;p&gt;한국 사람이라면 누구나 한 번쯤은 N행시를 만들어본 경험이 있을겁니다.&lt;br&gt;
예능에서도 많이 등장하고, 회사에서, 군대에서, 혹은 연인 이름으로 N행시를 만들어서
웃고 떠들어본 경험들이 다들 있을 것 같습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/185188797-2c08552a-a5a0-4c08-b47a-0637a3a31ad8.png&quot; width=&quot;300&quot;&gt;
&lt;p&gt;무한도전에서 박명수님이 &lt;code class=&quot;language-text&quot;&gt;북아메리카&lt;/code&gt;로 5행시를 했을 때, 배꼽잡고 웃었던 기억이 있습니다 😁 😁&lt;br&gt;
이와 같이 센스 있는 N행시를 인공지능이 한다면 어떨까요?!&lt;/p&gt;
&lt;p&gt;이런 생각을 가지고 저희 튜닙에서 인공지능 기술을 이용해서 AI N행시 서비스를 만들었습니다!&lt;/p&gt;
&lt;p&gt;👉 링크: &lt;a href=&quot;https://tunibridge.ai/nverse&quot;&gt;https://tunibridge.ai/nverse&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;갑자기 콜 수가 너무 많아서 ‘어디서 공격하나?‘라고 저희 회사 사람들 모두 생각하고 있었는데,
알고보니 트위터쪽에서 바이럴을 탔습니다!!&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/185190085-73ae436b-eb06-4b00-8c00-0484adcf53fd.png&quot; width=&quot;350&quot;&gt;
&lt;p&gt;몇 시간만에 리트윗이 1만이 넘어가며 지금까지도 몇 초에 한 분씩 사용하고 있습니다.&lt;/p&gt;
&lt;p&gt;너무 많은 분들이 이용해주셔서 몇 시간 정도 서버가 다운이 되는 불상사가 있었지만,
서빙 팀원들이 고생해준 덕분에 지금은 원활하게 이용이 가능합니다! 😎&lt;/p&gt;
&lt;p&gt;N행시를 시작으로 앞으로 공개될 저희 서비스들이 모두 바이럴을 타서 흥했으면 좋겠습니다!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Coding - 좋은 코딩 습관 (네이밍)]]></title><description><![CDATA[Sooftware Coding - 좋은 코딩 습관 (네이밍) 깔끔한 코드를 짜기 위한 제가 생각하는 10가지 습관입니다. ※ 저의 개인적인 주관이 포함된 글입니다. 1. 변수, 클래스명에는 동사를 넣지 않는다 변수, 클래스명은 다음과 같이 count…]]></description><link>https://sooftware.github.io/coding-habit/</link><guid isPermaLink="false">https://sooftware.github.io/coding-habit/</guid><pubDate>Wed, 17 Aug 2022 17:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Sooftware Coding - 좋은 코딩 습관 (네이밍)&lt;/h1&gt;
&lt;p&gt;깔끔한 코드를 짜기 위한 제가 생각하는 10가지 습관입니다.&lt;br&gt;
※ 저의 개인적인 주관이 포함된 글입니다.&lt;/p&gt;
&lt;h3&gt;1. 변수, 클래스명에는 동사를 넣지 않는다&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;FeatureExtract&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;FeatureExtractor&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;work&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;worker&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;변수, 클래스명은 다음과 같이 count, num_workers, image, user … 등 숫자, ~을 하는 객체, ~한 여부 (bool) 등이기 때문에
동사보다는 명사가 가장 잘 어울린다고 생각합니다.&lt;/p&gt;
&lt;h3&gt;2.  함수명에는 동사를 넣는다&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;trainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;반면, 함수같은 경우는 ~을 하는 행동을 정의하는 것입니다. id를 받아오는 함수라고 하면, id()보다는
get_id()과 같이 ~하다라는 의미가 담긴 명명이 잘 어울릴 것입니다.&lt;/p&gt;
&lt;h3&gt;3. 변수명에 굳이 관사를 넣지 않는다.&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;a_cat&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;가장 좋은 변수명은 짧으면서도 효과적으로 의도를 전달하는 변수명입니다.&lt;br&gt;
굳이 관사를 넣음으로 인해 변수명이 길어질 필요가 없습니다.&lt;/p&gt;
&lt;p&gt;관사를 넣는다고 의도 전달이 더 명확하게 되는것도 아니기 때문에 변수명, 함수명, 클래스명에 대해서 특수한 경우를 제외하고는
굳이 관사를 넣어줄 필요는 거의 없다고 생각힙니다.&lt;/p&gt;
&lt;h3&gt;4. 변수명에 전치사는 최대한 생략한다.&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;the_number_of_worker&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;num_workers&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;우리나라 사람들이 많이 하는 실수라고 합니다. number_of_worker 등과 같이, 전치사를 많이 넣습니다.&lt;/p&gt;
&lt;p&gt;우리나라 말로 옮기자면, the_number_of_worker는 “worker의 수”입니다.&lt;/p&gt;
&lt;p&gt;하지만, 간단하게 의도만 표현하는데 굳이 문법을 맞춰줄 필요는 없습니다. “worker의 수”보다는 간결하게 “worker수”라는 표현인&lt;/p&gt;
&lt;p&gt;worker_num과 같은 표현이 더 간결하면서도 의도 전달에 부족하지 않을 것입니다. 참고로, 뭔가를 세거나 숫자를 표시하는 변수는 num_somethings 혹은 count_somethings (cnt_somethings) 와 같은 형식을 많이 사용합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Seq2seq
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sentence_to_id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; char2id&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;물론 위와 같이 “to”는 함수, 변수 등 여러모로 자주 쓰입니다. to는 짧으면서도 의도를 효과적으로 전달해주는 단어이기 때문입니다.&lt;/p&gt;
&lt;p&gt;이와 같이 전치사를 최대한 줄이지만, 전치사를 씀으로, 더 깔끔하고, 효과적으로 의도 전달이 된다면 안 쓸 이유는 없습니다.&lt;/p&gt;
&lt;p&gt;그리고 to 같은 경우는 2(two)와 발음의 유사성 때문에 char_to_id =&gt; char2id와 같이 많이 쓰입니다._to_라는 4개의 글자를 2라는 1개의 글자로 대체함으로써 더 짧은 네이밍이 된다는 장점도 있습니다.&lt;/p&gt;
&lt;h3&gt;5. 단수와 복수를 구분한다.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Example:: Python&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;items &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; item &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;우리나라 사람들이 많이들 신경쓰지 않는 부분이라고 합니다. 제가 굉장히 중요하게 생각하는 부분인데요,&lt;/p&gt;
&lt;p&gt;단수와 복수를 구분해놓으면 코드를 읽기가 굉장히 쉬워집니다.&lt;/p&gt;
&lt;p&gt;단수형이라면 어떤 값 혹은 객체가 하나인 자료형, 복수형이라면 여러 값 혹은 객체가 들어있는 자료형임을 짐작하게 합니다.&lt;/p&gt;
&lt;p&gt;실제로 다른 사람이 짠 코드를 볼 때, 단수형 복수형이 명확하게 구분된 코드와 구분이 되지 않은 코드를 읽어보면 그 차이를 선명하게 느낄 수 있습니다.&lt;/p&gt;
&lt;h3&gt;6. 사용하는 언어의 암묵적인 Rule을 지킨다.&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token literal-property property&quot;&gt;CamelCase&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Java
&lt;span class=&quot;token literal-property property&quot;&gt;snake_cake&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; c
&lt;span class=&quot;token literal-property property&quot;&gt;Hybrid&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; python&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;어떤 언어를 사용하게 되면, 대부분의 프로그래머들이 암묵적으로 지키는 Rule 혹은 언어에서 권장하는 형식 있습니다.&lt;/p&gt;
&lt;p&gt;프로그램의 실행이나 결과에는 반영되지 않지만, 다른 사람들이 코드를 더 읽기 쉽게 만들어주는 규칙입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/184926983-b7939920-db95-42db-87e1-df50c6bc0e9e.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;대표적으로 Java의 CamelCase가 있습니다. c언어나 파이썬은 camelCase와 snake_case를 섞어서 쓰곤 합니다.&lt;/p&gt;
&lt;p&gt;아래는 c언어에서 가장 많이 쓰이는 컨벤션이라고 합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Struct              TitleCase
Struct Members      lower_case or lowerCase

Enum                ETitleCase
Enum Members        ALL_CAPS or lowerCase

Public functions    pfx_TitleCase (pfx = two or three letter module prefix)
Private functions   TitleCase
Trivial variables   i,x,n,f etc...
Local variables     lower_case or lowerCase
Global variables    g_lowerCase or g_lower_case (searchable by g_ prefix)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;CamelCase Example&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;var: raiseValueError
var: sentenceToId&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;snake_case Example&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;var: raise_value_error
var: sentence_to_id&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;물론 위와 같은 사항들 모두 권장일 뿐, 꼭 지켜야 하는 것은 아닙니다만,
아무래도 많은 개발자들이 따르는 규칙을 따른다면 여러모로 편리한 점이 있는 것 같습니다.&lt;/p&gt;
&lt;h3&gt;7. 통상적으로 사용되는 변수명/규칙을 사용한다.&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;temp, obj, worker, num_somethings, count_somethings, flag, idx, is_condition, info, freq, token ... &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;어떤 사람의 코드를 보더라도 꼭 등장하는 변수명들이 있습니다.
temp, flag, obj 등등.. 어디서나 많이 보이는 변수명도 있고,
num_somethings, count_somethings, is_condition과 같이 일정 형식으로 많이 쓰이는 변수명도 있습니다.&lt;/p&gt;
&lt;p&gt;예를 들어 “워커의 수”라는 것을 변수명으로 만든다면 &lt;code class=&quot;language-text&quot;&gt;num_workers&lt;/code&gt;와 같은 형식을 많이 사용합니다.
한 프로젝트에 뭔가의 숫자를 담아두는 변수를 위와 같은 형식으로 통일해둔다면 코드 읽기가 많이 수월해집니다.&lt;/p&gt;
&lt;p&gt;특정 변수명들은 변수명만으로 어떤 역할을 할지를 예측할 수도 있고, 변수명의 형식을 보고 bool 타입일지, int 타입일지를 예측도 가능하게 해줍니다.&lt;/p&gt;
&lt;p&gt;자주 사용되는 변수명이나 형식 같은 경우는 어떤 분야인지에 따라서도 차이가 나기 때문에, 같은 분야의 여러 코드를 보게 되면 도움이 많이 됩니다.
예를 들어 인공지능 분야의 경우에는 인공지능을 &lt;code class=&quot;language-text&quot;&gt;model&lt;/code&gt;이라고 많이 표현하기 때문에, 이왕이면 변수명을 &lt;code class=&quot;language-text&quot;&gt;model&lt;/code&gt;로 만들어주면
코드를 파악 혹은 검색할 때 수월해집니다.&lt;/p&gt;
&lt;p&gt;요즘은 microsoft, ibm, google 등 세계적인 대기업들도 오픈소스를 공개하기 때문에, 세계적인 대기업들에서는 어떤 식으로 변수명을 구성하는지를 볼 수도 있습니다.&lt;/p&gt;
&lt;h3&gt;8. 상수는 모두 대문자로 표시해준다.&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; layer_size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; main_width &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;MAIN_WIDTH&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; main_height &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;768&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;MAIN_HEIGHT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;768&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;값이 변하지 않는 상수라면, 값이 변하지 않는다는 것을 표시해주는 것이 좋습니다.
제가 사용하는 언어들에서는 모두 위 규칙을 따르는 것 같은데, 혹시 본인이 사용하는 언어가
다른 규칙을 따른다면, 해당 규칙을 따라주시면 됩니다.&lt;/p&gt;
&lt;h3&gt;9. 로직이 끝나면 한 줄 띄어준다.&lt;/h3&gt;
&lt;p&gt;같은 함수 내에서라도, 분명 여러 로직이 있습니다.
변수를 선언하는 부분, 혹은 계산하는 부분이 있을 것이고,
for, while 문 같이 반복분을 도는 경우도 있을 것입니다.&lt;/p&gt;
&lt;p&gt;하나의 함수는 한 화면안에 모두 들어와야 된다라고 하며 모든 코드를 따닥따닥 붙여놓는 분들이 계십니다.&lt;/p&gt;
&lt;p&gt;분명 한 화면 안에 들어오는 함수가 좋은 함수지만, 이를 위해서 가독성을 포기해야 한다면,
저는 한 화면이 넘어가더라도 한 줄씩 띄어줌으로써 로직이 분리되는 코드를 지향합니다.&lt;/p&gt;
&lt;h3&gt;10. 코드에 규칙이 있어야 한다.&lt;/h3&gt;
&lt;p&gt;위의 9가지 규칙 다 안 지키더라도, 네이밍과 코드에는 꼭 일정한 규칙이 있어야 합니다.&lt;/p&gt;
&lt;p&gt;리스트는 뒤에 _list를 붙이다던지, class는 두 번째 글자만 대문자라던지,
어떤 규칙이던 규칙적이기만 하면 &lt;strong&gt;그나마&lt;/strong&gt; 괜찮습니다.&lt;/p&gt;
&lt;p&gt;최악은 모든 네이밍이 지멋대로이고, 어떤 규칙도 찾아볼 수 없다면, 그 코드는 아마
빠른 시일내에 다시 짜야될 가능성이 굉장히 높습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;이상으로 제가 생각하는 깔끔한 코드를 짜는 10가지 규칙이였습니다.
생각나는대로 작성해서 빠트린 부분이 있을수도 있습니다.&lt;/p&gt;
&lt;p&gt;깔끔한 코드를 짜기 위한 가장 좋은 방법은 역시 좋은 코드를 많이 보는 것 같습니다.&lt;/p&gt;
&lt;p&gt;요즘은 주요 대기업들에서도 오픈소스를 많이 공개하기 때문에, 깃허브를 조금만 뒤져보면 좋은 코드는 너무나 많이 있는 것 같습니다.&lt;/p&gt;
&lt;p&gt;위의 내용 모두 개인적인 견해인 점을 참고해주시면 감사하겠습니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Pandas - 다중 딕셔너리를 Pandas DataFrame으로!]]></title><description><![CDATA[Sooftware Pandas - 다중 딕셔너리를 Pandas DataFrame으로! 가끔 데이터를 요렇게 저렇게 정리하다가보면, 데이터를 멀티인덱싱(Multi-Indexing…]]></description><link>https://sooftware.github.io/multiple-dict-to-df/</link><guid isPermaLink="false">https://sooftware.github.io/multiple-dict-to-df/</guid><pubDate>Tue, 16 Aug 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Sooftware Pandas - 다중 딕셔너리를 Pandas DataFrame으로!&lt;/h1&gt;
&lt;p&gt;가끔 데이터를 요렇게 저렇게 정리하다가보면, 데이터를 멀티인덱싱(Multi-Indexing) 형식으로 정리해야
깔끔해지는 경우가 종종 있다. 예를 들면 아래와 같은 딕셔너리 형태의 데이터는 딕셔너리 형태로 놓고 보면 한 눈에
구조를 파악하기 쉽지 않다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1410&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;290&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;278&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;B&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;292&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;652&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1034&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;C&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;96&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1817&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;D&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;186&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;181&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1611&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;E&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;271&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;297&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1410&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;B&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1676&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;282&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;B&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;274&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;869&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;835&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;C&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;112&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1863&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;D&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;216&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;912&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;850&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;E&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;110&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;845&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1023&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;C&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1907&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;49&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;B&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1081&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;409&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;488&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;C&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;199&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1731&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;D&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;496&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;338&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1144&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;E&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;743&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;504&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;731&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;D&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;628&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1295&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;B&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1268&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;407&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;303&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;C&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;175&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;245&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1558&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;D&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1316&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;374&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;288&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;E&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1014&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;534&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;430&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 딕셔너리를 아래와 같은 형태로 보면 굉장히 보기 편해진다.&lt;/p&gt;
&lt;img width=&quot;169&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/42150335/184917567-d1445d88-229c-4397-b2d2-7170b10b222c.png&quot;&gt;
&lt;p&gt;종종 이렇게 데이터를 정리할 일이 필요한데, 개인적으로 딕셔너리를 DataFrame으로 변환하는 것을 선호해서 기록차
남긴다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; pandas &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; pd

data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1410&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;290&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;278&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;B&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;292&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;652&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1034&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;C&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;96&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1817&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;D&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;186&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;181&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1611&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;E&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;271&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;297&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1410&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;B&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1676&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;282&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;B&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;274&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;869&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;835&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;C&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;112&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1863&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;D&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;216&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;912&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;850&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;E&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;110&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;845&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1023&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;C&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1907&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;49&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;B&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1081&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;409&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;488&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;C&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;199&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1731&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;D&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;496&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;338&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1144&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;E&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;743&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;504&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;731&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;D&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;628&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1295&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;B&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1268&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;407&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;303&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;C&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;175&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;245&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1558&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;D&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1316&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;374&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;288&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token string&quot;&gt;&apos;E&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1014&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;534&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;430&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

df &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pd&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;DataFrame&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_dict&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; orient&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;index&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;stack&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to_frame&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
df &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pd&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;DataFrame&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;df&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;values&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tolist&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;df&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[마크다운으로 발표자료 만들기 (Marp for VS Code)]]></title><description><![CDATA[마크다운으로 발표자료 만들기 (Marp for VS Code) 저는 개인적으로 무언가를 정리할 때 텍스트 레벨에서 모든 편집이 가능한 마크다운(Markdown…]]></description><link>https://sooftware.github.io/marp/</link><guid isPermaLink="false">https://sooftware.github.io/marp/</guid><pubDate>Sat, 30 Jul 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;마크다운으로 발표자료 만들기 (Marp for VS Code)&lt;/h1&gt;
&lt;p&gt;저는 개인적으로 무언가를 정리할 때 텍스트 레벨에서 모든 편집이 가능한 마크다운(Markdown)을 선호합니다.
그래서 제 블로그 포스팅도 모두 마크다운으로 작성되어 있는데요, 가끔 제가 정리해둔 문서로 발표자료 형식으로
만들어야 할 때가 종종 있습니다. 사내 세미나라던지, 스터디라던지 등등..&lt;/p&gt;
&lt;p&gt;예전에는 PPT나 Keynote를 써서 하나하나 발표자료로 재구성하곤 했는데,
‘이 마크다운 형식을 쉽게 발표자료로 바꿀수는 없을까?‘라는 생각에 조금 찾아보니
역시나 개발된 프로그램이 있었습니다.&lt;/p&gt;
&lt;h2&gt;Marp (Markdown Presentation)&lt;/h2&gt;
&lt;img src=&quot;https://marp.app/assets/og-image.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;MARP는 위에 설명한대로 마크다운 형식의 파일을 쉽게 발표자료로 사용하게 해주는 프로그램입니다.
여러 IDE의 확장 프로그램으로 사용이 가능한데, 저는 VS Code를 이용해서 사용했습니다.&lt;/p&gt;
&lt;h3&gt;Marp Extension 설치&lt;/h3&gt;
&lt;img src=&quot;https://velog.velcdn.com/images%2Foen%2Fpost%2Facf19426-ee81-48f8-a727-2d769a2a670a%2Fimage.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;Vscode의 Extension 창에서 marp를 검색하면 쉽게 설치 가능합니다.&lt;/p&gt;
&lt;h3&gt;Usage&lt;/h3&gt;
&lt;p&gt;사용 예시로 아래와 같은 마크다운 파일이 있을때 적용해보겠습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;markdown&quot;&gt;&lt;pre class=&quot;language-markdown&quot;&gt;&lt;code class=&quot;language-markdown&quot;&gt;&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;#&lt;/span&gt; Streamlit&lt;/span&gt;

&lt;span class=&quot;token bold&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;token content&quot;&gt;&lt;span class=&quot;token italic&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token content&quot;&gt;The fastest way to build data apps in Python&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;**&lt;/span&gt;&lt;/span&gt;
  
![](&quot;https://streamlit.io/images/brand/streamlit-logo-secondary-colormark-darktext.svg&quot;)

&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; github repository: https://github.com/streamlit/streamlit
&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; tutorial: https://docs.streamlit.io/en/stable/getting_started.html

&lt;span class=&quot;token code-snippet code keyword&quot;&gt;`streamlit`&lt;/span&gt;는 파이썬 기반으로 손쉽게 웹 어플리케이션을 개발하는 오픈소스입니다. 웹에 대한 이해 없이도 간단한 파이썬 코드만으로 대부분의 웹 어플리케이션 구현이 가능합니다. 간단한 데이터 Visualization 혹은 인공지능 모델 시연 등 여러 분야에 활용될 수 있을 것 같습니다.

&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;##&lt;/span&gt; Installation&lt;/span&gt;

&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; Install command
$ pip install streamlit
$ streamlit hello&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위와 같은 마크다운 파일을 아래처럼 바꿔주면 됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;markdown&quot;&gt;&lt;pre class=&quot;language-markdown&quot;&gt;&lt;code class=&quot;language-markdown&quot;&gt;&lt;span class=&quot;token front-matter-block&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token front-matter yaml language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;marp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;#&lt;/span&gt; Streamlit&lt;/span&gt;

&lt;span class=&quot;token bold&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;token content&quot;&gt;&lt;span class=&quot;token italic&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token content&quot;&gt;The fastest way to build data apps in Python&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;*&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;**&lt;/span&gt;&lt;/span&gt;
  
![](&quot;https://streamlit.io/images/brand/streamlit-logo-secondary-colormark-darktext.svg&quot;)

&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; github repository: https://github.com/streamlit/streamlit
&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; tutorial: https://docs.streamlit.io/en/stable/getting_started.html
  
&lt;span class=&quot;token hr punctuation&quot;&gt;---&lt;/span&gt;

&lt;span class=&quot;token code-snippet code keyword&quot;&gt;`streamlit`&lt;/span&gt;는 파이썬 기반으로 손쉽게 웹 어플리케이션을 개발하는 오픈소스입니다. 웹에 대한 이해 없이도 간단한 파이썬 코드만으로 대부분의 웹 어플리케이션 구현이 가능합니다. 간단한 데이터 Visualization 혹은 인공지능 모델 시연 등 여러 분야에 활용될 수 있을 것 같습니다.

&lt;span class=&quot;token hr punctuation&quot;&gt;---&lt;/span&gt;

&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;##&lt;/span&gt; Installation&lt;/span&gt;

&lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; Install command
$ pip install streamlit
$ streamlit hello&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;맨 위에 아래 텍스트를 넣어주고, 페이지 구분을 &lt;code class=&quot;language-text&quot;&gt;---&lt;/code&gt;로 표시해주면 됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;---
marp: true
---&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위와 같이 바꿔주게 되면 다음과 같이 슬라이드를 미리 볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 571px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/59947a1c06619717d2babf1fca5d934e/503dd/marp-ex.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 172.99999999999997%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAjCAYAAACU9ioYAAAACXBIWXMAAAsTAAALEwEAmpwYAAACRklEQVRIx61Wi1KjMBT1/z9tXXVq1dW6aq0KFAgJJYGER87OvbidtvYxCnfm5DEkh8t9ctZ1Hbz3o4C4zpqm+fKA5LtkJG3b9oS7cuzSPtkipMFUFlEqsRQKhalOXjyqoe86pDLH5P4Jt7M5PqIUpLW1FnVdMypr0TQt/AbZ7gu2NHTOQsoMSkoIIRDHCaIwRBgGSJKY11oXX0yyu17bkLbWOmhjYHQBayuUtYe2HYzzvDauQ8H7bq8Jtgm9R5wkmL++Yf6R4iVUeElqzCKHp9jhcenwEPXzU1xD6Ba2Oaah96iqCqtCY2UBVXrkZbuGNC0y3c/KtExY1d1xwg1ffuK0nIxDfrhBeQz7hAnpU4uigNZ6EIjDGNOHDeXgGDiYej+VLacMxdHiMEhDGpq2hVQ58lVvWDLw6hNSKUipkOcrqDznvdZ0RqPQGlJKZJnk/O+Lg++QSYmryRR3f+4xvbllXE9vGBeXVzi/uMSv89+4vJpgcj3Fze0dz88vc75z/zDjYsIFllhpk6QphMgY9EaRZawZa6gUlnGMJEn5WSoE0lRw/u91yhA5mHqjeZmGUb3snFtX5qEgXzAhhUpZloNBdWHUT97qy/8TfIhTiOtgX/5us187pWtbbk6Lt3e8Lt7YFr36A8KGvENks8e/WC5jNu6A4tAndSoyBGGEjyBEEC4hMgnrari6OQk6Rz8Caw3pz2DxHuB5vsB7ECGIYmRqBV1amMqdBJ0j0gNdb9s5ZMvOn8BndIyeyxw2owc2hcnQFrqJf3lYueMl7riSAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;marp ex&quot;
        title=&quot;marp ex&quot;
        src=&quot;/static/59947a1c06619717d2babf1fca5d934e/503dd/marp-ex.png&quot;
        srcset=&quot;/static/59947a1c06619717d2babf1fca5d934e/0eb09/marp-ex.png 500w,
/static/59947a1c06619717d2babf1fca5d934e/503dd/marp-ex.png 571w&quot;
        sizes=&quot;(max-width: 571px) 100vw, 571px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Theme&lt;/h3&gt;
&lt;p&gt;위 발표자료가 조금 심심하게 느껴질 수 있습니다.
편리한 대신, 디테일하게 하나하나 조정하기는 어렵습니다만,
사전에 등록되어 있는 테마들을 이용해서 밋밋한 발표자료를 조금 개선할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;markdown&quot;&gt;&lt;pre class=&quot;language-markdown&quot;&gt;&lt;code class=&quot;language-markdown&quot;&gt;&lt;span class=&quot;token front-matter-block&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token front-matter yaml language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;marp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;theme&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; uncover&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위와 같이 &lt;code class=&quot;language-text&quot;&gt;theme: 테마명&lt;/code&gt;을 표시해주게 되면 해당 테마가 적용된 발표자료로 변환됩니다.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 565px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/0ae14b2629cce0f94fec4910e74607ad/a1277/marp-ex2.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 173.4%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAjCAYAAACU9ioYAAAACXBIWXMAAAsTAAALEwEAmpwYAAADVklEQVRIx61WiW7bOBD1/39QgSJtNr2CbrFFsUkc27Gty7Idx5dkSbYu6hVvZKqSL2y6FfBMihw+cjjzRm6laY48L5Blx+A455OEyKSfZeqibYuGeY7aJPYGEBw+RYG9PQ4IIZtWhIfg8/HTLa7e/YXb22+4vv6AN2/e4uvf/8hcfVONBiHdiuNs714uCxxnjKenITqdJ9zfP6LXG8B1n5GmSmx2u9Ke7xUhSejGauWj3zdkETEcWrCsEabTFximDct2YdsuDMPB42NPxtl2u314XiAc5CoJVemiyktoFzhXIq36u10q4Kn0SRt3yMj4mwhDw5ZdbWcMyx7DdaeI4xy5ArIcSPOyzU7cd1a/QyEMY9y7S3Sma7SnPrqzDQbzAJaXwPJTGF4C208FQy+Bv1OAKr0pNFTjhFt0rTE6potllCFMAS8usN7l8HZ51a62OZbbXAjDRCGIS2xihSgp9oRJhjgDTD/FKMhh+CnGQSYnG3pl396kMs/33jrBwEth7cf0+CQss6PFC85ShSJTUFmzPewXF8ZVVkiwWlG0RRCE2PwBhGFU3uEppfwOjrTMvNLaTNPjtsy9osrBOmhTSU+pUvRa/PX+ax5RCo8ZhbHIirplu1isMRpNMJnMpGWSE5SiM5qILA3DlnfTHMma2WwhJazFHyrkqTdAu92VQkBNcxHff/y4Q39gSP/u/lHmqGHq/eGhI++c40b0VAifn+cyQaHTuNPtizHBDXgCErDVY+Pxc9XnmtnLsjwhK7DvhzBNRxaM3Im4Qhd5BbqiPLS7sintWNZoQ7fv7toyttlEEpwqKIQOvw5GEG6rEkaXeCpGsx48Qq9vFNhT3wmldN3/FclTdkefgPrpjkpT7TtzquxrlCcULSfCXJb/34NeS65Ky9Th/wE5yCWJrV3Wl/ta6LWiZR73XFDkm3FGtxeDUidkcur3c4+eb667kDZlKVL48uUrbm4+4ebDZ7x/f4Orq2t8//7vEdlZwsMdmcjUNBXEBGefCqrb1tuThLrPS+b9zudLqSSsQFTMfLH674R1hby8LDHomzANB47tCkbOGKulhyiKX3eHJFyvN+KqbY2kLtLV5WItheTVhA0do1kEzqVY45/DpYQ91OslSGIHAWXz5/ATdsOPkIfYhJ8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;marp ex2&quot;
        title=&quot;marp ex2&quot;
        src=&quot;/static/0ae14b2629cce0f94fec4910e74607ad/a1277/marp-ex2.png&quot;
        srcset=&quot;/static/0ae14b2629cce0f94fec4910e74607ad/0eb09/marp-ex2.png 500w,
/static/0ae14b2629cce0f94fec4910e74607ad/a1277/marp-ex2.png 565w&quot;
        sizes=&quot;(max-width: 565px) 100vw, 565px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;발표자료로 변환&lt;/h2&gt;
&lt;img src=&quot;https://velog.velcdn.com/images%2Foen%2Fpost%2Fe14e1639-731a-4a4f-99c3-54c1b2f55ce1%2Fimage.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;이렇게 작성된 발표자료를 pdf 등의 형식으로 내보내려면 오른쪽 상단 2번째에 위치한 버튼(삼각형 2개)을 누르고
상단에 뜨는 ‘Export slide deck’ 버튼을 누르면 됩니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - 문장의 개체명을 분석해보자! 개체명 인식, Named Entity Recognition (NER)]]></title><description><![CDATA[Sooftware NLP - 문장의 개체명을 분석해보자! Named Entity Recognition (NER) NLP 기술을 이용하면 꽤나 정교한 텍스트 분석이 가능합니다. 텍스트 분석에서 빼놓으면 섭섭한 녀석이
개체명 인식(Named Entity…]]></description><link>https://sooftware.github.io/ner/</link><guid isPermaLink="false">https://sooftware.github.io/ner/</guid><pubDate>Fri, 22 Jul 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Sooftware NLP - 문장의 개체명을 분석해보자! Named Entity Recognition (NER)&lt;/h1&gt;
&lt;p&gt;NLP 기술을 이용하면 꽤나 정교한 텍스트 분석이 가능합니다. 텍스트 분석에서 빼놓으면 섭섭한 녀석이
개체명 인식(Named Entity Recognition, 이하 NER)입니다. 예를 들어 이런 분석이 필요하다고 생각해보겠습니다.
&lt;strong&gt;2021년에 나온 한국 소설에서 가장 많이 등장한 이름&lt;/strong&gt;을 찾는다고 해봅시다. (2021년에 출간된 한국 소설
데이터는 주어졌다고 생각합니다.) 그럼 이 주어진 말뭉치를 어떻게 분석해서 &lt;strong&gt;2021년에 나온 한국 소설에서 가장 많이 등장한 이름&lt;/strong&gt;을
알아낼 수 있을까요? 이럴 때 필요한게 개체명 인식(NER)입니다!&lt;/p&gt;
&lt;img width=&quot;450&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/42150335/180271967-da966f2e-273d-4110-8917-d52610b6ef79.png&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;출처: &lt;a href=&quot;https://demo.tunib.ai/text&quot;&gt;TUNiB’s Text Analytics Demo&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;위 이미지와 같이 인명, 나이, 날짜, 서비스 용어, 스포츠 단체 등을 자동으로 분석해주는 기술이 제공된다면,
위의 문제는 쉽게 해결 가능합니다. 이러한 기술을 NER이라고 부르며, 대표적인 NLP 문제이기도 합니다.
위에서 예시를 든 문제는 간단한 예시였지만, 대량의 텍스트 분석의 상당 부분을 자동화할 수 있습니다.&lt;/p&gt;
&lt;h2&gt;NER 시스템은 어떻게 만드나요?&lt;/h2&gt;
&lt;p&gt;그렇다면 이 NER 시스템은 어떻게 만들어질까요? 몇몇 entity들은 단순한 룰 기반으로도 잡을 수 있습니다.
예를 들어 요일, 방향, 개수, 신체 부위 등은 용어를 사전 형식으로 등록하거나, 정규식으로 충분히 잡을 수 있습니다.
하지만, 이름, 기관명 등은 단순히 룰 기반만으로는 잡기가 어렵습니다. 그렇기 때문에 최근의 NER 시스템은
인공지능 기반으로 만들어지고 있는 추세입니다.&lt;/p&gt;
&lt;h3&gt;데이터셋 구조&lt;/h3&gt;
&lt;p&gt;인공지능 기반 시스템을 만들기 위해서는 학습 데이터가 필요합니다. NER 시스템을 만들기 위해서는 먼저,
사전에 Entity들이 정의되어야 합니다. 정의가 되었다면, 아래 그림과 같이 텍스트와 해당 텍스트에서 Entity에 해당하는 부분에
Entity Number를 매핑시킨 형태의 데이터가 필요합니다.&lt;/p&gt;
&lt;img width=&quot;500&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/42150335/180276038-bba8cd83-2a70-4096-bb0c-c144f8e36bcb.png&quot;&gt;
&lt;p&gt;위 그림에서는 ‘이름’에 해당하는 Entity의 번호는 10번이므로, ‘해리 케인’, ‘손흥민’이 있는 부분에는 10번으로 매핑된 것을
확인할 수 있습니다. 이와 같이 학습 데이터를 모두 위와 같은 형식이 될 수 있도록 만든다면 NER 시스템을 학습할 수 있는
데이터셋이 됩니다.&lt;/p&gt;
&lt;h3&gt;모델링&lt;/h3&gt;
&lt;p&gt;다음으로 모델링을 살펴보겠습니다. 사실 모델링을 자세히 알기위해서는 Transformer, BERT 등의 사전 지식이 필요합니다.
이 포스팅에서는 해당 부분에 대해서는 스킵하겠습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/180276814-0d7aa44d-5adb-4e22-a338-f4a992e33bc5.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;위 그림과 같이 NER 모델의 학습은, 모든 토큰을 입력으로 넣고, 아웃풋 단계에서는 각 토큰이 어느 Entity에 해당하는지를
각각 분류시키고, 이에 대한 결과를 Cross Entropy Loss로 계산을 해서 모델을 학습하게 됩니다. 한국어로 예를 들자면,
‘해리 케인’을 이루는 [‘해’, ‘리’, ‘케’, ‘인’] 각 토큰들에 대해 Label을 10으로 모델에게 알려주는 방식입니다.&lt;/p&gt;
&lt;h2&gt;NER 시스템을 사용해보고 싶어요!&lt;/h2&gt;
&lt;p&gt;NER 시스템에 흥미가 좀 생기셨나요? 그렇다면 이 시스템을 좀 사용해보고 싶다, 혹은 직접 이 시스템을
이용해서 어떤 Product를 만들고 싶으신 분들이 계실 것 같습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;잘 만들어진 NER 시스템을 좀 사용해보고 싶어요! - &lt;a href=&quot;https://demo.tunib.ai/text&quot;&gt;TUNiB’s Text Analytics Demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;NER 시스템을 직접 시스템에 넣어보고 싶어요! - &lt;a href=&quot;https://kakaobrain.github.io/pororo/tagging/ner.html&quot;&gt;kakaobrain’s Pororo NER&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;NER 시스템을 사용해보고 싶으신 분들은 튜닙의 Text Analytics 데모를 사용해보시면 되시고,
직접 프로그램에 녹여내고 싶으신 분들은 카카오브레인에서 공개한 Pororo를 사용하시면 쉽게 프로토타입 정도의
NER 시스템을 프로그램에 반영하실 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; pororo &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Pororo

ner &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Pororo&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;task&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ner&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lang&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
ner&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;It was in midfield where Arsenal took control of the game, and that was mainly down to Thomas Partey and Mohamed Elneny.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;It&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;was&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;in&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;midfield&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;where&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Arsenal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ORG&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;took&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;control&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;of&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;the&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;game&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;,&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;and&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;that&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;was&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mainly&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;down&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;to&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Thomas Partey&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;PERSON&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;and&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Mohamed Elneny&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;PERSON&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
ner &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Pororo&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;task&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ner&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lang&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ko&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
ner&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;손흥민은 28세의 183 센티미터, 77 킬로그램이며, 현재 주급은 약 3억 원이다.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;손흥민&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;PERSON&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;은&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;28세&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;QUANTITY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;의&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;183 센티미터&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;QUANTITY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;,&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;77 킬로그램&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;QUANTITY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;이며,&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;현재&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;주급은&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;약 3억 원&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;QUANTITY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;이다.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# `apply_wsd` : for korean, you can use Word Sense Disambiguation module to get more specific tag&lt;/span&gt;
ner&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;손흥민은 28세의 183 센티미터, 77 킬로그램이며, 현재 주급은 약 3억 원이다.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; apply_wsd&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;손흥민&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;PERSON&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;은&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;28세&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;AGE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;의&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;183 센티미터&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;LENGTH/DISTANCE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;,&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;77 킬로그램&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;WEIGHT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;이며,&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;현재&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;주급은&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;약 3억 원&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;MONEY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;이다.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
ner &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Pororo&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;task&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ner&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lang&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zh&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
ner&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;毛泽东（1893年12月26日－1976年9月9日），字润之，湖南湘潭人。中华民国大陆时期、中国共产党和中华人民共和国的重要政治家、经济家、军事家、战略家、外交家和诗人。&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;毛泽东&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;PERSON&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;（&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;1893年12月26日－1976年9月9日&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;DATE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;）&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;，&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;字润之&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;，&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;湖南&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GPE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;湘潭&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GPE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;人&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;。&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;中华民国大陆时期&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GPE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;、&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;中国共产党&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ORG&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;和&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;中华人民共和国&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GPE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;的&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;重&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;要&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;政&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;治&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;家&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;、&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;经&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;济&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;家&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;、&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;军&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;事&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;家&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;、&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;战&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;略&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;家&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;、&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;外&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;交&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;家&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;和&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;诗&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;人&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;。&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
ner &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Pororo&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;task&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ner&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lang&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ja&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
ner&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;豊臣 秀吉、または羽柴 秀吉は、戦国時代から安土桃山時代にかけての武将、大名。天下人、武家関白、太閤。三英傑の一人。&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;豊臣秀吉&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;PERSON&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;、&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;または&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;羽柴秀吉&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;PERSON&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;は&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;、&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;戦国時代&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;DATE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;から&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;安土桃山時代&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;DATE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;にかけて&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;の&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;武将&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;、&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;大名&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;。&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;天下&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;人&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;、&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;武家&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;関白&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;、太閤&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;。&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;三&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;英&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;傑&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;の&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;一&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;人&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;。&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;O&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - 혐오는 이제 그만! St. Patrick]]></title><description><![CDATA[혐오는 이제 그만! St. Patrick…]]></description><link>https://sooftware.github.io/st-patrick/</link><guid isPermaLink="false">https://sooftware.github.io/st-patrick/</guid><pubDate>Sat, 16 Jul 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;혐오는 이제 그만! St. Patrick&lt;/h1&gt;
&lt;p&gt;남녀간의 성혐오, 게이, 레즈비언 등의 성소수자에 대한 혐오, 특정 종교에 대한 혐오 등
요즘 한국 사회는 ‘혐오의 시대’라는 말이 어울리는 것 같습니다. 어쩌면 이런 혐오가 항상 존재했지만
인터넷, 스마트폰이 발달이 충분히 돼서 더욱 대두되는 문제일수도 있을 것 같습니다.
요즘은 페이스북, 유튜브, 뉴스 기사 등 댓글창을 보면 꼭 특정 집단에 대해 차별적이고 혐오적인 발언들을
많이 볼 수 있는 것 같습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/179356677-9c6f48b4-edee-42ca-8046-3eac49be0c95.png&quot; width=&quot;400&quot;&gt;
&lt;h3&gt;그렇다면 이런 혐오 댓글, 채팅들을 자동으로 필터링할수는 없을까요?&lt;/h3&gt;
&lt;p&gt;자동으로 필터링해주는 기술을 가장 접하기 쉬운 경우가 게임 채팅이 아닐까 싶습니다.
다들 게임하시다가 상대방의 채팅 혹은 내 채팅이 일부 가려져서 보인 경험이 있을겁니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;야 이 씨발새끼야 →  야 이 ** **야&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;하지만 적어도 현재까지의 게임 채팅 필터링의 경우, 단순히 ‘혐오 사전’을 구축하고 이를 적용해서
혐오 사전에 포함된 표현이 있는 경우 필터링하는 룰 기반의 방식을 사용하고 있습니다.&lt;/p&gt;
&lt;p&gt;그래서 아래와 같은 의도하지 않은 필터링이 적용될 때가 있습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;이게 시발점이 될 거 같아 → 이게 **점이 될 거 같아&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;바로 위의 예시처럼, 단순히 룰 기반으로는 이 문제를 해결하기 어렵습니다. 그렇다고 모든 채팅을
사람이 일일이 보면서 체크할 수도 없는 노릇이죠. 그래서 현재 기준으로 이 문제를 풀기 가장 좋은 방법은
인공지능을 이용하는 방법일 것 같습니다. 룰 기반보다는 유연하게 대처가 가능하면서도,
사람이 일일이 대응하는것보다 훨씬 경제적입니다. 물론, 사람보다 정확성 면에서는 떨어지겠지만요.&lt;/p&gt;
&lt;h3&gt;그럼 인공지능을 쓰면 문제가 해결되는거네요?&lt;/h3&gt;
&lt;p&gt;항상 그렇듯, 인공지능은 절대 100%라는 것을 보장하지 않습니다. 또한 인공지능은
가르친대로 일을 수행하기 때문에 인공지능을 &lt;strong&gt;잘&lt;/strong&gt; 가르쳐야합니다. 그렇다면 잘 가르치려면
어떻게 해야할까요? 혐오 표현에 대한 정확한 정의와 학습 데이터의 일관성, 다양한 케이스의 데이터가 필요할 것 같습니다.
하지만, 혐오에 대한 정확한 정의와, 학습 데이터의 일관성, 다양한 케이스의 데이터 모두 하나같이
쉽지 않습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;나는 가영이가 머리 풀면 섹시하더라&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;나는 *** 대통령이 일을 잘 한건지 모르겠어.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;여러분은 위에 문장이 어떻게 느껴지시나요? 성희롱/정치 성향 혐오로 보이시나요? 아니면
단순한 개인의견으로 보이시나요?&lt;/p&gt;
&lt;p&gt;누군가는 위에 예시를 혐오로 느끼고, 누군가는 개인의견 정도로 넘어갈 수 있을 것 같습니다.
이처럼 이 ‘혐오’라는게 무짜르듯이 딱 잘라지지 않고, 개인마다 모두 의견이 다르기 때문에
이를 혐오다 / 아니다로 단순히 이진 분류로 정의하기에는 다소 어려운 것 같습니다.&lt;/p&gt;
&lt;h3&gt;St. Patrick&lt;/h3&gt;
&lt;p&gt;그래서 저희 팀에서는 이 혐오 문제를 혐오다 / 아니다로 문제를 정의하기 보다는 보다 더
세분화해서 구분했습니다.&lt;/p&gt;
&lt;img width=&quot;279&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/42150335/179357591-4d476555-2a80-4b23-b4a1-7dee3e6453d8.png&quot;&gt;
&lt;p&gt;[없음(혐오 없음), 주의(혐오 가능성 있음), 명백(혐오 가능성 높음), 심각(혐오 심각)]와 같이 4단계로 구분했습니다.
또한 혐오 표현의 종류를 [욕설, 모욕, 폭력위협/범죄조장, 외설, 성혐오, 연령차별, 인종 차별/지역혐오, 장애인 혐오, 종교 혐오, 정치 성향 혐오, 직업 혐오] 11개로
정의했습니다.&lt;/p&gt;
&lt;img width=&quot;550&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/42150335/179357901-fb930252-c98a-4f57-87c0-40b57e3eba0d.png&quot;&gt;
&lt;p&gt;위는 실제로 St. Patrick 데모입니다. 정의된 11개의 혐오에 대해서 0-3의 Likert 척도로 예측하며,
혐오 표현 부분에 대해서 하이라이팅을 해주고 있습니다.&lt;/p&gt;
&lt;p&gt;아직 St. Patrick이 성능이 아주 우수하다! 라고 말하기에는 부족한 면이 있지만, 올해 4월에
v0.1 공개를 시작으로 현재 v0.3.3까지 차근차근 꾸준히 성능을 개선해나가며 버젼업을 하고 있습니다.
또한 이번 포스팅에서는 설명을 생략했지만, 주민번호, 전화번호, 주소 등의 개인 정보도 아래와 같이 잡아주는
기능이 탑재되어 있습니다.&lt;/p&gt;
&lt;img width=&quot;550&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/42150335/179358084-18e225dd-957f-4ce1-9e87-3805016f7a59.png&quot;&gt;
&lt;p&gt;이 외에도, 더 다양한 기능 제공을 위해 연구/개발 중이며, 빠른 시일내에 추가 공개될 예정이니 &lt;em&gt;&lt;strong&gt;&lt;a href=&quot;https://demo.tunib.ai/safety/kor&quot;&gt;[St. Patrick 링크]&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt; 많은 사용 부탁드리며,
사용관련해서 피드백 혹은 문의사항이 있는 경우, &lt;a href=&quot;mailto:kaki.ai@tunib.ai&quot;&gt;kaki.ai@tunib.ai&lt;/a&gt;로 연락주시면 감사하겠습니다 :)&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - 한국어 사전학습 모델 (Korean Pre-trained Language Model)]]></title><description><![CDATA[한국어 사전학습 모델 (Korean Pre-trained Language Model) 공개된 한국어 사전학습 모델을 기록합니다. 크게 아래 3개의 모델 계열로 구분했으며, 모델 사이즈는 정확하지 않을 수 있습니다. Encoder Model (BERT…]]></description><link>https://sooftware.github.io/korean-plm/</link><guid isPermaLink="false">https://sooftware.github.io/korean-plm/</guid><pubDate>Tue, 12 Jul 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;한국어 사전학습 모델 (Korean Pre-trained Language Model)&lt;/h1&gt;
&lt;p&gt;공개된 한국어 사전학습 모델을 기록합니다. 크게 아래 3개의 모델 계열로 구분했으며, 모델 사이즈는 정확하지 않을 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Encoder Model (BERT 계열)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Decoder Model (GPT 계열)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Encoder-Decoder Model (Seq2seq 계열)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Encoder Model (BERT 계열)&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;center&quot;&gt;Model Name&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;Size&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;Link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;LASSL BERT&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Small (10M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/lassl/bert-ko-small&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;LASSL RoBERTa&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Small (10M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/lassl/roberta-ko-small&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;TUNiB ELECTRA (Ko)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Small (10M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/tunib/electra-ko-small&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;TUNiB ELECTRA (Ko-En)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Small (10M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/tunib/electra-ko-en-small&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KoELECTRA&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Small (10M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/monologg/koelectra-small-v3-discriminator&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KcELECTRA&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Small (10M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/beomi/kcelectra-v2022-dev&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;Soongsil-BERT&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Small (10M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/jason9693/soongsil-bert-small&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;Ko-CHAR-ELECTRA&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Small (10M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/monologg/kocharelectra-small-discriminator&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;Distill-KoBERT&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;30M&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/monologg/kocharelectra-base-discriminator&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KoBERT&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/skt/kobert-base-v1&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KorBERT&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://aiopen.etri.re.kr/service_dataset.php&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;HanBERT&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/monologg/HanBert-Transformers&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KcBERT&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/beomi/kcbert-base&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;Soongsil-BERT&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/jason9693/soongsil-bert-base&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KLUE-RoBERTa&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/klue/roberta-base&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KoELECTRA&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/monologg/koelectra-base-v3-discriminator&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KcELECTRA&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/beomi/KcELECTRA-base&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;TUNiB-ELECTRA (Ko)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/tunib/electra-ko-base&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;TUNiB-ELECTRA (Ko-En)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/tunib/electra-ko-en-base&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;LMKor Albert&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/kykim/albert-kor-base&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;LMKor Bert&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/kykim/bert-kor-base&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;LMKor Funnel&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/kykim/funnel-kor-base&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;LMKor ELECTRA&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/kykim/electra-kor-base&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KalBERT&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/MrBananaHuman/KalBert&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;LASSL BERT&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/lassl/bert-ko-base&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KoBigBird&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/monologg/kobigbird-bert-base&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;Ko-CHAR-BERT&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/MrBananaHuman/KoreanCharacterBert&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;Ko-CHAR-ELECTRA&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/monologg/kocharelectra-base-discriminator&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;BrainSBERT&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/hyunwoongko/brainsbert-base&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KPFBERT&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/jinmang2/kpfbert&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KcBERT&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Large (340M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/beomi/kcbert-large&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KLUE-RoBERTa&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Large (340M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/klue/roberta-large&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Decoder Model (GPT 계열)&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;center&quot;&gt;Model Name&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;Size&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;Link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;LASSL GPT2&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Small (20M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/lassl/gpt2-ko-small&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;LMKor KoGPT2&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/kykim/gpt3-kor-small_based_on_gpt2&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;SKT KoGPT2&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (110M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/skt/kogpt2-base-v2&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;SKT KoGPT Trinity&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;1.2B&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/skt/ko-gpt-trinity-1.2B-v0.5&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KakaoBrain KoGPT&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;6B&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/kakaobrain/kogpt&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Encoder-Decoder Model (Seq2seq 계열)&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;center&quot;&gt;Model Name&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;Size&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;Link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;Cosmoquester BART&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Mini (13M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/cosmoquester/bart-ko-mini&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KE-T5 (Ko-En)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Small (60M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/KETI-AIR/ke-t5-small&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KE-T5 (Ko)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Small (60M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/KETI-AIR/ke-t5-small-ko&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;LMKor T5&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Small (60M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/kykim/t5-kor-small&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;Cosmoquester BART&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Small (40M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/cosmoquester/bart-ko-small&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;LMKor BERT Shared&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (130M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/kykim/bertshared-kor-base&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;SKT KoBART&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (130M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/gogamza/kobart-base-v2&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;Cosmoquester BART&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (130M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/gogamza/kobart-base-v2&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KcT5&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (220M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/beomi/KcT5-dev&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KE-T5 (Ko-En)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (220M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/KETI-AIR/ke-t5-base&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KE-T5 (Ko)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (220M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/KETI-AIR/ke-t5-basko&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;Asian BART (Ko)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (360M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;hyunwoongko/asian-bart-ko&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;pko-t5 (Ko)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (250M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/paust/pko-t5-base&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;Wisenut KoT5 (Ko)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Base (220M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/wisenut-research/KoT5#usage&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;mBART&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Large (610M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/facebook/mbart-large-50&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KE-T5 (Ko-En)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Large (770M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/KETI-AIR/ke-t5-large&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;KE-T5 (Ko)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Large (770M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/KETI-AIR/ke-t5-large-ko&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;pko-t5 (Ko)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Large (800M)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;https://huggingface.co/paust/pko-t5-large&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content:encoded></item><item><title><![CDATA[2022 AI 온라인 경진대회 1위]]></title><description><![CDATA[2022 AI 온라인 경진대회 1위 2022 인공지능 경진대회 - 기계독해 태스크에서 1위를 차지했습니다. 🎉 🎉 작년에는 제가 모든 리딩 및 코딩을 담당했는데, 이번에는…]]></description><link>https://sooftware.github.io/2022_ai_online_competition/</link><guid isPermaLink="false">https://sooftware.github.io/2022_ai_online_competition/</guid><pubDate>Fri, 24 Jun 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;2022 AI 온라인 경진대회 1위&lt;/h1&gt;
&lt;img src=&quot;https://cdn.eachj.co.kr/news/photo/202205/6129_10631_1030.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;2022 인공지능 경진대회 - 기계독해 태스크에서 1위를 차지했습니다. 🎉 🎉&lt;br&gt;
작년에는 제가 모든 리딩 및 코딩을 담당했는데, 이번에는 4명의 인턴분들이 코딩과 진행을 담당하고, 저는 리딩과 입코딩을 담당해서 진행했습니다.
작년에 이어서 두 해 연속 1위를 기록했다는 점에서 의미가 있는 것 같습니다. 😁&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/179344840-3c8ba535-3e1c-46a4-b73f-3931c52b439d.png&quot; width=&quot;400&quot;&gt;
&lt;div class=&quot;gatsby-resp-iframe-wrapper&quot; style=&quot;padding-bottom: 56.25%; position: relative; height: 0; overflow: hidden; margin-bottom: 1rem&quot; &gt; &lt;iframe src=&quot;https://www.youtube.com/embed/jYmUxs4vfKs&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot; style=&quot; position: absolute; top: 0; left: 0; width: 100%; height: 100%; &quot;&gt;&lt;/iframe&gt; &lt;/div&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Huggingface Datasets Methods]]></title><description><![CDATA[Huggingface Datasets Methods 자주 사용하는 허깅페이스 datasets의 메서드를 정리합니다. load_datasets 허깅페이스 서버에 올라가 있는 데이터셋을 다운 받을 때 사용하는 메서드 save_to_disk…]]></description><link>https://sooftware.github.io/datasets/</link><guid isPermaLink="false">https://sooftware.github.io/datasets/</guid><pubDate>Thu, 17 Feb 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Huggingface Datasets Methods&lt;/h1&gt;
&lt;p&gt;자주 사용하는 허깅페이스 datasets의 메서드를 정리합니다.&lt;/p&gt;
&lt;h2&gt;load_datasets&lt;/h2&gt;
&lt;p&gt;허깅페이스 서버에 올라가 있는 데이터셋을 다운 받을 때 사용하는 메서드&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; datasets
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; dataset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; datasets&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;load_dataset&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;klue&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; dataset
DatasetDict&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    train&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Dataset&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        features&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;guid&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;source&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sentence1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sentence2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;labels&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        num_rows&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;11668&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    validation&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Dataset&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        features&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;guid&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;source&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sentence1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sentence2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;labels&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        num_rows&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;519&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;save_to_disk&lt;/h2&gt;
&lt;p&gt;DatasetDict Object를 디스크에 저장하는 메서드&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; datasets
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; dataset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; datasets&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;load_dataset&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;klue&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; dataset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;save_to_disk&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;test&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;load_from_disk&lt;/h2&gt;
&lt;p&gt;위의 &lt;code class=&quot;language-text&quot;&gt;save_to_disk&lt;/code&gt;로 저장한 파일을 이용해서 DatasetDict로 읽어오는 메서드&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; datasets
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; dataset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; datasets&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;load_dataset&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;klue&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; dataset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;save_to_disk&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;path/of/my/dataset/directory&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; reloaded_encoded_dataset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; datasets&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;load_from_disk&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;path/of/my/dataset/directory&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;DatasetDict Constructor&lt;/h2&gt;
&lt;p&gt;Dictionary를 바로 DatasetDict Object로 바꿔주는 방법&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; datasets &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; DatasetDict
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; dataset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; DatasetDict&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;    &lt;span class=&quot;token string&quot;&gt;&quot;train&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;        &lt;span class=&quot;token string&quot;&gt;&quot;test1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;        &lt;span class=&quot;token string&quot;&gt;&quot;test2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;        &lt;span class=&quot;token string&quot;&gt;&quot;test3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;    &lt;span class=&quot;token string&quot;&gt;&quot;validation&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;        &lt;span class=&quot;token string&quot;&gt;&quot;test1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;        &lt;span class=&quot;token string&quot;&gt;&quot;test2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;        &lt;span class=&quot;token string&quot;&gt;&quot;test3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;    &lt;span class=&quot;token string&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;        &lt;span class=&quot;token string&quot;&gt;&quot;test1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;        &lt;span class=&quot;token string&quot;&gt;&quot;test2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;        &lt;span class=&quot;token string&quot;&gt;&quot;test3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; dataset
DatasetDict&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    train&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;test1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;test2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;test3&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    validation&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;test1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;test2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;test3&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    test&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;test1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;test2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;test3&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;from_json&lt;/h2&gt;
&lt;p&gt;Json 파일로부터 DatasetDict를 로드하는 메서드&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; datasets &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; DatasetDict
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; dataset&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; DatasetDict&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_json&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;path_of_json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; dataset
DatasetDict&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    train&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Dataset&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        features&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;guid&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;source&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sentence1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sentence2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;labels&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        num_rows&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;11668&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    validation&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Dataset&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        features&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;guid&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;source&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sentence1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sentence2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;labels&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        num_rows&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;519&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Decoding Strategy (디코딩 전략)]]></title><description><![CDATA[Decoding Strategy (디코딩 전략) 이번 포스팅에서는 자연어처리 모델의 디코딩 전략에 관해서 다뤄보려고 합니다. 디코딩이란 말처럼 디코딩은 디코더에서
수행하는 작업입니다. 즉, BERT와 같은 인코더 모델에서 사용하는게 아니라 GPT…]]></description><link>https://sooftware.github.io/generate/</link><guid isPermaLink="false">https://sooftware.github.io/generate/</guid><pubDate>Sat, 15 Jan 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Decoding Strategy (디코딩 전략)&lt;/h1&gt;
&lt;p&gt;이번 포스팅에서는 자연어처리 모델의 디코딩 전략에 관해서 다뤄보려고 합니다. 디코딩이란 말처럼 디코딩은 디코더에서
수행하는 작업입니다. 즉, BERT와 같은 인코더 모델에서 사용하는게 아니라 GPT와 같은 디코더 모델 혹은 인코더-디코더를 모두
가지고 있는 Seq2seq 모델의 디코더에서 수행됩니다. 같은 모델이더라도 이 디코딩 전략을 어떻게 가져가냐에 따라서
디코딩의 퀄리티와 수행 시간들이 천차만별이므로, 자연어처리를 공부하시는 분들이라면 한 번은 꼭 짚고 넘어가야 하는 개념입니다.&lt;/p&gt;
&lt;h2&gt;Greedy Search&lt;/h2&gt;
&lt;p&gt;가장 기본적인 디코딩 전략입니다. 단순하게 매 타임스텝마다 가장 높은 확률을 가지는 토큰을 다음 토큰으로 선택하는 전략입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/149542712-7c3db121-5bb1-4a26-bfd2-9e32135346ec.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;Greedy Search는 가장 기본적이면서도 직관적입니다. 시간복잡도 면에서는 훌륭한 방법이지만, 최종 정확도 관점에서는 꽤나
아쉬운 방법입니다. 특정 시점 t에서 확률 분포 상에서 1등과 2등의 확률 차이가 매우 작더라도 Greedy Search는 1등만 선택할 뿐입니다.
여기서 문제점은 디코딩이라는 과정은 특정 t 시점에서 끝나는게 아니라, 시퀀스 길이 N만큼의 시점 t가 있다는 점입니다.
단 한 번이라도 정답 토큰이 아닌 다른 토큰으로 예측하게 되면 뒤의 디코딩에도 영향을 미치기 때문에 정확도 면에서는 많이 아쉬운 전략입니다.&lt;/p&gt;
&lt;h2&gt;Beam Search&lt;/h2&gt;
&lt;p&gt;Greedy Search 방법에서 시간복잡도를 조금 포기하고 정확도를 높이기 위해 제안된 방법입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/149543597-d3d4c079-7938-468b-aae9-ef9774ac4d6c.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;가장 좋은 디코딩 방법은 가능한 모든 경우의 수를 고려해서 누적 확률이 가장 높은 경우를 선택하는 것이겠지만 이는 시간복잡도 면에서
사실상 불가능한 방법입니다. 빔서치는 이러한 Greedy Search와 모든 경우의 수를 고려하는 방법의 타협점입니다. 해당 시점에서
유망하다고 판단되는 빔 K개를 골라서 진행하는 방식입다. Greedy Search가 놓칠 수 있는 시퀀스를 찾을 수 있다는 장점이 있지만,
시간복잡도 면에서는 더 느리다는 단점도 가지고 있습니다. 또한 빔 개수 K를 몇 으로 설정하냐에 따라서도 결과와 수행시간이 달라지기 때문에
적절한 K를 찾아야 합니다.&lt;/p&gt;
&lt;h2&gt;N-gram Penalty&lt;/h2&gt;
&lt;p&gt;언어모델의 고질적인 문제점 중 하나는 동일한 말을 계속 반복한다는 것입니다. 이러한 현상을 줄여주기 위해 n-gram 패널티를 줄 수 있습니다.
n-gram 단위의 시퀀스가 두 번 이상 등장할 일이 없도록 확률을 0으로 만드는 전략입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/149546126-59292e15-cfe9-4ed4-855c-f0a0f54e4fa0.png&quot; width=&quot;450&quot;&gt;
&lt;p&gt;이 전략을 사용하게 되면 동일한 말을 반복하는 현상을 줄일 수 있지만, n-gram으로 설정한 시퀀스가 두 번 이상 등장할 수 없기 때문에
주의해서 사용해야 합니다.&lt;/p&gt;
&lt;h2&gt;Beam search is boring !!&lt;/h2&gt;
&lt;p&gt;최근 연구 결과들에서 빔서치의 단점이 부각되고 있습니다. 기계번역이나 요약 같이 어느 정도 정답이 정해져 있는 태스크에서는
빔서치가 효과적이지만, dialogue/story generation과 같은 open-ended generation 태스크에서는 적절치 않다는 연구 결과들이 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1808.10006&quot;&gt;Correcting Length Bias in Neural Machine Translation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1808.09582&quot;&gt;Breaking the Beam Search Curse: A Study of (Re-)Scoring Methods and Stopping Criteria for Neural Machine Translation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그리고 빔서치의 가장 큰 문제점은 less-surprising 하다는 것입니다. 빔서치는 K개의 빔에서 가장 높은 확률을 가지는 문장을
선택하게 되는데, 결과를 보게 되면 대체적으로 가장 뻔하게 예측이 되는 문장으로 생성됩니다. 이는 대화/스토리 생성와 같은
open ended 태스크에서는 치명적인 단점입니다. 예측 가능하고 뻔한 문장이 생성된다는 것은 재미라는 점에서 많은 마이너스 포인트를 가져가게 됩니다.
아래 그래프가 이러한 경향성에 대해서 아주 잘 보여주고 있습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/149557583-d636cdf1-5711-4fcb-bb2c-9ae5e844e6b1.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;그래서 이러한 &lt;strong&gt;지루한&lt;/strong&gt; 디코딩을 조금이나마 재밌게 만들기 위해서는 어느 정도의 &lt;strong&gt;랜덤성&lt;/strong&gt;이 추가되면 개선이 될 수도 있습니다.&lt;/p&gt;
&lt;h2&gt;Sampling&lt;/h2&gt;
&lt;p&gt;디코딩 방법에 랜덤성을 추가하는 대표적인 디코딩 전략입니다. 이를 non-deterministic 하다고 표현하는데, 방법은 간단합니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/149557912-9a6d52fb-3829-4606-983d-39d067c42757.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;위의 그림을 예로 설명하겠습니다. 네모 상자 위에 적힌 숫자는 각 토큰의 해당 시점 t의 확률입니다.
nice는 0.5, dog은 0.4, car는 0.1 입니다. greedy search라면 바로 nice를 선택하고 이어나가겠지만 sampling은
이 확률을 그대로 선택될 확률로 사용합니다. 즉, nice라는 토큰이 선택될 확률을 0.5로 줌으로써 다른 토큰들(dog, car)이
선택될 수 있는 랜덤성을 부여하는 방법입니다.&lt;/p&gt;
&lt;h2&gt;Top-k Sampling&lt;/h2&gt;
&lt;p&gt;Top-k Sampling은 Sampling 방법을 약간 개조한 전략입니다. 다음 토큰 선택시, 확률이 높은 K개의 토큰들만으로 한정해서 Sampling을 진행하는 방식입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/149559141-aca96ef5-58a0-4a7b-979d-3972ca234bd9.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;GPT-2 논문에서 이 전략으로 스토리 생성에서 큰 효과를 봤으나, 이 방법은 모델의 창의성을 저하할 수 있다는 단점을 가지고 있습니다.&lt;/p&gt;
&lt;h2&gt;Top-p Sampling (Nucleus Sampling)&lt;/h2&gt;
&lt;p&gt;Top-k Sampling의 문제점을 개선하기 위해 제안된 방법으로, 확률이 높은 K개의 토큰으로부터 샘플링을 하지만,
&lt;strong&gt;누적 확률이 p 이상이 되는 최소한의 집합&lt;/strong&gt;으로부터 샘플링을 하게 하는 전략입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/149561365-545447c8-bed5-4495-ba99-d4e5e85d801a.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;이론 상으로는 top-p 샘플링이 top-k보다 좋아보이지만, 항상 그렇듯 경우에 따라 더 좋을 때도 아닐때도 있습니다.
두 전략 모두 꽤 잘 작동하므로 두 전략 모두 사용해보면서 결과를 비교해보는게 가장 좋습니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[광주소프트웨어마이스터고등학교 학생들 튜닙 방문]]></title><description><![CDATA[…]]></description><link>https://sooftware.github.io/soma/</link><guid isPermaLink="false">https://sooftware.github.io/soma/</guid><pubDate>Tue, 11 Jan 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;광주소프트웨어마이스터고등학교 학생들 튜닙 방문&lt;/h1&gt;
&lt;p&gt;이번 화요일에 광주소프트웨어마이스터고등학교 학생들의 튜닙 오피스 방문이 있었습니다. 학생들에게 오피스 소개와 기념 사진 촬영을 하고, 자유로운 분위기에서 저희 튜닙 회사 소개와 질의 응답시간을 가졌습니다. 고등학생들 입에서 BERT, GPT와 같은 인공지능 모델 이름과 각종 개발 용어가 나오는 모습에 감탄하며 질의 응답시간이 진행됐고, 영어와 수학 공부는 하기 싫다며 투덜대는 모습이 귀여우면서도 NLP 엔지니어를 꿈꾸는 학생, AI Vision 엔지니어를 꿈꾸는 학생, 모바일 개발자를 꿈꾸는 학생 등 벌써부터 각자의 목표를 가지고 진지하게 고민하는 모습이 보기 좋았습니다. :)
학생분들이 성장하여 미래에 현업에서 만나는 날을 기약하며 이번 오피스 방문은 성황리에 마무리 됐습니다!&lt;/p&gt;
&lt;p&gt;저는 고등학생 때 ‘미래에 뭐 할지 모르니까 일단 남들하는 공부나 하자’라는 생각을 하고 있었는데,
벌써부터 미래 확고한 목표를 가지고 준비하는 모습이 멋있네요.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Generation with Retrieval]]></title><description><![CDATA[Generation with Retrieval 이번에 딥마인드에서 RETRO(Retrieval-Enhanced Transformer) 라는 모델을 내놓았습니다. 문서 retrieval + GPT 기반 모델인데,
7B 모델임에도 불구하고 2…]]></description><link>https://sooftware.github.io/fid_and_rag/</link><guid isPermaLink="false">https://sooftware.github.io/fid_and_rag/</guid><pubDate>Tue, 04 Jan 2022 23:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Generation with Retrieval&lt;/h1&gt;
&lt;p&gt;이번에 딥마인드에서 &lt;a href=&quot;https://deepmind.com/research/publications/2021/improving-language-models-by-retrieving-from-trillions-of-tokens&quot;&gt;RETRO(Retrieval-Enhanced Transformer)&lt;/a&gt; 라는 모델을 내놓았습니다. 문서 retrieval + GPT 기반 모델인데,
7B 모델임에도 불구하고 25배나 큰 모델과 비견될만한 성능을 보여줬습니다. 요즘 트렌드는 검색 + GPT로 가는 것 같습니다.&lt;/p&gt;
&lt;p&gt;언어모델이 아무리 크고 많은 데이터를 봤다고 하더라도 세상의 모든 지식을 담을 수는 없습니다.
그리고 새롭게 생긴 지식이라면 더더욱 언어모델 입장에서는 알 수가 없습니다. 이런 문제를 검색과 결합해서
풀어보려는 시도가 많이 있었고, 이번 포스팅에서는 그 기반이 된 개념인 &lt;strong&gt;Fusion-in-Decoder(FID)&lt;/strong&gt; 와 &lt;strong&gt;Retrieval-Augmented Generation(RAG)&lt;/strong&gt;
를 다뤄보겠습니다.&lt;/p&gt;
&lt;h2&gt;Fusion-in-Decoder (FiD)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Fusion-in-Decoder(FID)&lt;/strong&gt; 는 생성 모델 입력에 검색 결과를 넣어서 활용합니다.
아래 그림과 같이 어떤 쿼리가 들어왔을 때 적절한 N개의 문서를 가져오고 이 결과를 언어모델의 인코더에 넣어줍니다.
그리고 디코더는 이 결과를 활용해서 적절한 응답을 생성하는 방식입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/148075563-977db2da-5297-41f1-9f11-cfd54f9ffe4a.png&quot; width=&quot;300&quot;&gt;  
&lt;p&gt;FiD 본 논문에서 검색 모델은 BM25, DPR(Dense Passage Retrieval )을 활용했습니다. 생성 모델로는 위에 설명한 바와 같이
인코더와 디코더가 필요하기 때문에 T5, Bart와 같은 Seq2seq (Sequence-to-Sequence) 기반의 모델을 사용했습니다.&lt;/p&gt;
&lt;p&gt;FiD는 이름은 거창하지만 방식 자체는 어렵지 않습니다. 아래 2개의 개념만 알면 됩니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;FiD의 인코더 입력 형식&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Question:  Where was Alan Turing born? 
Context: Alan Turing was a British computer scientist. Born in Maida Vale, London.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;FiD의 디코더 입력 형식&lt;/li&gt;
&lt;/ol&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/148076695-0fd48602-36dc-4d95-b579-b3c720a32c7d.png&quot; width=&quot;450&quot;&gt;
&lt;p&gt;위 그림과 같이 N개 문서에 대한 각 인코더 아웃풋 벡터를 이어붙여서(concat) 디코더에 넣고 답변을 생성합니다.&lt;/p&gt;
&lt;p&gt;FiD 본 논문에서는 프리트레이닝 된 T5 모델로 Question-Answer pair 데이터로 파인튜닝해서 모델을 만들었습니다.
검색 모델(BM25, DPR)은 따로 학습하지 않았다고 합니다.&lt;/p&gt;
&lt;h2&gt;Retrieval Augmented Generation (RAG)&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/148077292-38acd9d7-e6b7-46aa-821a-4a918ca0f7d8.png&quot; width=&quot;450&quot;&gt;
&lt;p&gt;&lt;strong&gt;Retrieval-Augmented Generation(RAG)&lt;/strong&gt; 역시 생성시에 검색 결과를 활용합니다.
FiD와의 차이점으로는 검색 모델을 따로 학습하지 않은 FiD와는 달리 RAG는 검색 모델 역시 학습한다는 차이가 있습니다.
(RAG는 Retriever로 bi-encoder 기반의 DPR, Generator로 BART를 사용했습니다.)&lt;/p&gt;
&lt;p&gt;RAG는 &lt;code class=&quot;language-text&quot;&gt;RAG-Sequence&lt;/code&gt;와 &lt;code class=&quot;language-text&quot;&gt;RAG-Token&lt;/code&gt;라는 2가지의 변형 알고리즘을 만들었습니다.
둘은 계산을 행하는 단위가 문장 전체냐, 토큰이냐의 차이를 가지고 있습니다.&lt;/p&gt;
&lt;h3&gt;RAG-Sequence&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/148079083-bbe3b655-665f-4e46-b76f-7ae91c2ee3a1.png&quot; width=&quot;250&quot;&gt;
&lt;ol&gt;
&lt;li&gt;Retriever로 쿼리와 관련된 K개의 문서를 찾는다.&lt;/li&gt;
&lt;li&gt;K개 문서 각각을 프롬프트로 하는 시퀀스를 K개 생성한다.&lt;/li&gt;
&lt;li&gt;2에서 구한 K개의 시퀀스의 확률 분포를 모두 합친다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;위 그림과 같이 관련 있는 문서 K개에 대하여 시퀀스 길이 N까지 예측한 확률 분포 시퀀스를 모두 더한 뒤,
각 위치에서 가장 높은 확률을 갖는 토큰들을 뽑아내면 됩니다.
여러개의 생성 모델로 예측한 뒤 합쳐서 토큰을 뽑아내는 앙상블 방식과 유사하다는 생각이 듭니다.&lt;/p&gt;
&lt;h3&gt;RAG-Token&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/148079562-daff56f3-1fbe-4e33-a66a-6fa649ddade5.png&quot; width=&quot;250&quot;&gt;
&lt;ol&gt;
&lt;li&gt;Retriever로 쿼리와 관련된 K개의 문서를 찾는다.&lt;/li&gt;
&lt;li&gt;다음 토큰을 생성할 때 K개 문서 각각에 대해서 구한다.&lt;/li&gt;
&lt;li&gt;2에서 구한 확률 분포를 합쳐서 다음 토큰을 결정한다.&lt;/li&gt;
&lt;li&gt;이를 시퀀스 길이 N만큼 반복한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;방식 자체는 RAG-Sequence와 크게 다르지 않습니다.
단지 확률 분포를 언제 합치느냐만 다릅니다.
다음 토큰을 예측할 때 Acoustic 모델과 Language 모델 2개의 확률분포를 합쳐서 결정하는
음성인식 시스템과 유사한 방식이라는 생각이 듭니다.&lt;/p&gt;
&lt;p&gt;주의할 점은 학습 대상은 DPR의 쿼리인코더와 Generator인 BART이며, DPR의 문서 인코더는 고정해 두었습니다. (bi-encoder 구조 참고!)&lt;/p&gt;
&lt;p&gt;그리고 “Retrieval Augmentation Reduces Hallucination in Conversation” 논문에 따르면 RAG로 학습한 검색 모델을
FiD의 검색 모델로 사용시 FiD의 성능을 높일 수 있다고 합니다 :)&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ratsgo.github.io/insight-notes/docs/qa/answerer&quot;&gt;ratsgo님 블로그&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/pdf/2007.01282.pdf&quot;&gt;Leveraging Passage Retrieval with Generative Models for Open Domain Question Answering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/pdf/2005.11401.pdf&quot;&gt;Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/pdf/2104.07567.pdf&quot;&gt;Retrieval Augmentation Reduces Hallucination in Conversation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Basic Computer System - 연산 장치]]></title><description><![CDATA[Basic Computer System ※ 본 포스팅의 내용은  책을 읽고 공부한 내용을 기록한 포스트입니다. 컴퓨터를 구성하는 3 요소 연산 장치 (CPU) => 초당 얼마나 많이 계산 가능한지 메모리 장치 (RAM, Hard-Drive…]]></description><link>https://sooftware.github.io/cs-basic/</link><guid isPermaLink="false">https://sooftware.github.io/cs-basic/</guid><pubDate>Tue, 04 Jan 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Basic Computer System&lt;/h2&gt;
&lt;p&gt;※ 본 포스팅의 내용은 &lt;code class=&quot;language-text&quot;&gt;고성능 파이썬 (High Performance Python)&lt;/code&gt; 책을 읽고 공부한 내용을 기록한 포스트입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컴퓨터를 구성하는 3 요소
&lt;ul&gt;
&lt;li&gt;연산 장치 (CPU) =&gt; 초당 얼마나 많이 계산 가능한지&lt;/li&gt;
&lt;li&gt;메모리 장치 (RAM, Hard-Drive) =&gt; 데이터를 얼마나 많이 저장할 수 있으며, 얼마나 빠르게 읽고 쓸 수 있는지&lt;/li&gt;
&lt;li&gt;연결 장치 (BUS) =&gt; 장치 간에 데이터를 얼마나 빠르게 옮길 수 있는지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;연산 장치&lt;/h3&gt;
&lt;p&gt;컴퓨터의 가장 핵심적인 장치로 입력되 bit를 다른 bit로 변환하거나 프로세스 상태를 변경하는 기능을 제공한다.
일반적인 연산 장치는 CPU지만 최근에는 인공지능 모델 학습에 잘 쓰이는 GPU가 인기를 끌고 있다. 연산 장치 성능의 핵심은 한 사이클에 처리할 수 있는 연산의 개수와 1초에
처리할 수 있는 사이클의 횟수이다. 한 사이클에 처리할 수 있는 연산의 개수는 **IPC(Instructions Per Cycle)**로 측정하고,
초당 사이클 횟수는 &lt;strong&gt;클럭 속도&lt;/strong&gt;로 측정한다.&lt;/p&gt;
&lt;p&gt;이 두 개념은 CPU의 주 성능 지표이다. 어떤 CPU는 IPC 값이 높지만 클럭 속도가 느리고, 어떤 CPU는 반대인 경우도 있으며,
GPU는 클럭 속도가 빠르고 IPC 값도 크지만 다른 문제에서 병목 현상이 발생한다.&lt;/p&gt;
&lt;p&gt;클럭 속도를 높이면 초당 연산량이 증가하므로 모든 프로그램의 속도가 개선되며, IPC 값이 높아지면 &lt;strong&gt;벡터화&lt;/strong&gt; 수준이 증가하므로
처리 성능이 올라간다. 벡터화는 CPU가 여러 데이터를 입력받아 한 번에 처리할 때 발생하는데, 이런 명령을 **SIMD(Single Instruction Multiple Data)**라고 한다.&lt;/p&gt;
&lt;h3&gt;연산 장치 관련 기술&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Hyperthreading
&lt;ul&gt;
&lt;li&gt;OS에 가상의 두 번째 CPU를 인식시키고 단일 CPU의 실행 유닛에 두 스레드를 번갈아 가며 실행하도록 하는 기법&lt;/li&gt;
&lt;li&gt;단일 스레드 대비 30%까지 성능을 끌어올릴 수 있음&lt;/li&gt;
&lt;li&gt;두 스레드가 서로 다른 실행 유닛을 사용할 때 (Ex-한 스레드는 실수 연산, 다른 스레드는 정수 연산을 할 때) 잘 작동&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;비순차적 명령어 처리 (Out-of-order Execution) - Pipeline
&lt;ul&gt;
&lt;li&gt;이전 작업의 결과에 영향을 받지 않는 부분을 찾아내서 두 작업을 순서와 관계없이 실행하거나 동시에 실행하는 기법&lt;/li&gt;
&lt;li&gt;순서에 관계가 있는 경우 기다렸다가 처리하는 등의 로직이 섞여 있음&lt;/li&gt;
&lt;li&gt;사용 가능한 자원을 최대한 활용함으로써 처리 속도를 상승시킴&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;멀티 코어 아키텍처
&lt;ul&gt;
&lt;li&gt;실행 유닛 하나에 CPU를 여러 개 사용하는 기법&lt;/li&gt;
&lt;li&gt;암달의 법칙(Amdahl’s Law): 멀티 코어에서 작동하도록 설계된 프로그램이더라도 하나의 코어에서 실행해야 되는 부분이 존재하므로,
이 루틴이 코어를 더 투입하더라도 성능이 더 좋아지지 않는 병목으로 작용한다는 법칙이다.&lt;/li&gt;
&lt;li&gt;파이썬에서는 GIL(Global Interpreter Lock) 때문에 코어를 여러 개 활용하기 쉽지 않음. GIL은 한 번에 명령 하나만 실행하도록 강제하는 파이썬 고유의 인터프리터 법칙으로
다수의 코어를 사용하더라도 한 번에 명령 하나만 처리하기 때문에 멀티 코어를 사용하는 장점이 사라진다.&lt;/li&gt;
&lt;li&gt;멀티 코어를 사용하기 위해서는 파이썬 내장 라이브러리인 multiprocessing 혹은 ray, numpy or numexpr, cython 등을 사용할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[고성능 파이썬 (High Performance Python)]]></title><description><![CDATA[고성능 파이썬 (High Performance Python) 신년 첫 개발 서적으로 고성능 파이썬 (High Performance Python…]]></description><link>https://sooftware.github.io/highperformance-python/</link><guid isPermaLink="false">https://sooftware.github.io/highperformance-python/</guid><pubDate>Mon, 03 Jan 2022 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;고성능 파이썬 (High Performance Python)&lt;/h1&gt;
&lt;p&gt;신년 첫 개발 서적으로 고성능 파이썬 (High Performance Python) 책을 읽어보려고 합니다.&lt;/p&gt;
&lt;img src=&quot;http://image.kyobobook.co.kr/images/book/xlarge/210/x9791162244210.jpg&quot; width=&quot;300&quot;&gt;  
&lt;p&gt;아무래도 거의 모든 개발을 파이썬만 사용하고 있는데, 조금이라도 더 파이썬을 잘 활용하기 위해
공부를 해보려고 합니다. 1장을 읽고 있는데, 다른 파이썬 책들과는 다르게 하드웨어 얘기부터 시작을 하는게
난이도가 조금 있을 것 같습니다. 대학생때 파이써닉한 프로그래밍을 하기 위해 개인적으로도, 학교에서도 공부를 꽤 했지만,
파이썬의 내부적으로 어떻게 이루어져 있고, 이를 어떻게 활용해서 프로그램을 더 빠르고, 더 가볍에 만들 수 있을지에 대한 공부를
미뤄왔는데 올해에는 이 책을 통해 파이썬 고오오오수로 거듭나보겠습니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[2021년 회고]]></title><description><![CDATA[2021년 회고 2020년 회고 글 을 적은지 얼마 되지 않은 것 같은데 벌써 202…]]></description><link>https://sooftware.github.io/2021/</link><guid isPermaLink="false">https://sooftware.github.io/2021/</guid><pubDate>Fri, 31 Dec 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;2021년 회고&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://sooftware.github.io/2020/&quot;&gt;2020년 회고 글&lt;/a&gt; 을 적은지 얼마 되지 않은 것 같은데 벌써 2021년 회고 글을 쓸 날이 오네요. 😱&lt;br&gt;
작년 회고를 쓸 때는 ‘올해처럼 극적이였던 해는 한동안 없겠지?‘라고 생각했던게 무색하게 올해는 더욱 극적이였던 것 같습니다.&lt;br&gt;
그런 의미에서 올해도 역시 회고글을 작성해볼까 합니다. 몇 일 전에 군생활할 때 작성했던 1년치 일기를 쭉- 읽어봤는데, 잊고있었던 일들도 떠오르고
그때 내가 어떤 감정이였고, 어떤 걱정을 했는지, 어떤 노력들을 하고 있었는지를 볼 수 있어서 좋았습니다. 요즘은 전처럼 매일 일기를 쓰지는 못하고 있지만
적어도 1년에 한 번씩 회고글을 꾸준히 적어볼까 합니다. 몇 년 뒤, 몇십 년 뒤에 돌아보면 꽤나 귀중한 자산일 것 같습니다. 😁&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;이사&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pororo&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;창업 제의 &amp;#x26; 퇴사 &amp;#x26; 졸업&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;창업&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;제주도 한달 살이&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;슬럼프&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;전환&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;커져가는 튜닙&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;시드 투자 유치&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2021 AI Grand Challenge&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;보람, 조금 더 여유를 가지고&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;올해 기록&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;이사 (1월)&lt;/h2&gt;
&lt;p&gt;부모님 품이자 고향인 천안에서 19년을 편안히 보내고 20살부터는 혼자서 자취를 했습니다. 스무살때는 모교인 광운대 앞에서, 21살부터 군 전역 직후까지는
노량진에서 친누나와 함께, 그리고 다시 광운대 앞에서 올해 1월까지는 쭉 지내왔었습니다. 하지만 이제는 학교를 벗어나서 직장생활을 해야 됐기 때문에
이사를 해야했습니다. 사실 회사는 전년도 여름부터 다니고 있었고, 사실상 학교를 코로나 때문에 온라인으로만 운영이 됐기 때문에
진작에 이사를 했어야 했지만 작년에는 정직원 전환 여부도 확실치 않았고 제 마음 속에서도 대학원 진학과 취업 사이에서 갈등이 있었기 때문에 이사를 조금 미뤄뒀었습니다.&lt;/p&gt;
&lt;img src=&quot;http://eiec.kdi.re.kr/userdata//nara/201903/11934/edit/aaavTdVvu6wjd8JOBVXEw1551166099586.jpg&quot; width=&quot;500&quot;&gt;
&lt;p&gt;그래서 올해 초에는 미뤄뒀던 이사를 했습니다. 전 직장인 카카오브레인이 판교에 있었기 때문에 최대한 판교와 가까운 곳으로 알아봤는데,
판교, 정자 등 가까울수록 택도 없이 비싼 값에 어쩔 수 없이 거리를 조금 포기하고 죽전역 근처에 있는 용인시 보정동으로 이사를 했습니다.
제가 용인시에 살게될 거라고는 생각도 못했었는데.. ㅋㅋㅋ&lt;/p&gt;
&lt;p&gt;사실 한참 일이 바빠서 직접 못 알아보고 있던 차에 부모님께서 먼저 집을 알아봐주셨는데,
미리 약속을 하고 일을 하다가 퇴근하면 같이 집을 보기로 했습니다, 당시에 워낙 좋은 집 구하기가 힘들었고 앞서서 수지구청역쪽에 좋은 집이 있었는데,
잠깐 고민하는 사이에 다른 분이 계약을 해버리는 일까지 있어서 제가 합류하기 전에 부모님이 먼저 계약을 해버리셨습니다 ㅋㅋ&lt;/p&gt;
&lt;img src=&quot;https://t1.daumcdn.net/cfile/blog/165B98474D31471B0B&quot; width=&quot;500&quot;&gt;
&lt;p&gt;그래서 저는 계약하고 이사갈 날이 다가와서야 한 번 가봤는데, 부모님이 워낙에 집이 별로 크지 않다, 너무 기대하지 마라 등의 말을 해놓으셔서
기대를 완전 내려놓고 있었습니다. 그런데 막상 가보니 집이 조금 낡긴 했지만 전에 살던 학교 앞 원룸보다 2배 정도는 컸습니다.
그리고 무엇보다 집 바로 앞 쪽에 엄청 이쁜 카페거리가 있어서 평소 커피와 카페를 좋아하는 저에게는 최고의 위치였습니다 😁&lt;/p&gt;
&lt;p&gt;집 밖을 나가기만하면 심심치 않게 마주치던 대학 동기들, 후배들은 없어졌지만, 새로운 곳에서 2021년을 시작하게 돼서 꽤나 설레였었습니다.&lt;/p&gt;
&lt;h2&gt;Pororo (1월 - 2월)&lt;/h2&gt;
&lt;p&gt;올해 초에 제가 카카오브레인에서 하던 일은 지금은 공개된 오픈소스 자연어처리 라이브러리인 &lt;a href=&quot;https://github.com/kakaobrain/pororo&quot;&gt;pororo&lt;/a&gt;
의 음성 모듈 개발이였습니다. 제가 담당했던건 다국어 음성인식, 다국어 음성합성 모듈이였고, 관련해서 documentation, 테스트 코드 작성, 환경 테스트 등
이 라이브러리를 공개하기 위한 여러 준비로 바빴습니다.&lt;/p&gt;
&lt;img src=&quot;https://www.fnnews.com/resource/media/image/2011/04/22/201104221537150303_l.jpg&quot; width=&quot;200&quot;&gt;  
&lt;p&gt;지난 여름 회사 들어올때부터 진행한 프로젝트였고, 이 라이브러리가 많은 분들께 도움이 되리라는 확신이 있었기 때문에
이 라이브러리를 공개하는것에 대해서 저는 굉장히 설레였습니다. 당시의 목표는 현재 한국어 자연어처리 라이브러리 중 가장 많은 스타를 보유한
&lt;a href=&quot;https://github.com/konlpy/konlpy&quot;&gt;KoNLPy&lt;/a&gt; 를 넘어보자! 라는 목표가 있었는데, 오늘 날짜 기준으로 KoNLPy는 1.2K의 스타를, Pororo를 1.1K의 스타를 기록하고 있네요.
공개한 첫 날, 공개한지 몇시간이 지나지 않아 스타 300개를 빠르게 넘겼는데, 제가 참여한 프로젝트가 이렇게 큰 관심을 받는다는게 새삼 놀라워서 계속 깃허브 페이지를 새로고침한 기억이 있네요 ㅎㅎ 지난 수 개월간의 노력의 보상을 받은 느낌이였습니다. :)&lt;/p&gt;
&lt;img src=&quot;https://www.hanbit.co.kr/data/editor/20210620232918_cbmledvh.jpeg&quot; width=&quot;350&quot;&gt;
&lt;p&gt;몇 개월 전에는 박해선님이 번역해주신 ‘파이토치로 배우는 자연어처리’라는 책에 pororo가 소개되기도 하는 영광스러운 일도 있었습니다 :)&lt;/p&gt;
&lt;h2&gt;창업제의 &amp;#x26; 퇴사 &amp;#x26; 졸업 (2월)&lt;/h2&gt;
&lt;p&gt;Pororo도 공개를 했고, 당시에 저희 팀은 앞으로 1년간 어떤 일을 할지에 대해서 정말 많은 얘기를 했습니다.
서비스를 만들어보자, 연구를 하자, 오픈소스를 만들자, 빅모델을 만들자 등 여러 의견이 오갔던 것 같습니다. 당시에 저희 팀은 새로 입사하신 분,
다른 팀에 계시다가 새로 오신 분 등 꽤나 큰 변화가 있었습니다. 그래서 이때 논의한 앞으로의 1년 계획이 굉장히 중요했었습니다.&lt;/p&gt;
&lt;p&gt;한참 그러던 시기에 당시 팀장님, 현 대표님께서 충격적인 발언으로 저희 팀을 뒤집어 놓으셨습니다.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;‘고민을 많이 하다가 사직서를 냈다. 창업을 할 생각이다’&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;img src=&quot;https://mblogthumb-phinf.pstatic.net/20140825_140/mara0805_1408960090248uDb88_JPEG/%B3%EE%B6%F5%C7%A5%C1%A4%B1%E2%BA%BB.jpg?type=w2&quot; width=&quot;300&quot;&gt;  
&lt;p&gt;저를 포함한 모든 팀원들은 굉장히 크게 놀랐고, 웬만한 일에는 무덤덤한 편이 저도 당시 팀에 만족감이 컸기 때문에 받아들이기 어려울 정도의 큰 충격을 받았습니다.&lt;/p&gt;
&lt;p&gt;그 말을 듣고 집에서 혼자서 정말 많은 생각을 했습니다. ‘팀장님이 가시면 누가 팀장님으로 오시지?’, ‘팀장님을 따라간다고 하면 팀장님이 받아주실까?’,
등 정말 여러 많은 생각이 들었습니다. 언젠가는 스타트업에 가서 일을 하고 싶다, 먼 미래에는 내가 창업을 할 수도 있지 않을까? 라는 생각을 해본적은 있었지만,
이렇게 빨리 스타트업 씬에 뛰어든다는 생각을 해보지는 못했었습니다.&lt;/p&gt;
&lt;p&gt;그렇게 여러 생각에 하며 새벽에 잠을 못 자고 있었는데, 팀장님께서 연락이 오셔서 혹시 지금 잠깐 얘기 가능하냐고 물어보셨고,
저도 차라리 최대한 빨리 팀장님과 얘기를 해버리는게 마음이 편할거 같아서 바로 온라인으로 미팅을 했습니다.&lt;/p&gt;
&lt;img src=&quot;https://file.mk.co.kr/meet/neds/2021/04/image_readtop_2021_380640_16189064024617449.jpg&quot; width=&quot;450&quot;&gt;
&lt;p&gt;팀장님께서 아마 많이 놀랐을텐데, 제 생각은 어떤지, 그리고 같이 나와서 공동 창업을 할 생각이 있는지를 물어보셨고, 간단히 얘기를 나눈 뒤에
팀장님을 따라 가고 싶다는 의사를 표현을 했습니다. 그렇게 어찌저찌 시간이 지나고 저와 공동창업자들은
2월 말에 카카오브레인을 퇴사하게 됐습니다.&lt;/p&gt;
&lt;img src=&quot;https://shoark7.github.io/assets/img/insight/graduation.jpg&quot; width=&quot;500&quot;&gt;
&lt;p&gt;그리고 오랜만에 학교를 방문해 졸업식을 진행했습니다 :)&lt;br&gt;
정말 많은 일들이 있었던거 같은데 이제야 졸업이라니.. 라는 생각과 이제 더는 학생이 아니구나.. 라는 생각이 들었습니다.
오랜만에 만난 동기들, 후배들은 요즘같이 취직이 어려운 때에 그 좋은 직장을 퇴사하냐며 미쳤냐라는 반응과 그런 선택할 수 있는게 대단하다는 반응 등이 있었던 것 같습니다.
정작 저는 당시에 그게 그렇게 큰 결정이였는지에 대해서 충분히 실감하지 못하고 있었던 것 같습니다. 😅&lt;/p&gt;
&lt;p&gt;그리고 여자친구와 CC여서 졸업식 사진을 같이 찍을 수 있었던 점이 좋았습니다!&lt;br&gt;
당일날 정신이 없어서 많이 찍지는 못했지만 몇 장이라도 기록해놔서 다행이네요 😂&lt;/p&gt;
&lt;h2&gt;창업 (2-3월)&lt;/h2&gt;
&lt;p&gt;회사를 나와서는 사무실이 따로 없어서 공동창업자 멤버들과 한동안 여기저기를 떠돌아다녔습니다.
스터디 카페를 전전하기도 하고, 대표님 집에 가서 회의를 하기도 했습니다.
주로 어떤 아이템을 사업 아이템으로 할 건지에 대한 논의를 정말 많이 했고, 그 외에도
우리가 만들고 싶은 회사는 어떤 회사인지 등에 대해서 많은 얘기를 했습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147358261-ec932280-a80c-4cf2-aa62-6c9b4aeaa0ae.png&quot; width=&quot;300&quot;&gt;  
&lt;p&gt;그리고 이 시기에 여러 스타트업 대표님들, 관련 전문가 분들을 만나뵈면서 많은 조언을 얻었습니다.
스타트업이라는게 어려운 줄은 알았지만 막상 회사를 나와서 실제로 직접 해보려니 막막한게 한 두가지가 아니였습니다.
아이템을 정하는 것, 멤버들간의 의사소통 하는 것, 기술적인 부분만 알아야 되는게 아니라는 점 등
하나하나 쉬운게 없었습니다. 특히 제가 공동창업자라는 타이틀에 맞지 않게 너무나 아는 것이 없다는걸 깨달았습니다.
회사의 지분구조, 스톡옵션 개념, 시드 머니, 시리즈 A, 시리즈 B, 엑싯, B2B, B2C 등 처음 듣는 용어가 정말 많았습니다.
지금 돌이켜보니 제가 정말 무식했다는 생각이 절로 드네요 😅&lt;/p&gt;
&lt;img src=&quot;https://cloudfront-ap-northeast-1.images.arcpublishing.com/chosunbiz/ZURWHEEQKU5XLNVXLUXSI363RY.jpg&quot; width=&quot;450&quot;&gt;
&lt;p&gt;그렇게 한동안 스터디카페를 돌아다니다가 계속 이러고 있을수는 없어서 알아보다 &lt;a href=&quot;http://www.d2startup.com/&quot;&gt;네이버 D2SF&lt;/a&gt; 에
연락을 드렸고 운이 좋게도 마침 한 팀 자리가 비어서 저희가 그 자리로 들어갈 수 있었습니다. (D2 만세! 네이버 만세!)
D2에 입주한 다른 스타트업들을 옆에서 볼 수 있다는 것만으로도 저에게는 많은 공부가 됐습니다.
다른 스타트업들 분위기는 어떤지, 어떤 비젼을 가지고 있는지 등을 알게 되면서 조금 더 스타트업 생태계에 대한 이해도가 많이 높아졌습니다.
스타트업에 관심 있으신 분들이라면 기회가 있다면 꼭 D2에 방문해보시는 것을 추천드립니다! 👍 👍&lt;/p&gt;
&lt;p&gt;그리고 이때부터 여러 스타트업에 관심을 가지다가 최근에 제가 아는 스타트업들을 정리해놓은 깃허브 레포를 하나 만들었습니다.
아직 많이 허접하지만 꽤나 많은 분들이 관심을 가져주셨습니다 🙏&lt;/p&gt;
&lt;p&gt;링크: &lt;a href=&quot;https://github.com/sooftware/k-startups&quot;&gt;https://github.com/sooftware/k-startups&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;제주도 한달 살이 (4월)&lt;/h2&gt;
&lt;p&gt;창업 초기부터 창업 초기에 해외나 제주도 같은 곳에 가서 공동창업자들끼리 한달 생활을 해보자라는 얘기를 장난 반 진심 반으로 하곤 했는데,
4월 한달 동안 실제로 제주도에 내려가 같이 살게 되었습니다! (해외는 코로나 때문에 가고 싶어도 갈 수가 없었습니다 😂)
멤버끼리 더욱 돈독해지고 추억도 만들고 한달동안 빡세게 일해보자! 라는 취지였습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147360483-4c747ea0-840a-4a04-a88c-172985330f62.png&quot; width=&quot;300&quot;&gt;
&lt;p&gt;내려갈때는 마냥 즐거울 것을 기대하고 갔습니다. 지인 분들이 놀러오시기도 하고, 멤버들끼리 제주도 바다 구경도 자주 가곤 했지만,
마냥 즐겁지만은 않았습니다. 제주도로 내려간 주된 목적은 한달동안 업무에 집중을 하기 위해서였는데, 저는 제주도에서 업무에 집중을 잘 하지 못했습니다.
학생때도, 취직을 하고나서도 거의 집에서 혼자서 코딩을 하며 업무를 할 때가 많았는데, 새로운 환경에서 그리고 조금은 불편한
자리에서 일을 하다보니 일에 집중을 거의 하지 못했습니다. 제게 있어서 업무 환경이 제 퍼포먼스에 미치는 영향이 얼마나 큰지에 대해서
깨달을 수 있었습니다. 제가 업무 환경에 예민하다는 점, 그리고 혼자서 집중하는 시간이 꼭 필요하구나라는 점을 알 수 있었습니다.&lt;/p&gt;
&lt;h2&gt;슬럼프 (4월-5월)&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147762463-951ba91d-3793-478b-9a18-f2d8f3892c72.png&quot; width=&quot;450&quot;&gt;
&lt;p&gt;제주도에서부터, 한동안 제 역할의 갈피를 못 잡았던 것 같습니다.
3월은 창업 초기라 정신이 없었고, 4월은 제주도에서 일에 집중을 못해서 코딩을 하면서 업무에 몰입했던 기억이 희미해지고 있었습니다.
그러다보니 전처럼 의자에 앉고 바로 일에 몰입하기가 어려웠습니다.
그리고 제가 주로 해오던건 Speech Processing 관련 일이였는데, 지금 회사에서는 Natural Language Processing(NLP) 일을 해야 됐기 때문에
NLP 공부도 많이 했어야 했습니다. 당시에는 ‘Speech랑 NLP랑 크게 다르지 않으니 조금만 공부하면 금방 할 수 있다’라는 생각이 있었는데,
돌이켜보면 당시에 NLP 관련 지식이 많이 부족했다는 생각이 듭니다. 지식이 딸리니 업무에서도 퍼포먼스가 나오질 않았습니다.
그리고 제주도에서 많이 안 움직이고, 업무공간에 있는 맥주기계 맥주를 많이 먹은 탓에 몸에 살도 굉장히 많이 쪘었습니다 😭&lt;/p&gt;
&lt;h2&gt;전환 (5월-7월)&lt;/h2&gt;
&lt;p&gt;이 상태가 길어지면 제 스스로도 문제고, 회사에게도 민폐이기에 전환점이 필요했습니다.
어떻게 극복할까를 고민하고 이 시기를 이겨내기 위한 방법을 추렸습니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;운동을 다시 시작한다.&lt;/li&gt;
&lt;li&gt;일에 몰입하는 감각을 되살린다.&lt;/li&gt;
&lt;li&gt;업무적으로 성과를 낸다.&lt;/li&gt;
&lt;/ol&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147762596-5c1e91f9-d483-44e3-b4ed-4411ac11f116.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;제 기억에 제가 어떤 일을 할 때 몰입도가 가장 높았던 때를 돌이켜보면, 대학교 3학년때였던 것 같습니다.
당시에 아침 일찍부터 새벽까지 학교수업, 운동, 도서관, 개인 프로젝트 등을 진행하면서도 컨디션과 집중력이 항상 좋았고,
자신감도 충만했었습니다. 당시에는 주 5회 이상 하루 2시간씩 꼭 헬스장에서 운동을 했는데,
운동의 영향이 컸었다고 생각합니다. 언젠가부터 일이 바빠서 점점 운동과 멀어졌는데
다시 조금씩이라도 운동을 해야겠다는 생각이 들었습니다. 그래서 집 앞에 있는 헬스장에 가서 피티를 끊고 운동을 다시 시작하게 됐습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147762670-b3282082-9abf-4209-88b9-d895b496324f.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;두 번째로, 일에 몰입하는 감각을 다시 전처럼 끌어올리는게 필요했습니다.
이사, 창업, 제주도 한달 살이 등의 환경 변화로 제 업무 몰입도가 전에 비해 현저히 낮아졌다는 생각이 들었고,
지금의 환경에 최대한 빨리 적응해야 했습니다. 그래서 나름의 고민을 통해 주말을 이용해서 &lt;a href=&quot;https://github.com/openspeech-team/openspeech&quot;&gt;OpenSpeech&lt;/a&gt; 라는
프로젝트를 시작해야겠다는 결심이 섰습니다. 작년에 진행했던 &lt;a href=&quot;https://github.com/sooftware/kospeech&quot;&gt;KoSpeech&lt;/a&gt; 프로젝트는 한국어 음성인식에 특화된
프레임워크였기에, ‘다음 프로젝트로는 한국어뿐만 아니라 더 많은 언어와 더 많은 모델을 지원하는 프레임워크를 만들어야겠다’라는 생각이 있었습니다.
그런데 예상치 못하게 창업에 뛰어들면서 음성인식 연구/개발에 마침표를 제대로 못 찍었다는 아쉬움이 항상 있었는데,
이 프로젝트를 후딱 해버리며 일에 몰입하는 감각도 되찾고, 제 음성인식 연구/개발에 마침표를 찍기로 했습니다.
그렇게 학교 후배 한명과 함께 약 3번의 주말 정도를 투자해서 해당 프레임워크를 공개하게 됐습니다. 전부터 하고 싶었던 프로젝트를
한다는 두근거림 때문인지 다행히도 이 프로젝트를 진행하면서 전처럼 몰입도가 좋아졌고, 코딩 감각도 되살아났습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147763029-c58a8665-8a0d-4835-93ca-301caaca155d.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;운동도 꾸준히 하기 시작했고, 업무에 집중력도 서서히 올라가던 시기에 업무적으로 성과를 낼 만한 일이 저에게 주어졌습니다.
올해 열린 &lt;code class=&quot;language-text&quot;&gt;2021 인공지능 온라인 경진대회&lt;/code&gt;에 회사 대표로 참여해서 1위를 해오는 미션이 주어졌습니다. 해당 대회의 각 문제에서 1위를 하게 되면
&lt;strong&gt;3억원의 사업화 지원금&lt;/strong&gt;이 주어졌습니다. 대회 기간은 약 10일 정도로, 대회 기간도 짧으면서 상금은 컸기 때문에 저희는 참가를 하기로 했습니다.
그리고 저희 회사가 참여하는 첫 컴피티션이였기 때문에 &lt;em&gt;&lt;strong&gt;우리가 자연어처리 기술력은 국내 최고다!&lt;/strong&gt;&lt;/em&gt; 라는 말에 힘이 실릴 수 있도록
꼭 1등을 해야겠다는 생각으로 대회에 임했습니다. 그리고 제 개인적으로는 슬럼프를 극복하는 계기가 될 수 있었기에 저에게는 의미가 더 컸습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147763757-1918a12a-84dd-4b14-a156-bbe8921bfaa7.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;다행스럽게도 대회 Public / Private / Final 모든 리더보드에서 1위를 할 수 있었습니다. 마지막 1위 발표할때까지
5분마다 리더보드 새로고침을 하면서 순위를 확인했었습니다. 당시에 자다가도 누가 순위 역전했을까봐 몇번 씩 깨서
리더보드를 확인하고 다시 자기를 반복했었습니다.&lt;/p&gt;
&lt;p&gt;대회 진행중에는 Public 리더보드밖에 보지를 못해서 대회 종료후에 Private, Final 리더보드가 공개될때까지 기다리다가
1위를 확인하고는 안도감과 기쁨에 기분좋게 회사로 가서 파티를 했습니다. 🎉 🎉&lt;/p&gt;
&lt;p&gt;해당 대회 1등 노하우에 대해서 외부 발표도 했는데 해당 영상은 &lt;a href=&quot;https://www.youtube.com/watch?v=aKKDvdel5O4&amp;#x26;t=1246s&quot;&gt;여기&lt;/a&gt; 서 볼 수 있습니다!&lt;/p&gt;
&lt;h2&gt;커져가는 튜닙 (6월-11월)&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147765952-12dc20c8-e2be-474d-b5e0-84b65db544f3.png&quot; width=&quot;450&quot;&gt;
&lt;p&gt;이 전까지가 튜닙이 달려나가기 위한 준비과정 이였다면 이때쯤부터 달려나가기 시작했습니다.
저희 튜닙에 사람들이 늘어나기 시작했습니다. 개발, 기획 등의 영역에서 사람을 뽑기 시작하며,
매주 한-두명씩 지속적으로 늘어나면서 급속도로 커졌습니다.
저희가 만든 회사에 직원 분들이 하나씩 늘어나는 모습을 보니 신기했습니다.
그리고 사람이 많아짐에 따라 점점 체계가 필요해서 하나하나 상의해가며 체계를 잡아나갔고 때로는
어떻게 하는게 좋은것인지 판단하기 힘든 골치 아프지만 결정해야 되는 사안들도 있었습니다.
한 회사의 체계를 만들어나가는 일이라는건 참 어렵다는걸 새삼 알게되었고, 그로 인한 책임감도 많이 느껴졌습니다.
아직 제가 이런 역할을 감당할만한 경험과 지식이 부족해서 다른 공동창업자분들께 많이 배우고 있습니다. 😭&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147768229-849a8f0b-a3f8-4a88-a7fe-fbbc74cf9df7.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;사람이 늘어감에 따라서 저희가 할 수 있는 일도 많아져서 그동안 하고싶었던 많은 일들을 본격적으로 시작하게 됐습니다.
데이터 수집 및 검수, 언어 모델 개발, 서비스 기획 및 개발, 오픈소스 기여 등 이제 어엿한 스타트업의 모습을 제대로 갖추었다는
느낌이 들었습니다. 😁&lt;/p&gt;
&lt;h2&gt;🌱 시드 투자 유치&lt;/h2&gt;
&lt;p&gt;튜닙을 설립하고부터 저희 대표님께서 시드 투자를 유치하기 위해 많은 노력을 하셨는데요,
올해 11월에 그 노력의 결실이 이루어졌습니다. 🎉 🎉&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147767978-d6de583e-b985-424a-a537-fb013423f94c.png&quot; width=&quot;450&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.pacapital.co.kr/&quot;&gt;펄어비스캐피탈&lt;/a&gt;, &lt;a href=&quot;http://dscinvestment.com/&quot;&gt;DSC 인베스트먼트&lt;/a&gt;, &lt;a href=&quot;http://www.d2startup.com/&quot;&gt;네이버D2SF&lt;/a&gt; 로부터
30억 규모의 시드 투자를 유치하게 됐습니다! 이 투자가 위의 그림처럼 무럭무럭 자라나서 시리즈 A, B, C까지 쭉 이어지며
성장하는 시작이 되기를 바래봅니다. 🙏 투자해주신 펄어비스캐피탈, DSC 인베스트먼트, 네이버D2SF 모두 감사합니다!&lt;/p&gt;
&lt;h2&gt;2021 AI Grand Challenge (11월)&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147768928-696b23ba-3185-4010-bcd7-1c330319f5a2.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;회사 대표로는 두 번째로 컴피티션에 참가했습니다. AI Grand Challenge라는 대회인데, 사실 저에게는 꽤나 익숙한 대회입니다.
작년 2020 그랜드 챌린지 음성 인지 태스크에 저희 과 교수님께서 연구실 분들과 함께 참가하여 3위라는 성적으로 약 5억원의 사업화지원금을 받았었습니다.
당시 저와 제 친구들이 졸업작품으로 음성인식을 했던것을 기억해주시며 대회의 음성인식 모듈 개발을 맡겨주셨어서 해당 태스크에 참여해본 경험이 있었습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147769911-44f7c3b2-9a2d-4b51-92e8-8ed1570ff8c0.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;해당 트랙의 1등, 2등팀과도 개인적인 연이 있어서 관심을 계속 두고 있었던 대회였는데 이번에는 직접 회사 대표로 참가하게 됐습니다.
다만 이 대회는 이전에 참여했던 AI 온라인 경진대회와는 다르게 학습 데이터를 제공해주는 것이 아닌 학습 데이터를 각자 알아서 만들어서
모델을 학습하고 주최측이 보유한 테스트셋으로 모델 성능을 평가하는 대회였습니다. 일반적인 컴피티션과는 다른 형식이고,
인공지능 성능에 가장 중요한 데이터를 직접 제작해야한다는 점, 전년도, 전전년도 해당 트랙 우수팀들은 이미 수억원의 사업화지원금으로
데이터를 많이 만들었을 것이라는 점 등 쉽지는 않은 조건이였습니다. 그럼에도 불구하고, 나는 할 수 있다! 라는 생각으로 패기롭게 도전했으나,
아쉽게도 이번에는 3위에 그치고 말았습니다. 😭&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147770165-5fc7368a-a7f2-476b-ad50-7c45c591d8ef.png&quot; width=&quot;350&quot;&gt;  
&lt;p&gt;IITP 원장상을 수여받긴 했지만 1위를 못했다는 사실이 아직도 너무나 아깝습니다.. 회사 대표로 나가서 1등을 하지 못했다는 사실에 회사에도
미안한 마음입니다. 그래서 내년에 인공지능 온라인 경진대회, 그랜드 챌린지 등의 대회가 열린다면 나가서 꼭!! &lt;strong&gt;1등&lt;/strong&gt;을 하고야 말겠다는
다짐을 했습니다.&lt;/p&gt;
&lt;h2&gt;보람, 조금 더 여유를 가지고&lt;/h2&gt;
&lt;p&gt;글이 길어져서 원래 적고 싶었던 많은 내용들을 다 적지는 못했습니다만,
이렇게 돌아보니 올 한 해는 정말 많은 일이 있었던 것 같습니다.
대학교를 졸업한 첫 해이자, 창업의 첫 해로서 기쁘고 보람찬 일도 많았고 아쉬운 일도 많았습니다.
내년에는 아쉬움보다는 기쁘고 보람찬 일이 더 많았으면 좋겠습니다.&lt;/p&gt;
&lt;p&gt;슬럼프를 극복하기 위해 시작한 운동은 지금까지는 다행히도 꾸준히 하고 있습니다.
내년에는 더 열심히 해서 대학생때의 몸으로 돌아갔으면 좋겠습니다. 🙏 그리고 그동안 제가 조금은
여유를 가지지 못했던 것 같습니다. 오히려 마음의 여유가 없어서 일이 더 더뎌지고, 준비를 충분히 못한채로 일을 시작해서
일이 꼬이는 경우도 많았습니다. 내년에는 조금 더 여유를 가지고 멀리 보며 살아야겠습니다.&lt;/p&gt;
&lt;p&gt;그리고 최근에 제 주위에 많은 분들이 좋은 소식이 들려오고 있어서 기쁩니다. 항상 서로 응원해주는 여자친구도 원하는 기업에 합격했고,
종종 코딩 질문을 해오던 군대 동기도 원하던 대기업 은행으로 이직을 성공했습니다. 그리고 튜닙 인턴으로 있던 대학교 후배들과 일주일에 한 번씩
면담하면서 고민을 들어주거나 나름의 조언을 해줬는데 원하는 대학원, 원하는 기업에 최종 합격했다는 소식이 들려와서 꽤 기뻤습니다.
내년에도 주위 분들과 함께 서로 좋은 관계를 이어나가며 시너지를 내면 좋겠습니다.&lt;/p&gt;
&lt;h2&gt;올해 개인 기록&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;특별한 일
&lt;ul&gt;
&lt;li&gt;공동 창업 🚀&lt;/li&gt;
&lt;li&gt;시드 투자 유치 🌱&lt;/li&gt;
&lt;li&gt;대학교 졸업 👨‍🎓&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;올해 공개한 오픈소스 (⭐ 2k)
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/kakaobrain/pororo&quot;&gt;Pororo&lt;/a&gt; (⭐️ 1.1k)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/openspeech-team/openspeech&quot;&gt;OpenSpeech&lt;/a&gt; (⭐ 336)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sooftware/conformer&quot;&gt;Conformer&lt;/a&gt; (⭐ 298)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tunib-ai/tunib-electra&quot;&gt;TUNiB Electra&lt;/a&gt; (⭐ 84)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sooftware/k-startups&quot;&gt;k-startups&lt;/a&gt; (⭐ 155)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sooftware/nlp-tasks&quot;&gt;nlp-tasks&lt;/a&gt; (⭐ 38)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sooftware/luna-transformer&quot;&gt;luna-transformer&lt;/a&gt; (⭐ 25)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sooftware/pytorch-lr-scheduler&quot;&gt;pytorch-lr-scheduler&lt;/a&gt; (⭐ 25)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;받은 상
&lt;ul&gt;
&lt;li&gt;정보통신기획평가원장상 (IITP)&lt;/li&gt;
&lt;li&gt;정보통신산업진흥원장상 (NIPA)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;컴피티션
&lt;ul&gt;
&lt;li&gt;2021 AI Grand Challenge 3위&lt;/li&gt;
&lt;li&gt;2021 AI 온라인 경진대회 1위&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;발표
&lt;ul&gt;
&lt;li&gt;2021 SSDC - TUNiB Electra 개발기&lt;/li&gt;
&lt;li&gt;2021 LangCon - 한국어 음성 인식&lt;/li&gt;
&lt;li&gt;2021 AI Pangyo Camp, TUNiB - 2021 AI 온라인 경진대회 노하우&lt;/li&gt;
&lt;li&gt;광운대학교 특강 (컴퓨터공학과 3,4학년 대상)&lt;/li&gt;
&lt;li&gt;광운대학교 특강 (전자통신공학과 1학년 대상)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;블로그
&lt;ul&gt;
&lt;li&gt;44개의 포스트&lt;/li&gt;
&lt;li&gt;sooftware.io로 블로그 이전&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;논문
&lt;ul&gt;
&lt;li&gt;“Open-Source Toolkit for end-to-end korean speech recognition”, ELSEVIER, SIMPAC (Software Impacts)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Slack Bot]]></title><description><![CDATA[Slack Bot Python과 Slack API를 사용하여, 특정 채널에 자동으로 글을 올리거나 댓글을 달아주는 슬랙봇을 만들어보겠습니다. 두 개의 과정으로 진행되는데, 첫 번째는 Slack API에 bot을 등록하는 것이고 두 번째는 등록된 bot…]]></description><link>https://sooftware.github.io/slack_bot/</link><guid isPermaLink="false">https://sooftware.github.io/slack_bot/</guid><pubDate>Thu, 23 Dec 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Slack Bot&lt;/h1&gt;
&lt;p&gt;Python과 Slack API를 사용하여, 특정 채널에 자동으로 글을 올리거나 댓글을 달아주는 슬랙봇을 만들어보겠습니다.&lt;/p&gt;
&lt;p&gt;두 개의 과정으로 진행되는데,&lt;br&gt;
첫 번째는 &lt;strong&gt;Slack API에 bot을 등록하는 것&lt;/strong&gt;이고&lt;br&gt;
두 번째는 &lt;strong&gt;등록된 bot을 Python으로 활용하는 것&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;h2&gt;Slack API에 bot을 등록하는 것&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://api.slack.com/apps&quot;&gt;Slack API&lt;/a&gt;에 접속하여 &lt;code class=&quot;language-text&quot;&gt;Create An App&lt;/code&gt;을 클릭합니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/147100372-5c1966a6-7ff0-4df3-8aae-70c84c672f8e.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;br&gt;  
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;From scratch&lt;/code&gt;를 클릭합니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/147100695-d47f7fc3-b252-4e67-8d95-6c9b8478556d.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;앱 이름을 작성하고, 슬랙 작업 환경을 선택한 후에 &lt;code class=&quot;language-text&quot;&gt;Create App&lt;/code&gt;을 클릭합니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/147100979-a4aeabc5-a864-4260-acf1-cce5a0acfe9f.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;br&gt; 
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;Bots&lt;/code&gt;를 클릭합니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/147101118-9b1e2594-cd69-4b48-b29b-ccdcf9fedc45.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
 &lt;br&gt; 
&lt;p&gt;왼쪽 상단에는 입력한 앱 이름이 나오는 것을 확인할 수 있습니다.&lt;br&gt;
&lt;code class=&quot;language-text&quot;&gt;Review Scopes to Add&lt;/code&gt;를 클릭하여 앱 관련 권한을 설정할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/147101379-3229204f-7352-43db-b55e-4383f4fab42c.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
 &lt;br&gt; 
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;Install App to Workspace&lt;/code&gt; 버튼이 비활성화 되어있는데 적어도 하나의 권한(Scope)를 설정해야 활성화되는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/147101859-9d71f523-7d08-42e6-8bc4-11c4cc7e8960.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;스크롤을 내리면 &lt;code class=&quot;language-text&quot;&gt;Scopes&lt;/code&gt;를 설정하는 부분이 나타납니다.  &lt;code class=&quot;language-text&quot;&gt;Bot Token Scopes&lt;/code&gt; 부분에 있는 &lt;code class=&quot;language-text&quot;&gt;Add an OAuth Scope&lt;/code&gt;버튼을 클릭하여 관련 권한을 설정하면 됩니다.&lt;br&gt;
&lt;a href=&quot;https://api.slack.com/methods&quot;&gt;Slack API Methods&lt;/a&gt;에 가면 다양한 메소드를 확인하실 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/147102209-013a72c2-c929-422f-9093-0cab18689cde.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;예를 들어, &lt;a href=&quot;https://api.slack.com/methods/conversations.history&quot;&gt;conversations.history&lt;/a&gt;라는 메소드를 클릭한 사진을 가져왔습니다.&lt;br&gt;
이 메소드를 호출할 때 필요한 권한들이나 1분 동안 몇 번정도 호출할 수 있는지, Arguments, 사용법 등이 자세하게 설명되어 있는 것을 알 수 있습니다.  이 메소드의 경우 &lt;code class=&quot;language-text&quot;&gt;Rate limits&lt;/code&gt;가 Tier 3인데 클릭하면 자세한 정보가 나오고 &lt;code class=&quot;language-text&quot;&gt;50+ per minute&lt;/code&gt; 정도로 제한이 되는 것을 확인하실 수 있습니다.&lt;br&gt;
이처럼 용도에 맞게 메소드를 선택하시고, 권한을 설정해주시면 될 것 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/147104340-3d4908d7-6a18-48cc-bf21-664f1750f313.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;권한을 설정하면 &lt;code class=&quot;language-text&quot;&gt;Install App to Workspace&lt;/code&gt; 버튼이 활성화되고, 클릭하여 &lt;code class=&quot;language-text&quot;&gt;허용&lt;/code&gt; 버튼을 누릅니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/147105473-1e2c9f7e-06ef-4b46-93b8-b81a8a38ea64.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;Bot User OAuth Token&lt;/code&gt;이 나오고, 나중에 Slack API를 호출할 때 사용되니 잘 저장해둡니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/147106099-22df28c9-45f6-44fe-a348-95c9a847a132.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;그리고 Slack Bot 앱을 원하는 채널에 추가해주면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/147106614-7a82d9e1-9817-45e5-9671-0e775cd0f21a.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;br&gt;
&lt;br&gt; 
&lt;br&gt;
&lt;br&gt; 
&lt;h2&gt;등록된 bot을 Python으로 활용하는 것&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;slack_sdk&lt;/code&gt; 라이브러리를 사용할 것이기 때문에 터미널에서 아래 명령어로 설치합니다.&lt;/p&gt;
&lt;br&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;pip install slack_sdk&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;br&gt; 
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;__init__&lt;/code&gt;에서 아까 저장했던 token id를 &lt;code class=&quot;language-text&quot;&gt;WebClient&lt;/code&gt; 파라미터로 넣어줍니다.&lt;br&gt;
&lt;code class=&quot;language-text&quot;&gt;get_channel_id&lt;/code&gt; 메소드는 channel 이름을 파라미터로 넘겨주면 channel id를 리턴해주는 메소드입니다.&lt;br&gt;
여기서 &lt;code class=&quot;language-text&quot;&gt;conversations_list&lt;/code&gt; 메소드를 사용하는데, types로 “public_channel”을 넘겨주면 public 채널만 검색이 가능하고,
“private_channel”을 넘겨주면 bot이 추가되어있는 private 채널만 검색이 가능합니다.&lt;/p&gt;
&lt;br&gt;  
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; slack_sdk &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; WebClient


&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SlackAPI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; token&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; channel_name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;client &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; WebClient&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;token&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;channel_type &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;public_channel&quot;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# or &quot;private_channel&quot;&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;channel_id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; get_channel_id&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;channel_name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_channel_id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; channel_name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;conversations_list&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;types&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;channel_type&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        channels &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;channels&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        channel &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;lambda&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; channel_name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; channels&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        channel_id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; channel&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; channel_id&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;  
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;get_message_ts&lt;/code&gt; 메소드는 &lt;code class=&quot;language-text&quot;&gt;conversations_history&lt;/code&gt; 메소드를 사용하여 메시지의 timestamp(ts)와 text 내용을 파싱하여 리턴해주는 함수입니다.
파라미터 &lt;code class=&quot;language-text&quot;&gt;oldest&lt;/code&gt;는 메시지 검색을 처음부터 하지말고 해당 시간부터 해달라고하는 파라미터입니다.&lt;br&gt;
이 &lt;code class=&quot;language-text&quot;&gt;oldest&lt;/code&gt; 값을 계속 수정해주면 봇이 채널의 정보를 계속 가져올 때, 중복되지 않고 새로운 정보만 가져올 수 있도록 할 수 있습니다.&lt;/p&gt;
&lt;br&gt;  
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_message_ts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; end_ts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    message_info &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;conversations_history&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;channel&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;channel_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; oldest&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;end_ts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    messages &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;messages&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;        
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; message &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; messages&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        message_ts &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ts&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        message_text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        message_info&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ts&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; message_ts&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; message_text&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; message_info&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;  
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;post_thread_message&lt;/code&gt; 메소드는 &lt;code class=&quot;language-text&quot;&gt;chat_postMessage&lt;/code&gt; 메소드를 사용하여 원하는 채널, 원하는 스레드(메시지)에 댓글을 달아주는 함수입니다.&lt;br&gt;
파라미터로 &lt;code class=&quot;language-text&quot;&gt;thread_ts&lt;/code&gt;를 빼면, 원하는 채널에 스레드(메시지)를 남길 수 있습니다.&lt;/p&gt;
&lt;br&gt;  
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;post_thread_message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message_ts&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;chat_postMessage&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        channel&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;channel_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        text&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        thread_ts&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;message_ts
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt; 
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;post_emoji&lt;/code&gt; 메소드는 &lt;code class=&quot;language-text&quot;&gt;reactions_add&lt;/code&gt; 메소드를 사용하여 원하는 채널, 원하는 스레드(메시지)에 이모지를 달아주는 함수입니다.&lt;br&gt;
위의 &lt;code class=&quot;language-text&quot;&gt;post_thread_message&lt;/code&gt; 메소드와 같이 보통 여기서는 스레드(메시지)를 timestamp로 구분합니다.&lt;br&gt;
여기서는 이모지 &lt;code class=&quot;language-text&quot;&gt;&quot;smile&quot;&lt;/code&gt;을 사용하였는데, 직접 만든 이모지 뿐만 아니라 등록되어 있는 이모지의 이름을 적어주시면 됩니다.&lt;/p&gt;
&lt;br&gt; 
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;post_emoji&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message_ts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;reactions_add&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        channel&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;channel_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;smile&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        timestamp&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;message_ts
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt; 
&lt;p&gt;최종적으로 다 합친 코드입니다.&lt;/p&gt;
&lt;br&gt; 
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; slack_sdk &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; WebClient


&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SlackAPI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; token&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; channel_name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;client &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; WebClient&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;token&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;channel_type &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;public_channel&quot;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# or &quot;private_channel&quot;&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;channel_id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; get_channel_id&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;channel_name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_channel_id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; channel_name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;conversations_list&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;types&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;channel_type&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        channels &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;channels&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        channel &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;lambda&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; channel_name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; channels&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        channel_id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; channel&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; channel_id
        
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_message_ts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; end_ts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        message_info &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;conversations_history&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;channel&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;channel_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; oldest&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;end_ts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
        messages &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;messages&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;        
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; message &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; messages&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            message_ts &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ts&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
            message_text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
            message_info&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ts&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; message_ts&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; message_text&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; message_info

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;post_thread_message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message_ts&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;chat_postMessage&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            channel&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;channel_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            text&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            thread_ts&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;message_ts
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
       
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;post_emoji&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message_ts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;reactions_add&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            channel&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;channel_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;smile&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            timestamp&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;message_ts
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt; 
&lt;h1&gt;Reference&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wooiljeong.github.io/python/slack-bot&quot;&gt;https://wooiljeong.github.io/python/slack-bot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://api.slack.com/methods&quot;&gt;https://api.slack.com/methods&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Fine-grained Post-training for Improving Retrieval-based Dialogue Systems Paper Review]]></title><description><![CDATA[Fine-grained Post-training for Improving Retrieval-based Dialogue Systems Paper Review Paper: https://aclanthology.org/2021.naacl-main.12…]]></description><link>https://sooftware.github.io/bert_fp/</link><guid isPermaLink="false">https://sooftware.github.io/bert_fp/</guid><pubDate>Sat, 18 Dec 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Fine-grained Post-training for Improving Retrieval-based Dialogue Systems Paper Review&lt;/h1&gt;
&lt;img src=&quot;https://d3i71xaburhd42.cloudfront.net/9f359007e9af7e49e95b3bba3c8621c6fa2f8cca/4-Figure1-1.png&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Paper: &lt;a href=&quot;https://aclanthology.org/2021.naacl-main.122/&quot;&gt;https://aclanthology.org/2021.naacl-main.122/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Code: &lt;a href=&quot;https://github.com/hanjanghoon/BERT_FP&quot;&gt;https://github.com/hanjanghoon/BERT_FP&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;NAACL 2021에 억셉된 논문이다. 서강대 NLP 연구실, LG AI Research 팀에서 작성했다. Dialogue Retrieval 관련 논문인데,
방법이 심플하면서도 성능 좋다. (Ubuntu Dialogue 등 몇 데이터셋에서 SOTA를 찍었다)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Utterance Relevance Classification (URC)&lt;/strong&gt; 이 핵심인데, pre-training 된 모델을 가져와서 추가적으로 post-training을 시키는데,
MLM (Masked Language Modeling) + NSP (Next Sentence Prediction) 중 NSP를 dialogue 태스크에 맞게 조금 변형한다.&lt;/p&gt;
&lt;p&gt;[Context + &amp;#x3C;|sep|&gt; +  Response] 형식의 입력을 주고, 이 Response가 1. Correct Response 2. Random Utterance 3. Random Utterance in the same dialogue 중
어느 클래스에 속하는지 3개로 분류하는 식으로 학습한다. 이렇게 하면 기존의 Context - Response를 두고 적합한지 (Positive),
부적합한지 (Negative) 를 판단하는 binary classification 태스크로 문제를 풀 때보다
주어진 대화 데이터를 더 효과적으 활용한다는 면에서 데이터 오그멘테이션의 효과도 있게 된다.&lt;/p&gt;
&lt;p&gt;이 post-training은 MLM Loss (dynamic masking) + URC Loss로 학습이 되며,
이후 기존 response selection 태스크로 파인튜닝해서 사용 가능하다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[K-Startups (Korea AI Startups)]]></title><description><![CDATA[K(orea) Startups Intro 한국에 있는 테크 스타트업들 리스트와 간단한 설명을 기록합니다. ‘내가 아는 스타트업들이 얼마나 될까?’ 라는 간단한 생각을 시작으로 기록하게 됐습니다. 허훈님의 nlp-startups, 염기웅님의 Korea…]]></description><link>https://sooftware.github.io/k-startups/</link><guid isPermaLink="false">https://sooftware.github.io/k-startups/</guid><pubDate>Sun, 05 Dec 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;K(orea) Startups&lt;/h1&gt;
&lt;h2&gt;Intro&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;한국에 있는 테크 스타트업들 리스트와 간단한 설명을 기록합니다.&lt;/li&gt;
&lt;li&gt;‘내가 아는 스타트업들이 얼마나 될까?’ 라는 간단한 생각을 시작으로 기록하게 됐습니다.&lt;/li&gt;
&lt;li&gt;허훈님의 &lt;a href=&quot;https://github.com/Huffon/nlp-startups&quot;&gt;nlp-startups&lt;/a&gt;, 염기웅님의 &lt;a href=&quot;https://github.com/gyunggyung/Korea-Startups&quot;&gt;Korea-Startups&lt;/a&gt; 형식을 참고했습니다.&lt;/li&gt;
&lt;li&gt;제가 잘못알고 있거나 새롭게 추가하고 싶은 기업이 있으시다면 &lt;a href=&quot;https://github.com/sooftware/k-startups/issues&quot;&gt;이슈&lt;/a&gt;에 남겨주시면 감사하겠습니다.&lt;/li&gt;
&lt;li&gt;순서에 따로 의미는 없으며, 생각나는 순서로 작성했습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Startups&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://www.tunib.ai/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;TUNiB (튜닙)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 유명 깃허브 스타이자 자연어처리 리서쳐이신 &lt;strong&gt;박규병&lt;/strong&gt;님을 필두로 &lt;strong&gt;카카오브레인&lt;/strong&gt; 자연어처리 팀 출신들이 설립한 자연어처리 테크 스타트업. &lt;strong&gt;글로벌 페르소나 챗봇 서비스&lt;/strong&gt;를 개발하고 있으며 2021 AI 온라인 경진대회 1위 등 국내 컴피티션에서의 좋은 성적들과 &lt;a href=&quot;https://github.com/tunib-ai/parallelformers&quot;&gt;&lt;strong&gt;Parallelformers&lt;/strong&gt;&lt;/a&gt;, &lt;a href=&quot;https://github.com/tunib-ai/tunib-electra&quot;&gt;&lt;strong&gt;TUNiB-Electra&lt;/strong&gt;&lt;/a&gt; 등의 오픈소스 기여 등으로 자연어처리 기술력을 인정받고 있다. 특히 최근에는 &lt;strong&gt;Large-Scale 언어 모델&lt;/strong&gt; 개발에 힘쓰고 있다. 21년 하반기에 &lt;strong&gt;30억 규모의 시드 투자&lt;/strong&gt;를 마무리했다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.07)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.upstage.ai/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Upstage (업스테이지)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : AI 분야의 세계적인 석학이신 홍콩과기대 &lt;strong&gt;김성훈&lt;/strong&gt; 교수님(전 &lt;strong&gt;네이버 클로바&lt;/strong&gt; 헤드)을 필두로 네이버, 카카오, 엔비디아 핵심 인력들이 나와 만든 인공지능 스타트업. 김성훈 교수님 외에도 전 클로바 OCR팀 리더 &lt;strong&gt;이활석&lt;/strong&gt; 박사님, 파파고 AI 모델 리더이자 Github 에 있는 한국어 NLP 오픈소스 중 최다 추천을 받은 Konlpy 를 개발한 &lt;strong&gt;Lucy Park&lt;/strong&gt;님, 캐글 세계 랭킹 6위 김상훈님 등 AI 업계에서 유명하신 분들이 다수 포진되어 있다. 설립 1년만에 &lt;strong&gt;300억 규모의 시리즈 A&lt;/strong&gt;를 받으며 이례적인 속도로 성장하고 있다. 매출뿐 아니라 &lt;a href=&quot;https://github.com/KLUE-benchmark/KLUE&quot;&gt;&lt;strong&gt;KLUE&lt;/strong&gt;&lt;/a&gt; 등의 연구적 성과, Kaggle과 같은 세계적인 대회에서의 1위 등 여러 면에서 뛰어난 성과를 보이고 있다. 현재 AI 기술을 쉽게 도입할 수 있게 도와주는 AI Pack 을 개발해 기업이 고유의 핵심 비즈니스에 집중할 수 있도록 도와주고 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.07)&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://career.hyperconnect.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Hyperconnect (하이퍼커넥트)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 영상 메신저 서비스 &lt;a href=&quot;https://apps.apple.com/kr/app/%EC%95%84%EC%9E%90%EB%A5%B4-%EC%83%88-%EC%B9%9C%EA%B5%AC%EB%A1%9C-%EC%9D%BC%EC%83%81%EC%9D%84-%EC%83%88%EB%A1%9C%EA%B3%A0%EC%B9%A8/id972558973&quot;&gt;&lt;strong&gt;아자르(Azar)&lt;/strong&gt;&lt;/a&gt;와 라이브 동영상 서비스 &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.movefastcompany.bora&amp;#x26;hl=ko&amp;#x26;gl=US&quot;&gt;&lt;strong&gt;하쿠나 라이브&lt;/strong&gt;&lt;/a&gt;로 유명한 한국의 스타트업. 2021년 상반기에 미국의 매치그룹에 2조에 인수됐다. CVPR, INTERSPEECH와 같은 세계적인 학회에 논문을 꾸준히 게재하는 등 연구적으로도 뛰어난 성과를 보이고 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.lunit.io/ko&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Lunit (루닛)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 카이스트 박사 출신 분들이 설립한 회사로, 딥러닝 기술을 기반으로 한 &lt;strong&gt;인공지능을 통해 암을 포함한 질병의 진단 및 치료에 기여하는 솔루션을 개발&lt;/strong&gt;하는 스타트업. 각종 국제 AI 대회에서 구글, 마이크로소프트, IBM 등의 글로벌 기업과 하버드 의대팀을 제치고 최상위권에 오를 정도로 기술력이 뛰어나며 코스닥 기술특례상장을 위한 기술성 평가를 &lt;strong&gt;역대 최고 등급인 AA-AA&lt;/strong&gt;로 통과했다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.furiosa.ai/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Furiosa AI (퓨리오사 AI)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : &lt;strong&gt;인공지능 반도체 스타트업&lt;/strong&gt;으로 최근 자체 개발 실리콘 칩 ‘&lt;strong&gt;워보이(Warboy)&lt;/strong&gt;’가 글로벌 AI 반도체 성능 경연대회 &lt;strong&gt;엠엘퍼프(MLPerf)&lt;/strong&gt; 에서 미국 &lt;strong&gt;엔비디아(NVIDIA)&lt;/strong&gt; 를 제치는 등 우수한 기술력을 보유하고 있다. 최근 &lt;strong&gt;800억원 규모의 시리즈 B&lt;/strong&gt; 투자를 유치했다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://scatterlab.co.kr/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Scatter Lab (스캐터랩)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 2021년 초 한국을 강타한 일상대화 챗봇 &lt;a href=&quot;https://luda.ai/&quot;&gt;&lt;strong&gt;이루다&lt;/strong&gt;&lt;/a&gt;를 만든 스타트업. 이루다 서비스 외에도 &lt;a href=&quot;https://scienceoflove.co.kr/&quot;&gt;&lt;strong&gt;연애의 과학&lt;/strong&gt;&lt;/a&gt;과 같이 성공한 서비스가 있다. 높은 수준의 자연어처리 기술력을 보유하고 있으며 국내 어느 기업들보다도 &lt;strong&gt;많은 대화 데이터&lt;/strong&gt;를 보유하고 있다. 이전에 있었던 여러 문제점을 개선해서 최근에 다시 이루다 서비스를 시작할 예정이라고 한다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://neosapience.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Neosapience (네오사피엔스)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 국내에서 대표적인 음성 합성 서비스인 &lt;a href=&quot;https://neosapience.com/&quot;&gt;&lt;strong&gt;타입캐스트(Typecast)&lt;/strong&gt;&lt;/a&gt;를 운영하고 있다. 높은 수준의 음성 합성 기술력을 보유하고 있으며 관련해서 연구성과도 지속적으로 내고 있다. 최근에는 단순한 음성합성을 넘어서 랩을 하는 음성 합성 기술까지 선보이고 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.voyagerx.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Voyager X (보이저엑스)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 세이클럽(네오위즈), B612(네이버) 등을 성공시킨 &lt;strong&gt;남세동&lt;/strong&gt;님이 AI 서비스 제작을 목표로 설립한 스타트업이다. 영상편집 서비스 &lt;a href=&quot;https://vrew.voyagerx.com/ko/&quot;&gt;&lt;strong&gt;Vrew&lt;/strong&gt;&lt;/a&gt;, 모바일 스캐너 &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.voyagerx.scanner&amp;#x26;hl=ko&amp;#x26;gl=US&quot;&gt;&lt;strong&gt;vFlat&lt;/strong&gt;&lt;/a&gt; 등 다양한 분야에 AI 기술을 접목시키는 서비스를 개발하고 있다. 21년 상반기에 &lt;strong&gt;300억원 규모의 시리즈 A 투자&lt;/strong&gt;를 유치했다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.skelterlabs.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Skelter Labs (스켈터랩스)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 대표님이 구글코리아 대표 출신이며, 구글코리아 출신들이 다수 포진되어 있다고 한다. 대화 엔진, 음성 엔진, 추천, 예측 등 다양한 AI 기술을 내세우고 있다. 대화형 AI 솔루션 &lt;a href=&quot;https://aiq.skelterlabs.com/product/chatbot&quot;&gt;&lt;strong&gt;AIQ TALK&lt;/strong&gt;&lt;/a&gt;, 비정형 데이터를 분석해 개인 맞춤형 추천을 해주는 초개인화 솔루션 &lt;a href=&quot;https://aiq.skelterlabs.com/product/recommendation&quot;&gt;&lt;strong&gt;AIQ AWARE&lt;/strong&gt;&lt;/a&gt; 등의 서비스가 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://mathpresso.com/ko&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Mathpresso (매스프레소)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 수학 문제의 사진을 찍어 올리면 문제 풀이를 제시해주는 서비스인 &lt;a href=&quot;https://qanda.ai/ko&quot;&gt;&lt;strong&gt;QANDA(콴다)&lt;/strong&gt;&lt;/a&gt;를 운영중인 스타트업. 해외 50여개 국가에서 서비스 중이며, 전세계 월간 사용자(MAU)는 1200만 명에 이른다. 누적 앱 다운로드 수 4500만 건으로 상당히 성공한 서비스를 운영중이다. 서비스에 필요한 OCR, NLP 등의 기술력을 보유하고 있으며, 총 투자유치 1,220억으로 대형 스타트업이다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://modulabs.co.kr/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Modu Labs (모두의연구소)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 취업준비생부터 현업 엔지니어들까지 다양한 구성원들이 모여서 함께 연구하며 결과물을 만드는 연구 모임을 주관해주는 스타트업. 교육 프로그램 &lt;a href=&quot;https://modulabs.co.kr/apply-flip17/&quot;&gt;&lt;strong&gt;풀잎스쿨&lt;/strong&gt;&lt;/a&gt;, 인공지능 혁신 학교 &lt;a href=&quot;https://aiffel.oopy.io/&quot;&gt;&lt;strong&gt;AIFFEL&lt;/strong&gt;&lt;/a&gt; 등을 운영중이며 AI 교육 업계에 많은 기여를 해주고 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.rtzr.ai/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Return Zero (리턴제로)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 카카오 출신 엔지니어들이 설립한 스타트업이며, 통화 내용을 텍스트로 옮겨주는 서비스인 &lt;a href=&quot;https://www.vitoapp.io/&quot;&gt;&lt;strong&gt;VITO&lt;/strong&gt;&lt;/a&gt;를 운영중이다. 핵심 기술은 음성 인식으로, 최근에 코리아 AI 스타트업 TOP 100에 선정될 정도로 유망성을 인정받았다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://sendbird.com/ko&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Sendbird (센드버드)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 채팅 API를 판매하는 SaaS(Software-as-a-Service) B2B 스타트업이다. 21년 상반기에 1억달러 투자 유치를 하며 유니콘이 되었다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.07)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.superb-ai.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Superb AI (슈퍼브 AI)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : SKT 연구원 출신들이 설립한 스타트업. 머신러닝 데이터 플랫폼인 &lt;strong&gt;스위트(Suite)&lt;/strong&gt; 서비스를 운영중이다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.07)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://riiid.com/ko/main&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Riiid (뤼이드)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 맞춤형 토익 공부 어플리케이션인 &lt;a href=&quot;https://play.google.com/store/apps/details?id=co.riiid.vida&amp;#x26;hl=ko&amp;#x26;gl=US&quot;&gt;&lt;strong&gt;뤼이트 튜터 (구 산타토익)&lt;/strong&gt;&lt;/a&gt;를 운영중이다. &lt;strong&gt;누적 투자 2,800억&lt;/strong&gt;으로 대형 스타트업이다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://selectstar.ai/?gclid=Cj0KCQiA47GNBhDrARIsAKfZ2rA_N6dFN-Yih-DWF61TlO-IwlMgIHWwyHV_xSRKfr_JG4HMw0WuVyQaAiXSEALw_wcB&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;SELECTSTAR (셀렉트스타)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 크라우드소싱으로 AI 학습에 필요한 데이터를 수집 및 가공해주는 서비스를 제공해주는 스타트업. 전 세계적으로 데이터 수집∙가공 분야의 기업들이 높은 가치를 인정받는 추세를 고려하면 앞으로의 성장가능성이 더욱 기대되는 스타트업이다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.dunamu.com/views/01_main_ko.html&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Dunamu (두나무)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 한국의 암호화폐 거래소인 &lt;a href=&quot;https://upbit.com/&quot;&gt;&lt;strong&gt;업비트&lt;/strong&gt;&lt;/a&gt;를 운영중인 기업. 21년 12월 기준으로 &lt;strong&gt;기업가치를 약 18조원&lt;/strong&gt;으로 평가받고 있는 유니콘 스타트업이다.  &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://supertone.ai/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Supertone (슈퍼톤)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 서울대 &lt;strong&gt;이교구&lt;/strong&gt; 교수님이 2020년에 설립한 초기 스타트업으로 21년 초에 ‘노래하는 AI’를 선보이며 세간의 이목을 끌었다. 세계 최고 음성 학회인 ICASSP, INTERSPEECH에서도 좋은 성과를 보이고 있으며, 21년 상반기에 BTS가 속해있는 &lt;strong&gt;빅히트 엔터테인먼트가 40억원을 투자&lt;/strong&gt;했다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://artlab.ai/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;ART Lab (아트랩)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 인공지능 기술로 사용자별로 특화된 스킨케어 서비스를 제공해주는 기술을 개발하는 스타트업. &lt;a href=&quot;https://manifold.fit/&quot;&gt;&lt;strong&gt;매니폴드&lt;/strong&gt;&lt;/a&gt;라는 서비스를 운영하고 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://voithru.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Voithru (보이스루)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 유튜버/스트리머들을 대상으로 하는 영상 번역 서비스 &lt;a href=&quot;https://jamake.io/ko/&quot;&gt;&lt;strong&gt;자메이크(JAMAKE)&lt;/strong&gt;&lt;/a&gt;를 주 서비스로하는 스타트업. 자체적으로 &lt;strong&gt;음성인식, 번역&lt;/strong&gt; 등의 기술을 보유하고 있으며 여러 인공지능 관련 대회에서 우수한 성적을 내며 기술력을 인정받고 있다. 음성인식, 번역 후에 전문 번역가가 마무리 번역을 함으로써 번역 성능 100%라는 타이틀을 내세우고 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.atlaslabs.ai/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Atlas Labs (아틀라스랩스)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : &lt;strong&gt;음성인식&lt;/strong&gt; 기술을 메인으로 하는 스타트업. 자체 음성인식 엔진인 &lt;strong&gt;ZEROTH&lt;/strong&gt;를 활용해서 AI 통화 서비스인 &lt;a href=&quot;https://www.getswitch.app/&quot;&gt;&lt;strong&gt;SWITCH&lt;/strong&gt;&lt;/a&gt;를 운영하고 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://actionpower.kr/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Action Power (액션파워)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 인공지능 받아쓰기 솔루션 &lt;a href=&quot;https://daglo.ai/&quot;&gt;&lt;strong&gt;다글로(Daglo)&lt;/strong&gt;&lt;/a&gt; 서비스를 운영하는 스타트업. &lt;strong&gt;도메인 특화된 음성인식 서비스&lt;/strong&gt;를 주 서비스로 하고 있다. 최근 &lt;strong&gt;133억원 규모의 시리즈 A&lt;/strong&gt; 투자를 유치했다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.yanolja.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;yanolja (야놀자)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 호텔, 모텔 예약 서비스인 &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.cultsotry.yanolja.nativeapp&amp;#x26;hl=ko&amp;#x26;gl=US&quot;&gt;&lt;strong&gt;야놀자(yanolja)&lt;/strong&gt;&lt;/a&gt; 서비스를 메인으로 하는 스타트업. 21년 12월 기준 &lt;strong&gt;기업 가치 약 10조원&lt;/strong&gt;으로 평가받는 유니콘 스타트업이다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.kurly.com/shop/main/index.php&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Market Kurly (마켓컬리)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 수도권과 충청권, 대구권, 부산/울산권 을 한정으로 당일 주문 시 다음 날 새벽 배송되는 샛별배송 배달 서비스를 하고 있다. 21년 12월 기준 &lt;strong&gt;기업 가치 약 4조원&lt;/strong&gt;으로 평가받는 유니콘 스타트업이다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://lbox.kr/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;LBox (엘박스)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 판례 검색 서비스를 제공하는 스타트업. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://getliner.com/en&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;LINER (라이너)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 웹페이지 내 하이라이팅 기능을 제공하는 서비스 &lt;a href=&quot;https://getliner.com/en?fbclid=IwAR0lVffAHd7JbkH3dkUFc8r57lcHWL-_tvVZc7yzHmsnLmOd0M2thCexqNg&quot;&gt;&lt;strong&gt;LINER&lt;/strong&gt;&lt;/a&gt;를 운영하는 스타트업. 단 7명의 멤버로 50억 규모의 시리즈 A를 유치했다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://nftbank.ai/landing&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;NFT Bank (NFT뱅크)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 최근 핫한 &lt;strong&gt;NFT(Non-Fungible Token)&lt;/strong&gt; 금융 및 자산관리 플랫폼 서비스를 운영하고 있다. 세계 최대 엑셀러레이터인 와이컴비네이터 (Y-Combinator) 기업으로 선정되기도 했다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://www.dalchaebi.shop/13&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;DAL Company (디에이엘컴퍼니)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 맞춤 월경 서비스 &lt;a href=&quot;http://www.dalchaebi.shop/13&quot;&gt;&lt;strong&gt;달채비(Dalchaebi)&lt;/strong&gt;&lt;/a&gt;를 메인으로 하는 스타트업. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.42maru.ai/kr/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;42 Maru (포티투마루)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : &lt;strong&gt;Semantic QA&lt;/strong&gt;를 연구하며 글로벌 기계독해 경진대회 &lt;strong&gt;SQuAD&lt;/strong&gt;에서 우수한 성적을 거둔 이력이 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://lionrocket.ai/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Lion Rocket (라이언로켓)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : &lt;strong&gt;영상/음성 합성&lt;/strong&gt; 기술을 주력으로 하는 스타트업. 은행들과 가상 인간 제작 프로젝트 협업 등 다양한 기업과 협업을 하고 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.07)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://www.pulse9.net/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Pulse9 (펄스나인)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 가상 아이돌 &lt;a href=&quot;https://www.youtube.com/channel/UCSnQSjVVHs5bHKIpTJ7vqoA&quot;&gt;&lt;strong&gt;이터니티(ETERNITY)&lt;/strong&gt;&lt;/a&gt;를 만드는 스타트업. 21년 12월 기준 가장 많이본 영상은 200만 뷰를 기록했다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.beringlab.com/?lang=ko&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Bering Lab (베링랩)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : &lt;strong&gt;법률/특허 번역&lt;/strong&gt; 서비스를 메인으로 하는 스타트업. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://comcom.ai/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Common Computer (커먼컴퓨터)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 구글, 네이버 출신의 엔지니어들이 설립한 스타트업. 주요 서비스로는 블록체인 기반의 인공지능 관련 대규모 연산이 가능한 블록체인 &lt;a href=&quot;https://ainetwork.ai/&quot;&gt;&lt;strong&gt;AI Network&lt;/strong&gt;&lt;/a&gt;와 OpenResource 플랫폼 &lt;a href=&quot;https://ainize.ai/&quot;&gt;&lt;strong&gt;아이나이즈(Ainize)&lt;/strong&gt;&lt;/a&gt;가 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://silvia.io/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Silvia Health (실비아헬스)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 치매 예방과 조기 진단을 목표로 하는 두뇌건강 플랫폼을 시작으로, 디지털 헬스케어 시장에서 맞춤형 인지건강 관리를 선도한다는 목표를 가지고 있는 스타트업. 삼성 C-lab Outside 선정, 정주영 창업경진대회 최우수상, 보건복지부 X 건강보험심사평가원 빅데이터 활용 경진대회 최우수상 등 여러 대회에서 좋은 성적을 거두었다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.beyondhoneycomb.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Beyond Honeycomb (비욘드허니컴)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 인공지능 기술을 활용해 균일한 맛으로 셰프의 음식을 재현하는 AI 셰프 솔루션을 개발중인 스타트업. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.soundablehealth.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Soundable Health (사운더블 헬스)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 소리 기반의 헬스케어 서비스를 개발하는 스타트업. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://mindslab.ai:8080/kr&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;MINDs Lab (마인즈랩)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 다양한 인공지능 플랫폼/서비스를 제공하는 기업. 최근 코스닥에 상장되었다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.posicube.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;POSICUBE (포지큐브)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 음성 AI, Vision AI 서비스를 제공하는 스타트업. 대표 서비스로 인공지능 전화 자동응답 서비스인 &lt;a href=&quot;https://service.posicube.com/robi-reception.html&quot;&gt;&lt;strong&gt;robi리셉션&lt;/strong&gt;&lt;/a&gt;이 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.deepbrainai.io/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;DeepBrain AI (딥브레인 AI)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 영상합성 기술을 기반으로 AI Human을 구현하는 서비스를 제공하는 스타트업. 최근 높은 연봉, 억대 스톡옵션 등을 걸며 공격적으로 채용하고 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://jenti.ai/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Jenti AI (젠티)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 국내 여러 인공지능 대회에서 우수한 성적을 꾸준히 보이고 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://twoblockai.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;TWOBLOCK AI (투블럭 AI)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 자연어처리 기술을 기반으로 다양한 자연어처리 솔루션을 제공하고 있다. HanBERT, HanBART 등의 자연어처리 모델을 공개한 이력이 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.makinarocks.ai/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;MakinaRocks (마키나락스)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 산업별 이슈에 특화된 데이터 처리 플로우를 제공하는 스타트업. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.lxper.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;LXPER&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 자연어 처리 기술을 기반으로 &lt;strong&gt;영어 학습 컨텐츠&lt;/strong&gt;를 제작하는 스타트업. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://deepnatural.ai/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;DeepNatural (딥내츄럴)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 인공지능 데이터 가공 플랫폼을 운영중인 스타트업. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://pozalabs.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Poza Labs (포자랩스)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : AI 작곡 기술을 연구/개발하는 스타트업. 대표 서비스로 &lt;a href=&quot;https://flowbox.app/&quot;&gt;&lt;strong&gt;FlowBox(플로우박스)&lt;/strong&gt;&lt;/a&gt;가 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://www.2digit.io/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;2digit (투디지트)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 금융 시장을 예측하고 산업 동향을 파악하는 금융 전문 인공지능을 만드는 스타트업. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://desilo.ai/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Desilo (디사일로)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 암호화된 상태로 데이터 분석이 가능한 동형암호 기술에 기반한 데이터 분석, 거래 플랫폼을 개발하는 스타트업. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.lovo.ai/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;LOVO (로보)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : &lt;strong&gt;실리콘밸리&lt;/strong&gt;에 본사를 두고 있으며, &lt;strong&gt;글로벌 AI 성우 서비스&lt;/strong&gt;를 제공하고 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.bigc.studio/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;BIGC (빅크)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 엔터테이너, 뮤지션, 작가, 스페셜리스트 등 다양한 크리에이터들이 팬들과 소통하며 꾸준히 수익을 창출할 수 있는 플랫폼을 만드는 스타트업. 창업자인 김미희 대표는 2016년 모바일 회화 서비스 ‘튜터링’을 창업해, 300만 다운로드의 에듀테크 대표기업으로 성장시켜 인수합병을 이끈 이력이 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.thumb-technologies.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Thumb Technologies (썸 테크놀로지스)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : &lt;strong&gt;아마존, 애플, 인텔 등 해외 유명 기업 출신&lt;/strong&gt;들이 설립한 스타트업으로 자연어처리 기술을 기반으로 온·오프라인 회의내용을 자동으로 기록하고 요약하는 기술을 보유하고 있다. CEO는 한국 분이시며 나머지 멤버들은 외국인으로 이루어져 있다. 영어 의사소통이 되면서 자연어처리 기술을 보유한 인재를 찾고 있다고 한다. 최근 약 &lt;strong&gt;16억원 규모의 프리 시드 투자 유치&lt;/strong&gt;를 마무리했다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://zezedu.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;zezedu (제제듀)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : AI 기술을 이용해 수학 교육의 개인화를 목표로 하는 스타트업. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://gaudiolab.com/about-us/?lang=ko&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;GAUDIO Lab (가우디오랩)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 오디오테크 스타트업으로, 다양한 콘텐츠 환경에서 &lt;strong&gt;몰입감 높은 오디오 경험&lt;/strong&gt;을 구현하는 기술을 개발한다. 네이버와 긴밀하게 협력하고 있으며 높은 수준의 기술력을 인정받고 있다. 최근 &lt;strong&gt;113억원 규모의 시리즈 B 투자&lt;/strong&gt;를 유치했다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.05)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.vuno.co/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;VUNO (뷰노)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : &lt;strong&gt;의료분야&lt;/strong&gt;에 인공지능 기술을 적용해 X-ray·CT·MRI 등 의료영상 데이터부터 생체신호까지 광범위한 의료데이터를 분석하고 진단을 돕는 의료 AI 솔루션 개발 스타트업. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.07)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://www.humelo.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Humelo (휴멜로)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 단순한 음성 합성 기술을 넘어 음성의 감정 및 운율(음정, 속도)을 조절 가능하도록 하는 기술을 개발하는 스타트업. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.07)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://mindlogic.ai/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;MindLogic (마인드로직)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 인공지능 가상 연인 서비스 &lt;a href=&quot;http://ai-boyfriend-girlfriend.mindlogic.ai/&quot;&gt;&lt;strong&gt;가상남녀&lt;/strong&gt;&lt;/a&gt; 서비스를 운영중인 스타트업. 21년 상반기에 50억 규모의 시리즈 A 투자를 유치했다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.07)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.notion.so/608470c23d124915806d04378cc012d1&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Petpeotalk (펫페오톡)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 집에 남은 반려동물의 행동을 기록하고 AI 기반 기술로 행동을 분석해주는 반려동물 CCTV 서비스인 &lt;a href=&quot;https://dogibogi.co.kr/&quot;&gt;&lt;strong&gt;도기보기&lt;/strong&gt;&lt;/a&gt;를 운영중이다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.08)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://www.intellius.ai/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Intellius (인텔리어스)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 자연어처리 기술을 기반으로 의도 분류, 대화, 감성 분석 등의 기술을 서비스로 제공하는 스타트업. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.07)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://www.atommerce.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Atommerce (아토머스)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 비대면 전문 정신건강 서비스 &lt;a href=&quot;http://www.atommerce.com/&quot;&gt;&lt;strong&gt;마인드카페&lt;/strong&gt;&lt;/a&gt;를 운영하는 스타트업. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.07)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://vueron.org/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;VUERON (뷰런)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : &lt;strong&gt;LiDAR 센서&lt;/strong&gt;를 &lt;strong&gt;자율주행&lt;/strong&gt; 산업에 적용하는 기술을 개발하고 있는 스타트업. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.07)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://elice.io/home&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;elice (엘리스)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : AI 기술 기반으로 학생들의 행동 패턴을 파악하는 등 코딩 교육 플랫폼에 AI 기술을 적용하고 있는 스타트업. 최근에는 대기업쪽 코딩 교육에 많이 사용되고 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.08)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://wellxecon.com/&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;Wellxecon (웰시콘)&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; : 서울대 경제학부 홍석철 교수님이 설립한 스타트업으로, 금융과 건강이라는 두 도메인의 데이터를 활용해서 건강 분석에 금융 데이터를, 금융 분석에 건강 데이터를 활용하는 서비스를 제공하고 있다. 현재는 보험사 등과 협업하고 있다. &lt;em&gt;&lt;strong&gt;(Last Update: 2021.12.08)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Author&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sooftware&quot;&gt;Soohwan Kim&lt;/a&gt; @sooftware&lt;/li&gt;
&lt;li&gt;Contacts: &lt;a href=&quot;mailto:sh951011@gmail.com&quot;&gt;sh951011@gmail.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Flask]]></title><description><![CDATA[Flask Flask는 ‘micro’웹 프레임워크입니다. 즉 Django…]]></description><link>https://sooftware.github.io/flask/</link><guid isPermaLink="false">https://sooftware.github.io/flask/</guid><pubDate>Wed, 01 Dec 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Flask&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Flask는 ‘micro’웹 프레임워크입니다.&lt;/li&gt;
&lt;li&gt;즉 Django와 달리 최소한의 구성 요소와 요구 사항을 제공하기 때문에 시작하기 쉽고 필요에 따라 유연하게 사용할 수 있습니다.&lt;/li&gt;
&lt;li&gt;하지만 완전한 기능을 갖춘 앱을 만들기에 제약이 있다는 뜻은 아니고 오히려 쉽게 확장할 수 있도록 설계되어 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;install&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;pip install flask&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Hello Flask&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; flask &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Flask
app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Flask&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# Flask 객체 생성&lt;/span&gt;
 
&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;route&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;h1&gt;Hello World!&amp;lt;/h1&gt;&apos;&lt;/span&gt;
 
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Flask를 처음 시작할 때 생성하는 hello world 출력 코드입니다.&lt;/p&gt;
&lt;p&gt;정말 간단한 코드지만 Flask의 기본적인 구조를 잘 보여주고 있습니다.&lt;/p&gt;
&lt;p&gt;app은 Flask객체입니다. 원하는 기능을 추가하고 싶을 때 이 app에 기능을 추가해주면되고, 특정 url에 기능을 추가하고 싶을 경우에도 app을 기준으로 url을 추가해준 뒤 기능을 구현해주면 됩니다.&lt;/p&gt;
&lt;p&gt;아무튼 이렇게 실행을 하면 &lt;code class=&quot;language-text&quot;&gt;app.run()&lt;/code&gt;을 통해 &lt;code class=&quot;language-text&quot;&gt;http://127.0.0.1:5000/&lt;/code&gt; 주소로 app이 배포가 시작됩니다.&lt;/p&gt;
&lt;p&gt;5000번 port는 flask에서 실행한 서버의 포트이며, &lt;code class=&quot;language-text&quot;&gt;debug=True&lt;/code&gt; 개발용으로 실행한다는 뜻으로 프로젝트에서 변경된 코드가 생길 시 자동으로 변경된 코드를 적용해서 서버를 다시 시작해주는 기능을 갖고 있습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;Route&lt;/h3&gt;
&lt;p&gt;Flask를 사용시 어쩌면 가장 중요하다고 할 수 있는 route기능입니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; flask &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Flask

app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Flask&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;route&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;route&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/home&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;home&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Hello, World!&apos;&lt;/span&gt;

&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;route&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/user&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Hello, User!&apos;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;__main__&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;route는 말 그대로 경로를 지정해주는 기능입니다.&lt;/p&gt;
&lt;p&gt;이게 무슨말이냐. 보통 웹에 배포를 시작할 경우 다양한 기능들(로그인, 검색, 메뉴 등등)을 제공해야 하는데 &lt;code class=&quot;language-text&quot;&gt;http://127.0.0.1:5000/&lt;/code&gt; 이라는 주소 하나만으로는 모든 기능을 처리할 수 없습니다.
그렇다고 저 주소안에 여러기능들을 다 쑤셔넣을 수도 없으니까요.&lt;/p&gt;
&lt;p&gt;이 &lt;code class=&quot;language-text&quot;&gt;app.route&lt;/code&gt; 데코레이터를 이용해 url의 suffix를 추가해줄 수 있습니다.&lt;/p&gt;
&lt;p&gt;위에 코드를 예시로 들어보면 home 함수에는 &lt;code class=&quot;language-text&quot;&gt;/home&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;/&lt;/code&gt;이라는 문자가 route 데코레이터를 통해 추가된 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;이 말은 &lt;code class=&quot;language-text&quot;&gt;http://127.0.0.1:5000/&lt;/code&gt; 또는 &lt;code class=&quot;language-text&quot;&gt;http://127.0.0.1:5000/home&lt;/code&gt; 에 접속할 경우 home 함수를 실행하라는 뜻입니다.&lt;/p&gt;
&lt;p&gt;마찬가지로 &lt;code class=&quot;language-text&quot;&gt;http://127.0.0.1:5000/user&lt;/code&gt; 에 접속 시 user함수가 실행되는 것을 알 수 있습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;Blueprint&lt;/h3&gt;
&lt;p&gt;굉장히 중요한 기능인 이 route는 기능이 필요할 때마다 계속 추가되어야 하기 때문에, 함수가 많을 경우 번거로워질 수 있습니다.&lt;/p&gt;
&lt;p&gt;예를 들면 동일하게 &lt;code class=&quot;language-text&quot;&gt;/menu&lt;/code&gt; 로 시작하는 url이 있는 경우 2~3개면 상관없겠지만 실제 프로젝트에선 10개가 넘어갈 수도 있는데 전부 하나씩 menu를 달아주는 것은 비효율적입니다.&lt;/p&gt;
&lt;p&gt;이런 상황에서 blueprint를 이용하면 route함수들을 보다 구조적으로 관리할 수 있게 됩니다.&lt;/p&gt;
&lt;h3&gt;Blueprint 객체&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# app.py&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; flask &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Flask

app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Flask&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;views &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; main_views	
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;register_blueprint&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;main_views&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# views\main_views.py&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; flask &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Blueprint

bp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Blueprint&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;main_views&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; __name__&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; url_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/view&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@bp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;route&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/hello&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main_view&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;main view&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;blueprint 객체 생성&lt;/li&gt;
&lt;li&gt;Flask 객체 app에서 blueprint객체를 register해준다.&lt;/li&gt;
&lt;li&gt;controller route에서 blueprint 객체를 써준다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;최종적으로 hello_pybo함수의 url은 &lt;code class=&quot;language-text&quot;&gt;127.0.0.1:5000/view/hello&lt;/code&gt;가 됩니다.&lt;/p&gt;
&lt;p&gt;이런 식으로 blueprint를 사용하여 url을 구조적으로 관리해줄 수 있습니다.&lt;/p&gt;
&lt;h3&gt;app teardown appcontext&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;teardown_appcontext&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;shutdown_session&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;exception&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    db_session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;remove&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;app.teardown_appcontext&lt;/code&gt;데코레이터는 클라이언트의 요청이 종료됐을 경우에 자동으로 실행되도록 하는 함수입니다.&lt;/p&gt;
&lt;p&gt;위 함수를 읽기만해도 알 수 있듯이 클라이언트의 요청이 종료될 경우 해당함수가 실행돼 db가 종료되도록 한다는 뜻입니다.&lt;/p&gt;
&lt;p&gt;매우 간단하지만 중요한 개념이기 때문에 언급하고 넘어가겠습니다.&lt;/p&gt;
&lt;h2&gt;Database&lt;/h2&gt;
&lt;p&gt;이번엔 flask에 database를 연동하는 방법을 알아보겠습니다.&lt;/p&gt;
&lt;p&gt;흔히들 python에 database에 연동할 때 각 sql을 지원하는 라이브러리의 connect()함수를 사용하여 연동했을겁니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# ex) mysql 연결&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; pymysql 

conn &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pymysql&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;connect&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    user&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    passwd&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;{설정한 비밀번호}&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;127.0.0.1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    db&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;juso-db&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    charset&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;utf8&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이런 식으로 간단하게 연동한 뒤 원하는 sql명령을 처리해 db에 적용했습니다.&lt;/p&gt;
&lt;p&gt;하지만 flask는 보통 배포를 위해 사용되고 또한 배포되는 서버는 다수의 사용자가 사용하게 됩니다. 위와 같은 방식으로 구현한다면 1만명의 사용자가 접속했을 때 1만번의 db연결을 해줘야 됩니다.&lt;/p&gt;
&lt;p&gt;즉 매우매우 비효율적이고, 속도도 느립니다.&lt;/p&gt;
&lt;p&gt;이를 해결하기 위해 미리 db session을 저장해두는 pooling방식을 사용합니다.&lt;/p&gt;
&lt;h3&gt;flask-sqlalchemy&lt;/h3&gt;
&lt;p&gt;하지만 저희가 굳이 pooling을 구현할 필요는 없습니다. 이미 pooling방식으로 간단하게 데이터베이스를 연동할 수 있는 sqlalchemy 라이브러리가 존재하고,&lt;/p&gt;
&lt;p&gt;더 나아가 flask를 위해 구현되어 편리하게 app객체에 db옵션을 추가해줄 수 있고, 클라이언트 요청이 종료되면 자동으로 db_session을 pool에서 삭제시켜주기까지 하는
flask-sqlalchemy라는 라이브러리가 존재합니다.&lt;/p&gt;
&lt;h3&gt;config&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://flask-sqlalchemy.palletsprojects.com/en/2.x/config/#configuration-keys&quot;&gt;https://flask-sqlalchemy.palletsprojects.com/en/2.x/config/#configuration-keys&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;flask-sqlalchemy 라이브러리를 사용하면 flask 객체에 sqlalchemy에 대한 설정을 해줄 수 있습니다.&lt;/p&gt;
&lt;p&gt;전체 config속성은 위 링크에 접속하셔서 확인해주시면 되고, 그 중 중요하다고 생각되는 기능들을 알아보겠습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; flask &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Flask

app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Flask&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SQLALCHEMY_DATABASE_URI&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;postgresql://{user_name}:{password}@{host}:{port}/{database_name}&quot;&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SQLALCHEMY_COMMIT_ON_TEARDOWN&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SQLALCHEMY_POOL_SIZE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SQLALCHEMY_MAX_OVERFLOW&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SQLALCHEMY_POOL_RECYCLE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;사용법은 간단합니다. 생성된 flask객체의 config함수에서 원하는 속성값을 지정해주면 됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;SQLALCHEMY_DATABASE_URI&lt;/code&gt;: 연결에 사용되는 데이터베이스 URI (어떤 sql을 사용하느냐에 따라 주소의 형태가 다릅니다.)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;SQLALCHEMY_COMMIT_ON_TEARDOWN&lt;/code&gt;: 클라이언트의 request 마지막단에서 데이터베이스의 변경사항을 자동으로 커밋하는 기능&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;SQLALCHEMY_POOL_SIZE&lt;/code&gt;: pool 크기를 지정합니다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;SQLALCHEMY_MAX_OVERFLOW&lt;/code&gt;: pool overflow 크기를 지정합니다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;SQLALCHEMY_POOL_RECYCLE&lt;/code&gt;: pool에 존재하는 session이 자동으로 recycle되는 시간을 지정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;db연결&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; flask_sqlalchemy &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; SQLAlchemy

db &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; SQLAlchemy&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_app&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;app&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;flask_sqlalchemy의 SQLAlchemy 클래스 객체를 생성해주고 init_app을 앞서 설정했던 flask app과 연결해주면 매우 쉽게 연동이 완료됩니다.&lt;/p&gt;
&lt;p&gt;자 이제 SQLAlchemy를 이용해 새로운 table을 생성해보겠습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Model&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    __tablename__ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;test&apos;&lt;/span&gt;
    user_id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Column&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; primary_key&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Column&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; user_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user_id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; user_id
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; name&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;db.Model 클래스를 상속받는 Test라는 클래스를 생성해봤습니다.&lt;/p&gt;
&lt;p&gt;이 Test클래스는 하나의 table입니다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;__tablename__&lt;/code&gt;: 이름에서 알 수 있듯이 테이블명입니다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;user_id = db.Column(db.String(20), primary_key=True)&lt;/code&gt;: user_id라는 컬럼을 만드는데 String type에 길이는 20이며, primary_key로 지정하겠다는 의미입니다.&lt;/p&gt;
&lt;p&gt;이런 식으로 원하는 테이블과 column들을 원하는 대로 만들어줄 수 있으며 자유롭게 코드 내부에서 객체로 생성해 사용가능합니다.&lt;/p&gt;
&lt;p&gt;다만 실제로 sql내부에 생성하려면 별도의 작업이 필요합니다.&lt;/p&gt;
&lt;p&gt;아까 db를 연결했던 코드에서 단 한줄만 추가해주면 됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; flask_sqlalchemy &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; SQLAlchemy

db &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; SQLAlchemy&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_app&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;app&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;create_all&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;db.create_all()&lt;/code&gt;을 사용하면 db.Model을 상속받은 클래스들이 실제로 sql내부에 존재하는지 여부를 확인하고 존재한다면 자동으로 생성해줍니다.&lt;/p&gt;
&lt;h3&gt;기본적인 db응용&lt;/h3&gt;
&lt;p&gt;SELECT&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;query&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Test&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;#SELECT * FROM test&lt;/span&gt;
db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;query&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Test&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user_id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;#SELECT user_id FROM test&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;WHERE
&lt;code class=&quot;language-text&quot;&gt;filter&lt;/code&gt;를 사용합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;query&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Test&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Test&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user_id &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sooftware&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;query&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Test&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Test&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user_id &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sooftware&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Test&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Soohwan Kim&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;INSERT&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;test &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Test&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;sooftware&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Soohwan Kim&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;test&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;commit&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;sql에 대해 자세히 모르더라도 객체의 함수로 편리하고 쉽게 처리가 가능합니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[총, 균, 쇠 (guns germs and steel)]]></title><description><![CDATA[# 총, 균, 쇠 (guns germs and steel…]]></description><link>https://sooftware.github.io/guns-germs-and-steel/</link><guid isPermaLink="false">https://sooftware.github.io/guns-germs-and-steel/</guid><pubDate>Mon, 29 Nov 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;# 총, 균, 쇠 (guns germs and steel)&lt;/h1&gt;
&lt;p&gt;아직 책을 다 읽지 못해서 리뷰라고 하기는 뭐하지만 😅 일단은 드는 생각을 적어두려고 한다.&lt;/p&gt;
&lt;p&gt;일단 책은 “왜 유럽 사람들이 아프리카와 아메리카를 지배할 수 있었나?”라는 질문에서 시작한다. 궁금하긴 하지만
딱히 깊게 생각해본적 없는 질문이였는데, 이 질문을 보고나니 정말 왜 그럴까란 생각이 들어서 이번 주말에 시간 날때마다 읽었다.&lt;br&gt;
저자는 사람들이 내심 말은 하지 않지만, ‘유럽 사람들이 아프리카, 아메리카에 살던 사람들보다 우월하니까’라는 생각을 한다는 점을 지적하며,
이 생각은 철저하게 잘못되었다는 것을 이 책으로 설명하고 있다.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;유럽에서는 총을 만들고 있을때, 왜 아메리카와 아프리카에서는 총을 만들지 못했는가?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;유라시아와 비교하여 왜 아메리카와 아프리카는 조금 더 정치적인 발전을 하지 못했는가?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;왜 유라시아에 원주민들에 비해 아프리카, 아메리카 원주민들은 ‘균’에 취약했는가?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;등의 자연스레 딸려오는 질문들에 대해서 저자가 몇 십년동안 열심히 연구한 내용을 바탕으로 서술한다.&lt;/p&gt;
&lt;p&gt;그리고, 개인적으로 눈 여겨 본 부분은 ‘언어’에 관한 부분이였는데, 책의 앞 부분에서 약 5만년에서 10만년 정도 전쯤에 현생 인류로의 엄청난
발전(대약진)이 있었다고 추정되는데, 이러한 대약진의 원인으로 현대적 언어를 위한 해부학적 기반이 마련되었기 때문에 많은 발전이 있었을 것이라는 주장이 유력하다고 한다.&lt;/p&gt;
&lt;p&gt;책에서 언어는 인간의 창의성에 가장 중요한 부분이라고 언급하는데, 약 5만년에서 10만년 전 인간의 언어적 기반이 마련이 된 시기라면 최근 몇년, 그리고 향후 몇년~몇십년간은
인공지능의 언어(창의성)의 발전이 폭발적으로 일어나는 시기가 아닐까란 생각이 들었다. 그렇다면, 인간에게 언어의 발전이 대약진이라 부를만큼 큰 발전을 만들어냈으니,
인공지능의 언어의 발전도 인공지능 발전에 그만한 파급력이 있을 것이라는 평소 내 생각과 얼라인(align)이 많이 되는 것 같다.&lt;/p&gt;
&lt;p&gt;그런 중요한 시기에 관련 일을 하고 있다는 것만으로도 자부심을 느끼게 된다. 그냥 워낙 유명한 책이여서 상식을 늘려볼까란 생각에 읽어본 책이였는데,
생각지도 못하게 내가 왜 자연어처리쪽 일을 하고 있는가에 대해서 더 확신이 생기게 되었다. 소 뒷걸음치다가 쥐 잡았다라는 말을 이럴때 쓰는게 아닐까? 😋&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - GPT (Generative Pre-trained Transformer)]]></title><description><![CDATA[GPT (Generative Pre-trained Transformer) 1 gpt1 먼저 알아보고, gpt2에 대해 알아보겠습니다. GPT1 Improving Language Understanding by Generative Pre-Training…]]></description><link>https://sooftware.github.io/gpt/</link><guid isPermaLink="false">https://sooftware.github.io/gpt/</guid><pubDate>Tue, 23 Nov 2021 11:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;GPT (Generative Pre-trained Transformer)&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137573333-0e67caea-e8cb-4886-9ed0-46fa610d91d0.PNG&quot; alt=&quot;1&quot;&gt;&lt;/p&gt;
&lt;p&gt;gpt1 먼저 알아보고, gpt2에 대해 알아보겠습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h1&gt;GPT1&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf&quot;&gt;Improving Language Understanding by Generative Pre-Training&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;다양한 라벨링 되지 않은 데이터로 unsupervised pre-training하고, 라벨링 되어있는 데이터로 특정 task에 supervised fine-tuning 하는 self-supervised 학습을 한다.&lt;/li&gt;
&lt;li&gt;각 task마다 input 형태를 조금씩만 다르게하면 좋은 성능을 보일 수 있는 범용적인 representation을 학습한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;기존 NLP모델들은 labeled된 데이터를 바탕으로 지도학습을 했다. 하지만 존재하는 데이터는 unlabeled data가 훨씬 많기 때문에, unlabeled data의 정보를 활용한다면 효과적으로 학습할 수 있었다.&lt;/li&gt;
&lt;li&gt;But, 어떤 objective function이 유용한 text representation을 배우는데 효과적인지 알 수 없었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그리고 이전까지는 각각의 task마다 모델을 학습시켰기 때문에 범용적으로 학습된 모델을 다른 NLP task에 어떻게 사용할 것인지 명확한 방법이 존재하지 않았다.&lt;/p&gt;
&lt;p&gt;이러한 한계점들을 보완하고자 unsupervised pre-training과 supervised fine-tuning을 한 semi-supervised를 사용하였다.&lt;/p&gt;
&lt;br&gt;
&lt;h2&gt;Framework&lt;/h2&gt;
&lt;p&gt;모델의 학습은 다음과 같이 2단계로 나타낼 수 있다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;라벨링되지 않은 대량 데이터를 이용하여 범용적인 언어모델을 학습&lt;/li&gt;
&lt;li&gt;라벨링 데이터를 이용하여 특정 task에 맞춰 모델을 fine-tuning&lt;/li&gt;
&lt;/ol&gt;
&lt;br&gt;
&lt;h3&gt;Unsupervised pre-training&lt;/h3&gt;
&lt;p&gt;라벨링되지 않은 데이터 u가 주어졌을 때, 다음과 같은 likelihood를 최대화 하기위해 language modeling objective funtion을 사용한다.
&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137592007-c617d2a3-cdf1-4e1a-a73b-dd027f8f03d5.png&quot; alt=&quot;image&quot;&gt;&lt;br&gt;
k는 context window이고, Θ는 parameter이다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137592144-d0adde20-0da4-487c-9217-bd0a7537903b.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;language modeling objective funtion을 쉽게 표현하면 다음과 같다. 맞출 단어의 이전 단어들을 보고 해당 단어를 맞추는 것이다. 예를 들어, 위의 사진에서 정답 문장이 “다음 단어를 떠올리면 됩니다.” 일 때, 사진에서 정답(ground truth)은 “리면”이 된다. 그래서 모델은 이전 단어인 “다음 단어를 떠올”을 보고 여러 가지 토큰들 중에서 “리면”이 나올 likelihood를 최대화하는 방향으로 학습을 진행한다.&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137592439-d1e34ad4-ccd7-4bac-ad8b-e17be3398a3a.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;또한 GPT는 Transformer의 변형인 multi-layer Transformer decoder를 사용한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137593453-cf69c0e3-32bf-4361-ae5e-230fce52b9bc.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;token embedding 값과 position embedding 값을 더해준다. 그리고 transformer_block을 n번 통과하고 vocab 사이즈만큼 linear 해준 후 softmax를 취해준다.
n은 layer의 수, We는 token embedding 행렬, Wp는 position embedding 행렬이다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;Supervised fine-tuning&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137593397-8aa2714c-091d-41de-a1e9-3c0a83ae378e.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;위에서 학습한 언어 모델을 task에 맞춰 fine-tuning 한다. 앞서 학습한 pre-trained 모델을 통과하고 label y값을 예측하기 위해 linear 해준 후 softmax를 취해준다.&lt;/p&gt;
&lt;p&gt;또한 fine-tuning 단계에서 학습을 돕기 위해 언어모델을 보조 objective function으로 포함시켰다고 한다. 첫 번째 이유는 supervised 모델의 일반화(범용성)를 향상시키기 위해서이고, 두 번째 이유는 수렴을 빠르게 해주기 때문이다.&lt;/p&gt;
&lt;p&gt;그래서 아래와 같은 목적함수를 최적화한다.&lt;br&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137593826-48ce3aa6-a494-48bb-be1a-a0cc0f4dfb89.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;Task-specific input transformations&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137593951-4927546d-9138-4918-b520-bc3d3684973b.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;위에서 언급한 것 처럼 task에 맞게 input 형태를 적절하게 변형시켜주어야한다.&lt;/p&gt;
&lt;p&gt;스폐셜 토큰으로는 문장의 시작을 알리는 start 토큰 &lt;code class=&quot;language-text&quot;&gt;&amp;lt;s&gt;&lt;/code&gt;, 문장의 끝을 알리고 BERT의 CLS 토큰 역할을 하는 extract 토큰 &lt;code class=&quot;language-text&quot;&gt;&amp;lt;e&gt;&lt;/code&gt;, BERT의 SEP 토큰처럼 문장을 이어주는 delimeter 토큰 &lt;code class=&quot;language-text&quot;&gt;$&lt;/code&gt;이 있다.&lt;/p&gt;
&lt;h4&gt;Textual entailment&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;전제 p와 가정 h를 delimeter 토큰&lt;code class=&quot;language-text&quot;&gt;$&lt;/code&gt;로 연결하였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Similarity&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;두 개의 텍스트의 순서가 없으므로 두 개를 다른 순서로 이어붙여 총 2개를 입력으로 쓴다. (data augmentation)&lt;/li&gt;
&lt;li&gt;이는, Transformer에 각각의 입력으로 들어간다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Question Answering and Commonsense Reasoning (Multiple Choice)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;document context를 z, question을 q, 가능한 답변을 ak라고 하면, context와 question을 이어붙여 위 사진의 Context 부분을 만들고 delimeter 토큰&lt;code class=&quot;language-text&quot;&gt;$&lt;/code&gt;과 answer을 이어준다.&lt;br&gt;
수식으로 표현하면 &lt;code class=&quot;language-text&quot;&gt;[z;q;$;ak]&lt;/code&gt; 이러한 형태이고, 각각 독립적으로 모델에 전달된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;당시만해도 pre-training과 fine-tuning이 익숙하지 않았었는데, unsupervised pre-training을 통해 많은 성능 향상이 있었고, 그 모델로 여러가지 nlp task를 푸는데 성공하였다.&lt;/p&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;h1&gt;GPT2&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://d4mucfpksywv.cloudfront.net/better-language-models/language_models_are_unsupervised_multitask_learners.pdf&quot;&gt;Language Models are Unsupervised Multitask Learners&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Only unsupervised pre-training (fine-tuning x)&lt;/li&gt;
&lt;li&gt;Zero-shot으로 downstream task를 진행할 수 있는 General language model을 개발하자.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;여러 NLP task는 특정 task에 맞는 datasets을 가지고 supervised learning을 진행했다. 하지만 저자들은 이러한 모델이 &lt;code class=&quot;language-text&quot;&gt;Narrow Expert&lt;/code&gt; 로서 데이터 분포의 변화 혹은 Task의 변화에 매우 취약하다고 주장한다. Domain과 Task에 특화된 방법이 오히려 모델의 &lt;code class=&quot;language-text&quot;&gt;Generalization&lt;/code&gt; 능력을 저해하기 때문이다.&lt;br&gt;
또한 Multi-Task learning은 다양한 Domain과 Task를 동시에 수행하며 학습하는 방법으로서, Generalization 성능을 높일 수 있다. 하지만, 이를 위해서는 많은 양질의 학습 데이터를 수집하는 것과 적합한 objective function를 설정하는 것이 필요하다.&lt;br&gt;
그래서 WebText라고 불리는 수백만 웹 페이지의 데이터로 explicit supervision 없이 language models을 학습하고, Zero-shot downstream task가 가능한 언어 모델 GPT-2를 소개한다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;❓ &lt;code class=&quot;language-text&quot;&gt;zero-shot&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;few-shot&lt;/code&gt;이 뭐야?&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137766145-e4dd8db8-b74c-4b83-b71d-04f02207296d.png&quot; alt=&quot;image&quot;&gt;&lt;br&gt;
학습에 사용하는 데이터셋을 서포트 데이터, 테스트에 사용하는 데이터셋을 쿼리 데이터라고 한다.&lt;br&gt;
이러한 퓨샷 러닝 태스크를 &lt;code class=&quot;language-text&quot;&gt;N-way K-shot 문제&lt;/code&gt;라고 부른다. N은 범주의 수, K는 범주별 서포트 데이터의 수를 의미한다.&lt;br&gt;
위의 사진처럼 2개의 범주(고양이, 자동차), 범주당 5장의 이미지가 주어진 문제를 2-way 5-shot 문제라고 한다. 그러므로 zero-shot은 데이터를 한번도 안보고 테스트 하는 것을 의미한다.&lt;/p&gt;
&lt;br&gt;
&lt;h2&gt;Approach&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137767440-2c38b4c7-f1d4-4a73-9095-14a2d26c71e8.png&quot; alt=&quot;image&quot;&gt;&lt;br&gt;
Language modeling 방법으로 접근하였고, 조건부 확률로 sequential하게 다음 단어를 예측한다.&lt;/p&gt;
&lt;h3&gt;Training Dataset&lt;/h3&gt;
&lt;p&gt;GPT1에서는 News articles나 Wikipedia 같은 single domain text를 사용했다. 하지만 이번에는 다양한 도메인의 데이터셋을 만들기위해 직접 web crawling을 하여 데이터를 제작하였다.&lt;br&gt;
Reddit에서 3 karma(페이스북 좋아요 같은 것) 이상을 받은 2017년 12월 전 post만 가져와서 wikipedia와 중복 되는 부분을 삭제하고 40GB text, 총 8 million개의 문서를 생성했다.&lt;/p&gt;
&lt;h3&gt;Input Representation&lt;/h3&gt;
&lt;p&gt;본 논문에서는 Byte Pair Encoding(BPE) 방식을 채택하였다. BPE는 subword 기반의 인코딩 방법으로, 문자 단위로 단어를 분해하여 vocabulary를 생성하고 반복을 통해 빈도수가 높은 문자 쌍을 지속적으로 vocabulary에 추가하는 방법이다. Byte Pair Encoding(BPE)에 대한 더 자세한 내용은 &lt;a href=&quot;https://github.com/sooftware/engineering-is-all-you-need/blob/main/notes/tokenizer.md#bpebyte-pair-encoding&quot;&gt;링크&lt;/a&gt;를 참고해주세요!&lt;br&gt;
유니코드 수준의 BPE는 13만 개 이상의 매우 큰 vocabulary가 필요하다. 하지만 Byte 수준의 BPE는 오직 256개의 vocabulary만을 필요로 한다. 따라서 저자들은 BPE를 유니코드 수준이 아닌, Byte 수준으로 적용하는 시도를 하였다고 한다.&lt;/p&gt;
&lt;h3&gt;Model&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137771853-dd00cc8a-a3d3-4984-8dc2-46dc8803e061.png&quot; alt=&quot;image&quot;&gt;&lt;br&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137771879-4f171263-5705-48d6-886c-005c0d9ae47c.png&quot; alt=&quot;image&quot;&gt;&lt;br&gt;
모델 구조는 GPT-1의 구조와 거의 동일하다. 차이점은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;normalization 레이어를 각 하위 블록의 입력으로 이동.&lt;/li&gt;
&lt;li&gt;residual layer의 깊이 N에 따라 1/√N * weights를 사용하여 residual layer의 가중치를 설정.&lt;/li&gt;
&lt;li&gt;vocabulary의 크기가 50,257개로 증가.&lt;/li&gt;
&lt;li&gt;한번에 입력가능한 context size가 512에서 1024로 증가.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137774457-a1dd9717-7693-4d4d-8861-646b239262c1.png&quot; alt=&quot;image&quot;&gt;&lt;br&gt;
4가지의 모델 사이즈가 있고, base가 BERT의 라지사이즈와 동일하다.&lt;/p&gt;
&lt;br&gt;
&lt;h2&gt;Experiments&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137773933-47a1b4db-79bc-437a-8df7-0b7e1b0ca705.png&quot; alt=&quot;image&quot;&gt;&lt;br&gt;
Fine-tuning을 진행하지 않은 zero-shot 환경임에도 불구하고 8개의 데이터셋중 7개에서 SOTA를 달성하였다.&lt;/p&gt;
&lt;h3&gt;Question Answering&lt;/h3&gt;
&lt;p&gt;QA task에서 일반적으로 사용하는 ‘정확히 일치 하는지’ 여부(exact match metric)를 지표로 비교하였을 때에는 4.1%의 정확도로 기존의 모델들보다 5.3배 높은 정확도를 보였다.&lt;/p&gt;
&lt;p&gt;아래의 표는 GPT-2가 질문에 대한 답변을 한 결과이다.&lt;br&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137775894-da8f8e21-71a3-4aaf-801b-cf3e70bbfaac.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Generalization vs Memorization&lt;/h2&gt;
&lt;p&gt;Train set과 Test set의 과도한 중복(Overlap)은 모델의 memorization을 유도하고 generalization 성능을 왜곡하여 나타낼 수 있다.&lt;br&gt;
이러한 현상은 저자들이 생성한 WebText 데이터셋에서도 나타날 수 있다.&lt;br&gt;
다음 표는 벤치마크 데이터 Test set과의 overlap 정도를 보여준다. 8-gram으로 겹치는 정도를 데이터 간에 비교해서 측정했다고 한다.&lt;br&gt;
보통 1~6% overlap되고, 평균적으로 3.2% overlap된다고 한다. 본 논문에서는 de-duplication 기반의 n-gram overlap 사용을 추천하고 있다.&lt;br&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137777245-b93090c8-8d03-4bd2-9d7f-a6e57b07f43b.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;br&gt;  
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/137776893-d9db9439-7757-4805-ada4-09acff67767a.png&quot; alt=&quot;image&quot;&gt;&lt;br&gt;
또한 모델의 크기가 커질수록 train과 test 모두 perplexity가 떨어지는 것을 확인할 수 있다. 즉 GPT-2조차 WebText 데이터셋에 아직 underfitting 되어 더 개선될 여지가 있음을 보여준다.&lt;/p&gt;
&lt;h2&gt;Discussion&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Unsupervised task learning 영역도 중요.&lt;/li&gt;
&lt;li&gt;Supervision 없이 task를 배우는 pre-training 기술도 가능성이 있다.&lt;/li&gt;
&lt;li&gt;GPT-2로 많은 zero-shot task에 성능을 측정해보았을 때, 몇 개만 baseline보다 좋은 것이지 각 태스크를 fine-tuning한 모델들이 성능이 더 좋다.&lt;/li&gt;
&lt;li&gt;BERT에서 unidirectional representation은 비효율적이라 했는데 GPT-2가 이런 것을 극복하기에 충분한지 아직 불분명하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;GPT-2는 GPT-1 모델을 기반으로 하여 Unsupervised pre-training 작업을 극대화시킨 pretrained language model이다.&lt;br&gt;
Zero-shot으로 어느정도 유의미한 결과값을 얻었기 때문에 사이즈가 더 큰 모델과 다양한 데이터셋으로 pre-training하면 성능이 더 좋아질 수 있다.&lt;/p&gt;
&lt;br&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://openai.com/blog/language-unsupervised&quot;&gt;https://openai.com/blog/language-unsupervised&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://d4mucfpksywv.cloudfront.net/better-language-models/language_models_are_unsupervised_multitask_learners.pdf&quot;&gt;https://d4mucfpksywv.cloudfront.net/better-language-models/language_models_are_unsupervised_multitask_learners.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.kakaobrain.com/blog/106&quot;&gt;https://www.kakaobrain.com/blog/106&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Large Scale LM (2) Distributed Programming]]></title><description><![CDATA[Large Scale LM (2) Distributed Programming (작성중) 이 자료는 [해당 link…]]></description><link>https://sooftware.github.io/big-model2/</link><guid isPermaLink="false">https://sooftware.github.io/big-model2/</guid><pubDate>Mon, 22 Nov 2021 11:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Large Scale LM (2) Distributed Programming (작성중)&lt;/h1&gt;
&lt;p&gt;이 자료는 &lt;a href=&quot;https://github.com/tunib-ai/large-scale-lm-tutorials&quot;&gt;[해당 link]&lt;/a&gt; 를 참고하며 제 언어로 재작성한 글입니다.&lt;br&gt;
저의 추가적인 메모나 의견이 삽입되거나 삭제된 내용이 있습니다.&lt;br&gt;
더 퀄리티가 좋은 자료는 위의 링크를 참고하시길 바랍니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Large-Scale 모델은 메모리를 많이 먹기 때문에 어느 정도 커지게 되면 하나의 GPU에 올릴 수가 없습니다.
Big Model 학습이 어려운 주된 이유죠. 그래서 이런 Large-Scale 모델의 경우 여러대의 GPU에 모델을 쪼개서 올려야 합니다.
그리고 쪼개진 모델을 받은 GPU들간에 네트워크로 통신을 하면서 값을 주고 받아야 합니다. 이렇게 여러대의 장비로 분산시켜서
처리하는 작업을 분산처리라고 합니다. 이번 포스트에서는 PyTorch 프레임워크를 이용한 분산 프로그래밍 기초에 대해서 알아보겠습니다.&lt;/p&gt;
&lt;h2&gt;Multi-processing with PyTorch&lt;/h2&gt;
&lt;p&gt;분산 프로그래밍의 원활한 이해를 돕기 위해 PyTorch의 Multi-processing 애플리케이션에 대한 튜토리얼을 먼저 살펴보겠습니다.&lt;/p&gt;
&lt;h3&gt;Multi-process Terms&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Node: 컴퓨터 혹은 서버와 같은 장비를 말합니다. AI 쪽에서는 보통 GPU 여러대가 묶여있는 하나의 컴퓨터 or 서버를 칭합니다.&lt;/li&gt;
&lt;li&gt;Global Rank: 원래는 프로세스의 우선순위를 의미하지만 여기서는 의미는 주로 &lt;strong&gt;GPU의 ID&lt;/strong&gt;라고 보면 됩니다.&lt;/li&gt;
&lt;li&gt;Local Rank: 원래는 한 노드내에서의 프로세스 우선순위를 의미하지만, 여기서는 &lt;strong&gt;한 노드내의 GPU ID&lt;/strong&gt;라고 보면 됩니다.&lt;/li&gt;
&lt;li&gt;World Size: 프로세스의 개수를 의미합니다. 여기서는 주로 GPU의 개수를 의미합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://github.com/tunib-ai/large-scale-lm-tutorials/raw/ca29ff9f945a59abcc3e3f1000c4d83de97973d4/images/process_terms.png&quot; width=&quot;500&quot;&gt;  
&lt;h3&gt;Multi-process Application 실행 방법&lt;/h3&gt;
&lt;p&gt;PyTorch Multi-process 어플리케이션 실행 방법은 두 가지가 있습니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;으사용자의 코드가 메인 프로세스가 되어 특정 함수를 서브프로세스로 분기한다.&lt;/li&gt;
&lt;li&gt;PyTorch 런쳐가 메인 프로세스가 되어 사용자 코드 전체를 서브 프로세스로 분기한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;1) 사용자의 코드가 메인 프로세스가 되어 특정 함수를 서브프로세스로 분기한다.&lt;/h3&gt;
&lt;img src=&quot;https://github.com/tunib-ai/large-scale-lm-tutorials/raw/ca29ff9f945a59abcc3e3f1000c4d83de97973d4/images/multi_process_1.png&quot; width=&quot;500&quot;&gt; 
&lt;p&gt;일반적으로 &lt;code class=&quot;language-text&quot;&gt;Spawn&lt;/code&gt;과 &lt;code class=&quot;language-text&quot;&gt;Fork&lt;/code&gt; 등 두 가지 방식으로 분기할 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Spawn&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;메인 프로세스의 자원을 물려주지 않고 필요한 만큼의 자원만 서브프로세스에게 새로 할당&lt;/li&gt;
&lt;li&gt;속도가 느리지만 안전한 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Fork&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;메인 프로세스의 모든 자원을 서브 프로세스와 공유하고 프로세스를 시작&lt;/li&gt;
&lt;li&gt;속도가 빠르지만 위험한 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;multiprocessing &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; mp


&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; param1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; param2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;param1&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;param2&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; - rank: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;


processes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
mp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;set_start_method&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;spawn&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; rank &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    process &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Process&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;target&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;fn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; args&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;B1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;daemon &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;
    process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;start&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    processes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;process&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; process &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; processes&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;A0 B1 - rank: 0
A0 B1 - rank: 2
A0 B1 - rank: 3
A0 B1 - rank: 1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;2) PyTorch 런처가 부모 프로세스가 되어 사용자 코드 전체를 서브프로세스로 분기한다.&lt;/h3&gt;
&lt;img src=&quot;https://github.com/tunib-ai/large-scale-lm-tutorials/raw/ca29ff9f945a59abcc3e3f1000c4d83de97973d4/images/multi_process_2.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;이 방식은 &lt;code class=&quot;language-text&quot;&gt;python -m torch.distributed.launch --nproc_per_node=n OOO.py&lt;/code&gt;와 같은 방식으로 실행해줘야 동작합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;hello world, &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;RANK&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;hello world, 0
hello world, 1
hello world, 2
hello world, 3&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Distributed Programming with PyTorch&lt;/h2&gt;
&lt;h4&gt;Concept of Message Passing&lt;/h4&gt;
&lt;p&gt;OS 과목에서 배우는 개념이죠. 몇 년 전에 OS 과목을 배울 때 Message Passing은 분산 환경에서 주로 사용된다고 배운 기억이 있습니다.
Message Passing이란 Shared Memory(공유 메모리) 없이 프로세스간에 데이터를 주고 받는 방법입니다.
특정 태그가 달린 데이터를 네트워크에 보내면 다른 프로세스간 해당 데이터를 리시브를 하도록 하는 방식입니다.
코드 레벨에서 특정 태그를 이용하여 프로그래밍 해두면 원하는대로 원하는 프로세스에 데이터를 전달할 수 있습니다.
Large-scale 모델 개발시 이용되는 분산 통신 역시 대부분 이런 Message Passing 기법이 사용됩니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147876208-04481ccb-e115-41c4-9722-9639c185c498.png&quot; width=&quot;400&quot;&gt;  
&lt;h4&gt;MPI (Message Passing Interface)&lt;/h4&gt;
&lt;p&gt;MPI는 Message Passing에 대한 표준 인터페이스입니다. MPI는 Message Passing에 사용되는 여러 연산 (e.g. broadcast, reduce, scatter, gather, …)
등이 정의되어 있으며 대표적으로 OpenMPI라는 오픈소스가 존재합니다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.open-mpi.org/&quot;&gt;https://www.open-mpi.org/&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;NCCL &amp;#x26; GLOO&lt;/h4&gt;
&lt;p&gt;하지만 실제 사용에서는 openmpi보다는 nccl이나 gloo 같은 라이브러리를 많이 사용합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NCCL (NVIDIA COllective Communication Library)
&lt;ul&gt;
&lt;li&gt;NVIDIA에서 개발한 GPU 특화 Message Passing 라이브러리 (&lt;code class=&quot;language-text&quot;&gt;nickel&lt;/code&gt;라고 읽는다고 합니다.)&lt;/li&gt;
&lt;li&gt;NVIDIA GPU에서 사용시, 다른 라이브러리에 비해 월등히 빠르다고 알려져 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GLOO (Facebook’s Collective Communication Library)
&lt;ul&gt;
&lt;li&gt;Facebook에서 개발된 Message Passing 라이브러리입니다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;torch&lt;/code&gt;에서 주로 CPU 분산 처리에 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;일반적으로는 CPU는 GLOO, GPU는 NCCL을 사용하면 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;torch.distributed 패키지&lt;/h4&gt;
&lt;p&gt;torch.distributed 패키지는 gloo, nccl, openmpi 등을 하이레벨에서 래핑하고 있기 때문에,
일반적으로는 torch.distributed를 이용해서 프로그래밍을 하게 됩니다.&lt;/p&gt;
&lt;h4&gt;Process Group&lt;/h4&gt;
&lt;p&gt;프로세스가 많은 경우, 관리하기가 어렵습니다. 이럴때는 보통 프로세스 그룹을 만들어서 관리를 합니다.
&lt;code class=&quot;language-text&quot;&gt;torch.distributed&lt;/code&gt;의 &lt;code class=&quot;language-text&quot;&gt;init_process_group&lt;/code&gt;을 호출하면 전체 프로세스가 속한 default group이 만들어집니다.&lt;/p&gt;
&lt;p&gt;주의할 점은 &lt;code class=&quot;language-text&quot;&gt;init_process_group&lt;/code&gt; 함수는 반드시 서브프로세스에서 실행되어야 하며, 추가로 사용자가 원하는 프로세스들만 모아서
그룹을 생성하려면 &lt;code class=&quot;language-text&quot;&gt;new_group&lt;/code&gt;을 호출해야 합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;예제 1&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; dist

os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;RANK&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt;
os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;LOCAL_RANK&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt;
os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;WORLD_SIZE&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;

os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MASTER_ADDR&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;localhost&quot;&lt;/span&gt;
os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MASTER_PORT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;29500&quot;&lt;/span&gt;

dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_process_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;nccl&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rank&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; wirld_size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
process_group &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;new_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;예제 2&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;multiprocessing &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; mp
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; dist


&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; world_size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_process_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;nccl&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rank&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; world_size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;world_size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    group &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;new_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;world_size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;


os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MASTER_ADDR&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;localhost&quot;&lt;/span&gt;
os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MASTER_PORT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;29500&quot;&lt;/span&gt;
os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;WORLD_SIZE&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;4&quot;&lt;/span&gt;

mp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;spawn&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  fn&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;fn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  args&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  nprocs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  join&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  daemon&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  start_method&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;spawn&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 코드의 경우 python3 ***.py와 같이 실행하면 됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;예제 3&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; dist

dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_process_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;backend&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;nccl&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
group &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;new_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_world_size&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 코드는 python3 -m torch.distributed.launch —nproc_per_node=N ***.py와 같이 실행할 수 있습니다.&lt;/p&gt;
&lt;h4&gt;P2P Communication (Point to Point)&lt;/h4&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147877032-e1439e42-8db2-451a-9098-43063ac914e1.png&quot; width=&quot;300&quot;&gt;  
&lt;p&gt;P2P 통신은 특정 프로세스에서 다른 프로세스로 데이터를 전송하는 통신입니다. torch.distributed 패키지의 &lt;code class=&quot;language-text&quot;&gt;send&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;recv&lt;/code&gt; 함수를 활용하여 통신할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; dist

dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_process_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gloo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_rank&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    tensor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;randn&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;send&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dst&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_rank&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    tensor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;rank 1 before: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;\n&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;recv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;rank 1 after: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;\n&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; RuntimeError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;wrong rank&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;send&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;recv&lt;/code&gt;는 동기적으로 통신합니다. 비동기 방식 (non-blocking)으로 사용하려면 &lt;code class=&quot;language-text&quot;&gt;isend&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;irecv&lt;/code&gt;를 사용해야 합니다.
비동기 방식에서는 &lt;code class=&quot;language-text&quot;&gt;wait()&lt;/code&gt; 메서드를 통해 다른 프로세스의 통신이 끝날때까지 기다린 뒤에 접근해야 합니다.
멀티스레딩 프로그래밍 할 때가 기억나네요 😅&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; dist

dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_process_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gloo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_rank&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    tensor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;randn&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    request &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isend&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dst&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_rank&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    tensor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    request &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;irecv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; RuntimeError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;wrong rank&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wait&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;rank &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_rank&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Collective Communication&lt;/h3&gt;
&lt;p&gt;Collective Communication은 여러 프로세스가 참여하는 통신을 의미합니다. 다양한 연산들이 있지만 기본적으로
아래 4개의 연산이 중요합니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147877159-26b24204-de88-416b-9ad0-5c1061a82c26.png&quot; width=&quot;450&quot;&gt;
&lt;p&gt;여기 4개에 추가로 &lt;code class=&quot;language-text&quot;&gt;all-reduce&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;all-gather&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;reduce-scatter&lt;/code&gt; 등의 복합 연산과 동기화 연산인 &lt;code class=&quot;language-text&quot;&gt;barrier&lt;/code&gt;까지 총 8개 연산에 대해 아래에서 알아보겠습니다.&lt;/p&gt;
&lt;h4&gt;Broadcast&lt;/h4&gt;
&lt;p&gt;Broadcast는 특정 프로세스의 데이터를 그룹내의 모든 프로세스에 복사하는 연산입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147877187-10e16fb5-620f-496f-b52f-04769d47ad69.png&quot; width=&quot;400&quot;&gt;  
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;torch.distributed.broadcast&lt;/code&gt;로 사용 가능합니다. &lt;code class=&quot;language-text&quot;&gt;broadcast&lt;/code&gt;는 상황에 따라서 P2P 통신 용도로도 사용 가능합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;참고 예제 (deepspeed/runtime/pipe/p2p.py)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dest_stage&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; async_op&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;global&lt;/span&gt; _groups
    &lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; async_op &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Doesnt support async_op true&quot;&lt;/span&gt;
    src_stage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; _grid&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_stage_id&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    _is_valid_send_recv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;src_stage&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dest_stage&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    dest_rank &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; _grid&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;stage_to_global&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stage_id&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;dest_stage&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; async_op&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;global&lt;/span&gt; _async
        op &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isend&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dest_rank&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        _async&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;op&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; can_send_recv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;send&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dest_rank&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            group &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; _get_send_recv_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;src_stage&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dest_stage&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            src_rank &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; _grid&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;stage_to_global&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stage_id&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;src_stage&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;broadcast&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; src_rank&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; group&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;group&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; async_op&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;async_op&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Reduce&lt;/h4&gt;
&lt;p&gt;Reduce는 각 프로세스가 가진 데이터로 특정 연산을 수행해서 출력을 하나의 디바이스로 모아주는 연산입니다.
주로 sum, max, min 등의 연산을 수행합니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147877296-57e4f5e4-9d50-4424-a674-08e3d5ecc20a.png&quot; width=&quot;400&quot;&gt;  
&lt;ul&gt;
&lt;li&gt;Reduce sum 예시&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; dist

dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_process_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;nccl&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
rank &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_rank&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;set_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

tensor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ones&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; rank
&lt;span class=&quot;token comment&quot;&gt;# rank==0 =&gt; [[0, 0], [0, 0]]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank==1 =&gt; [[1, 1], [1, 1]]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank==2 =&gt; [[2, 2], [2, 2]]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank==3 =&gt; [[3, 3], [3, 3]]&lt;/span&gt;

dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; op&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReduceOp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SUM&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dst&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; rank &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# tensor([[6., 6.],&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#         [6., 6.]]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Scatter&lt;/h4&gt;
&lt;p&gt;Scatter는 여러 element를 쪼개서 각 device에 뿌려주는 연산입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147877358-f444a3e4-de35-4bd9-bb1d-9825b505add2.png&quot; width=&quot;400&quot;&gt;
&lt;ul&gt;
&lt;li&gt;예시&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; dist

dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_process_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gloo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# nccl은 scatter를 지원하지 않습니다.&lt;/span&gt;
rank &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_rank&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;set_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;


output &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;before rank &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;output&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;\n&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; rank &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    inputs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    inputs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;inputs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dim&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; split_size_or_sections&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# (tensor([10]), tensor([20]), tensor([30]), tensor([40]))&lt;/span&gt;
    dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scatter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;output&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; scatter_list&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;inputs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scatter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;output&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;after rank &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;output&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;\n&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# before rank 0: tensor([0.])&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# before rank 3: tensor([0.])&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# after rank 3: tensor([40.])&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# before rank 1: tensor([0.])&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# before rank 2: tensor([0.])&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# after rank 0: tensor([10.])&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# after rank 1: tensor([20.])&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# after rank 2: tensor([30.])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;nccl&lt;/code&gt;에서는 scatter 연산이 지원되지 않아서 아래 같은 방법으로 scatter 연산을 수행합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; dist

dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_process_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;nccl&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
rank &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_rank&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;set_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

inputs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
inputs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tensor&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;inputs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dim&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; split_size_or_sections&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
output &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; inputs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contiguous&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;after rank &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;output&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;\n&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# after rank 2: tensor([30.], device=&apos;cuda:2&apos;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# after rank 3: tensor([40.], device=&apos;cuda:3&apos;) &lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# after rank 0: tensor([10.], device=&apos;cuda:0&apos;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# after rank 1: tensor([20.], device=&apos;cuda:1&apos;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Megatron-LM Scatter 예시&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;_split&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;input_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Split the tensor along its last dimension and keep the
    corresponding slice.&quot;&quot;&quot;&lt;/span&gt;

    world_size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; get_tensor_model_parallel_world_size&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Bypass the function if we are using only 1 GPU.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; world_size&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; input_

    &lt;span class=&quot;token comment&quot;&gt;# Split along last dimension.&lt;/span&gt;
    input_list &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; split_tensor_along_last_dim&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;input_&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; world_size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Note: torch.split does not create contiguous tensors by default.&lt;/span&gt;
    rank &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; get_tensor_model_parallel_rank&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    output &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; input_list&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contiguous&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; output

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;_ScatterToModelParallelRegion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;autograd&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Function&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Split the input and keep only the corresponding chuck to the rank.&quot;&quot;&quot;&lt;/span&gt;

    &lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@staticmethod&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;symbolic&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;graph&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; input_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; _split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;input_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@staticmethod&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; input_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; _split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;input_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@staticmethod&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;backward&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; grad_output&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; _gather&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;grad_output&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Gather&lt;/h4&gt;
&lt;p&gt;Gather는 여러 디바이스에 존재하는 텐서를 하나로 모아주는 연산입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147877443-3e479d6f-c7e0-4da4-9f77-723e7e3208a6.png&quot; width=&quot;400&quot;&gt;
&lt;ul&gt;
&lt;li&gt;gather 예시&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; dist

dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_process_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gloo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# nccl은 gather를 지원하지 않습니다.&lt;/span&gt;
rank &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_rank&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;set_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ones&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; rank
&lt;span class=&quot;token comment&quot;&gt;# rank==0 =&gt; [0]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank==1 =&gt; [1]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank==2 =&gt; [2]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank==3 =&gt; [3]&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; rank &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    outputs_list &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gather&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; gather_list&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;outputs_list&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dst&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;outputs_list&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gather&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dst&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# [tensor([0.]), tensor([1.]), tensor([2.]), tensor([3.])]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;All-reduce&lt;/h4&gt;
&lt;p&gt;이름 앞에 All이 붙은 연산들은 해당 연산을 수행한 뒤, 결과를 모든 디바이스로 broadcast하는 연산입니다.
아래 그림은 All-reduce의 예시입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147877565-20269bae-5962-4fbb-a392-77999b0812a2.png&quot; width=&quot;400&quot;&gt;
&lt;ul&gt;
&lt;li&gt;All-reduce sum 예시&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; dist

dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_process_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;nccl&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
rank &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_rank&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;set_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

tensor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ones&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; rank
&lt;span class=&quot;token comment&quot;&gt;# rank==0 =&gt; [[0, 0], [0, 0]]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank==1 =&gt; [[1, 1], [1, 1]]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank==2 =&gt; [[2, 2], [2, 2]]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank==3 =&gt; [[3, 3], [3, 3]]&lt;/span&gt;

dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;all_reduce&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; op&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReduceOp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SUM&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;rank &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;\n&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# rank 1: tensor([[6., 6.],&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#         [6., 6.]], device=&apos;cuda:1&apos;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 2: tensor([[6., 6.],&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#         [6., 6.]], device=&apos;cuda:2&apos;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 0: tensor([[6., 6.],&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#         [6., 6.]], device=&apos;cuda:0&apos;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 3: tensor([[6., 6.],&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#         [6., 6.]], device=&apos;cuda:3&apos;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;All-gather&lt;/h4&gt;
&lt;p&gt;All-gather는 gather를 수행한 뒤, 모아진 결과를 모든 디바이스로 복사합니다.
All-reduce와 비슷해보이지만 결과를 보면 다른 연산인 것을 알 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; dist

dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_process_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;nccl&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
rank &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_rank&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;set_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ones&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; rank
&lt;span class=&quot;token comment&quot;&gt;# rank==0 =&gt; [0]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank==1 =&gt; [1]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank==2 =&gt; [2]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank==3 =&gt; [3]&lt;/span&gt;

outputs_list &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; device&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; device&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; device&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; device&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;all_gather&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tensor_list&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;outputs_list&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; tensor&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;outputs_list&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# [tensor([0.], device=&apos;cuda:1&apos;), tensor([1.], device=&apos;cuda:1&apos;), tensor([2.], device=&apos;cuda:1&apos;), tensor([3.], device=&apos;cuda:1&apos;)]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# [tensor([0.], device=&apos;cuda:0&apos;), tensor([1.], device=&apos;cuda:0&apos;), tensor([2.], device=&apos;cuda:0&apos;), tensor([3.], device=&apos;cuda:0&apos;)]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# [tensor([0.], device=&apos;cuda:2&apos;), tensor([1.], device=&apos;cuda:2&apos;), tensor([2.], device=&apos;cuda:2&apos;), tensor([3.], device=&apos;cuda:2&apos;)]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# [tensor([0.], device=&apos;cuda:3&apos;), tensor([1.], device=&apos;cuda:3&apos;), tensor([2.], device=&apos;cuda:3&apos;), tensor([3.], device=&apos;cuda:3&apos;)]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Reduce-scatter&lt;/h4&gt;
&lt;p&gt;Reduce scatter는 Reduce를 수행한 뒤, 결과를 쪼개서 디바이스에 반환합니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147877668-57d1728c-1451-4f6a-a37a-6c59bcb42d68.png&quot; width=&quot;400&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Reduce scatter 예제&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; dist

dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_process_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;nccl&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
rank &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_rank&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;set_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

input_list &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; rank
input_list &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;input_list&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dim&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; split_size_or_sections&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank==0 =&gt; [0, 00, 000, 0000]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank==1 =&gt; [1, 10, 100, 1000]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank==2 =&gt; [2, 20, 200, 2000]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank==3 =&gt; [3, 30, 300, 3000]&lt;/span&gt;

output &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; device&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current_device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;reduce_scatter&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    output&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;output&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    input_list&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;input_list&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    op&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReduceOp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SUM&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;rank &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;output&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;\n&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# rank 0: tensor([6], device=&apos;cuda:0&apos;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 2: tensor([600], device=&apos;cuda:2&apos;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 1: tensor([60], device=&apos;cuda:1&apos;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 3: tensor([6000], device=&apos;cuda:3&apos;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Barrier&lt;/h4&gt;
&lt;p&gt;Barrier는 프로세스 동기화를 위해 사용됩니다. 먼저 barrier에 도착한 프로세스는 모든 프로세스가 해당 지점까지 실행되는 것을 기다립니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; time
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; dist

dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_process_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;nccl&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
rank &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_rank&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; rank &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    seconds &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; seconds &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        seconds &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;rank 0 - seconds: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;seconds&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;\n&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;rank &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;: no-barrier\n&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
dist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;barrier&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;rank &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;rank&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;: barrier\n&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# rank 2: no-barrier&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 1: no-barrier&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 3: no-barrier&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 0 - seconds: 1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 0 - seconds: 2&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 0 - seconds: 3&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 0 - seconds: 4&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 0: no-barrier&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 0: barrier&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 1: barrier&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 3: barrier&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# rank 2: barrier&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Large Scale LM (1) Background]]></title><description><![CDATA[Large Scale LM (1) Background 이 자료는 [해당 link…]]></description><link>https://sooftware.github.io/big-model1/</link><guid isPermaLink="false">https://sooftware.github.io/big-model1/</guid><pubDate>Mon, 22 Nov 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Large Scale LM (1) Background&lt;/h1&gt;
&lt;p&gt;이 자료는 &lt;a href=&quot;https://github.com/tunib-ai/large-scale-lm-tutorials&quot;&gt;[해당 link]&lt;/a&gt; 를 참고하며 제 언어로 재작성한 글입니다.&lt;br&gt;
저의 추가적인 메모나 의견이 삽입되거나 삭제된 내용이 있습니다.&lt;br&gt;
더 퀄리티가 좋은 자료는 위의 링크를 참고하시길 바랍니다.&lt;/p&gt;
&lt;h2&gt;Motivation&lt;/h2&gt;
&lt;p&gt;2020년에 등장한 GPT-3는 역대 최고의 언어모델로 여겨지고 있습니다. 아키텍처보다도 더 많은 데이터, 더 큰 사이즈의 모델이
가장 중요하다고 여겨지게 만들어준 장본인이죠. 개인적으로는 지금까지 나온 모델 중에는 AGI(Artificial General Intelligence)에 가장 가까운
모델이라고 생각합니다. 그래서 저는 더 많은 데이터를 모으고, 이런 데이터를 많이 먹을 수 있는 Large-Scale 모델 학습 관련 기술이 굉장히
중요하다고 생각합니다.&lt;/p&gt;
&lt;h2&gt;모델 아키텍처가 그다지 중요하지 않다?&lt;/h2&gt;
&lt;p&gt;지금까지도 많은 논문이 새로운 모델 아키텍처를 도입하기 위한 연구를 많이 해왔습니다. 하지만 아쉽게도 트랜스포머의 등장 이후로는
큰 아키텍처의 변화보다는 트랜스포머 모델의 최적화가 더 많은 변화를 가져온 것 같습니다. 그리고 최근 연구 결과에 따르면
모델 아키텍처 자체는 그렇게 중요하지 않다라는 뉘앙스의 논문도 많이 나오고 있습니다. 그리고 이러한 결과를 뒷받침하듯, GPT-3가 아키텍처는
GPT-2를 유지하면서 많은 데이터와, 파라미터 수를 늘렸더니 엄청난 성능 향상을 보여줘서 전 세계를 놀라게했죠.&lt;/p&gt;
&lt;img src=&quot;https://github.com/tunib-ai/large-scale-lm-tutorials/raw/ca29ff9f945a59abcc3e3f1000c4d83de97973d4/images/arch_is_not_important.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;그래서 결국 지금까지의 연구 결과들을 놓고보자면, 관건은 데이터와 모델의 크기가 가장 중요한 것 같습니다.
단순히 벤치마크 성능만 올라가는게 아니라 Fine-tuning 없이도 번역, 요약, 분류 등의 태스크를 하는 등 새로운 지표를 열어서
Prompt-Engineering이라는 용어까지 나오며 새로운 트렌드로 자리잡았습니다.&lt;/p&gt;
&lt;img src=&quot;https://github.com/tunib-ai/large-scale-lm-tutorials/raw/ca29ff9f945a59abcc3e3f1000c4d83de97973d4/images/scale_is_all_you_need.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;위의 그래프에서 볼 수 있듯이, 모델 성능에 가장 중요한건 모델의 사이즈, 다음이 데이터의 크기라는 걸 볼 수 있습니다.
Y축이 log-scale이라는 것을 생각하면 모델의 크기가 성능에 미치는 영향은 실로 엄청납니다.&lt;/p&gt;
&lt;h2&gt;이대로 간다면..?&lt;/h2&gt;
&lt;img src=&quot;https://github.com/tunib-ai/large-scale-lm-tutorials/raw/ca29ff9f945a59abcc3e3f1000c4d83de97973d4/images/GPT-X.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;이대로 간다면 몇년 뒤에는 GPT-3와도 비교도 안 될 만큼 큰 모델들이 등장하며, 더 마법같은 일을 보여주지 않을까 싶습니다.
한국에서도 네이버가 빠르게 앞장서서 하이퍼클로바라는 모델을 만들어서 한국어 GPT-3를 만들었고, 카카오브레인도 최근에 GPT-6B 모델을
오픈소스로 공개하며 앞으로 더 큰 모델을 공개하겠다는 포부를 밝혔죠. Large-Scale LM은 이제는 엄연한 트렌드로 받아들여야 할 것 같습니다.&lt;/p&gt;
&lt;h2&gt;장벽&lt;/h2&gt;
&lt;img src=&quot;https://github.com/tunib-ai/large-scale-lm-tutorials/raw/ca29ff9f945a59abcc3e3f1000c4d83de97973d4/images/hard_core_engineering.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;하지만 현실적으로 Large-Scale 모델 학습은 굉장히 어렵습니다. 개념적으로도 Megatron-LM, Zero 등을 이해해야하며
뒤이어 따라오는 엔지니어링 능력은 실로 많은 능력을 필요로합니다. 빅데이터 처리 기술 역시 마찬가지고요. 그래서 Large-Scale LM 학습을 위해 필요한 많은 지식들을
공부하며 블로그에 기록해보려고 합니다. 모델 학습부터 시작해서 데이터 처리, 이후 배포 등 많은 엔지니어링 기술을 필요로 할텐데 하나하나 공부하며 기록해보겠습니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[튜닙 블로그 개편]]></title><description><![CDATA[튜닙 블로그 개편 2021.11.16일자로 튜닙 블로그가 개편되었습니다! 기존에는 노션을 이용해 다소 밋밋한 텍스트 위주의 UI…]]></description><link>https://sooftware.github.io/tunib-blog/</link><guid isPermaLink="false">https://sooftware.github.io/tunib-blog/</guid><pubDate>Sat, 20 Nov 2021 11:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;튜닙 블로그 개편&lt;/h1&gt;
&lt;p&gt;2021.11.16일자로 튜닙 블로그가 개편되었습니다!&lt;br&gt;
기존에는 노션을 이용해 다소 밋밋한 텍스트 위주의 UI 였는데, 이번에 티스토리로 옮기면서 카드 형식으로 보는 느낌을
바꿔 보았습니다. 튜닙 블로그는 현재 아래와 같은 섹션들로 구성되어 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;최신 글: 대문 페이지는 섹션에 관계없이 최신 글 10개를 노출합니다.&lt;/li&gt;
&lt;li&gt;STORY: 튜닙의 이모저모를 소개하고 뒷이야기들을 다룹니다.&lt;/li&gt;
&lt;li&gt;NEWS: 튜닙의 여러 소식들을 알립니다.&lt;/li&gt;
&lt;li&gt;PRESS: 튜닙과 관련된 언론 보도들을 소개합니다.편&lt;/li&gt;
&lt;li&gt;TECH: 기술적인 내용들을 다룹니다. 튜닙의 기술뿐 아니라 AI 기술 이야기도 합니다.&lt;/li&gt;
&lt;li&gt;PEOPLE: 튜니버들을 소개합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;튜닙 블로그는 진지하고 딱딱한 분위기를 지양합니다. 대신, 가볍고 잔잔하게, 자주 튜닙의 소식들을 관심 있는 분들께 전달하는 것이 취지입니다. 앞으로도 자주 글을 올릴 예정입니다!&lt;/p&gt;
&lt;p&gt;튜닙 블로그 링크: &lt;a href=&quot;https://tunib.tistory.com/&quot;&gt;https://tunib.tistory.com/&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[튜닙, 30억 규모 시드투자 유치]]></title><description><![CDATA[튜닙, 30억 규모 시드투자 유치 저희 튜닙이 30억 규모의 시드투자를 유치했습니다! 😄 😄 이번 투자에는 펄어비스캐피탈(PAC), DSC인베스트먼트, 네이버 D2SF…]]></description><link>https://sooftware.github.io/tunib-seed/</link><guid isPermaLink="false">https://sooftware.github.io/tunib-seed/</guid><pubDate>Tue, 16 Nov 2021 11:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;튜닙, 30억 규모 시드투자 유치&lt;/h1&gt;
&lt;p&gt;저희 튜닙이 30억 규모의 시드투자를 유치했습니다! 😄 😄&lt;br&gt;
이번 투자에는 펄어비스캐피탈(PAC), DSC인베스트먼트, 네이버 D2SF 세 곳이 참여해 주셨습니다.
앞으로 더 발전하는 모습 보여드리겠습니다!&lt;/p&gt;
&lt;p&gt;기사링크: &lt;a href=&quot;https://platum.kr/archives/175048&quot;&gt;https://platum.kr/archives/175048&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[광운대학교 SW 중심대학사업단에서 SW 전문가 특강]]></title><description><![CDATA[광운대학교 SW 중심대학사업단에서 SW 전문가 특강 2021.11.04에 모교인 광운대학교 컴퓨터공학과 학생들을 대상으로 SW…]]></description><link>https://sooftware.github.io/ssdc_2021_2/</link><guid isPermaLink="false">https://sooftware.github.io/ssdc_2021_2/</guid><pubDate>Sat, 30 Oct 2021 11:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;광운대학교 SW 중심대학사업단에서 SW 전문가 특강&lt;/h1&gt;
&lt;p&gt;2021.11.04에 모교인 광운대학교 컴퓨터공학과 학생들을 대상으로 SW 전문가 특강 강의를 하게 됐습니다.
올해 초에 졸업한 학과인 전자통신공학과 학생들 대상으로는 한 번 발표를 했는데, 이번에는 컴퓨터공학과 학생들 대상으로 강의를 하게 됐네요.&lt;/p&gt;
&lt;p&gt;내용은 제 소개와 제가 하는 일에 대한 소개 및 튜닙 소개와 홍보를 조금 할 예정입니다 :)&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - DeepSpeed Usage]]></title><description><![CDATA[DeepSpeed Usage…]]></description><link>https://sooftware.github.io/deepspeed/</link><guid isPermaLink="false">https://sooftware.github.io/deepspeed/</guid><pubDate>Sat, 30 Oct 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;DeepSpeed Usage&lt;/h1&gt;
&lt;p&gt;최근 인공지능 모델은 사이즈가 점점 커지는 추세입니다.&lt;/p&gt;
&lt;img src=&quot;https://neurohive.io/wp-content/uploads/2020/02/rsz_ddad-scaled.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;다른 어떤 방법보다도 그냥 더 큰 모델, 더 많은 데이터를 집어넣으면 더 좋은 모델이 만들어지는게 현실인 것 같습니다.
문제는 큰 모델은 학습시키기가 어렵다는 건데요, 많이 쓰이는 비싼 GPU A100이 메모리 40GB인데, 2B 넘어가는 모델은
학습시에 GPU 1대에 올릴수가 없어서 Model Parallelism과 같은 방법으로 모델을 쪼개서 GPU에 올리거나 해야합니다.&lt;/p&gt;
&lt;img src=&quot;https://xiandong79.github.io/downloads/ddl1.png&quot; width=&quot;400&quot;&gt;  
&lt;p&gt;근데 이런 Model Parallelism을 직접 하나하나 구현하려면 굉장히 어렵습니다.
하지만 고맙게도 Microsoft에서 DeepSpeed라는 오픈소스를 공개해주었습니다.&lt;/p&gt;
&lt;p&gt;DeepSpeed는 지나치게 큰 모델에 대한 트레이닝에 어려움을 겪는 개발자들을 위해 기존보다 10배 이상 큰 모델을 5배 이상의 속도로 게다가 코드 변화 거의 없이 학습 시킬 수 있는 혁명적인 오픈소스 라이브러리입니다.&lt;/p&gt;
&lt;p&gt;이번 포스트에서는 DeepSpeed 사용법에 대해 간단하게 기록해둘까 합니다.&lt;br&gt;
예제 코드는 2.7B의 파라미터를 가진 GPT-Neo 2.7B 모델로 테스트 했습니다.&lt;/p&gt;
&lt;p&gt;Dataset 클래스 정의 등의 디테일한거는 스킵했습니다.&lt;/p&gt;
&lt;h2&gt;기존 PyTorch Code&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;utils&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; DataLoader
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; transformers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; GPTNeoForCausalLM&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; AutoTokenizer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; LineByLineDataset

device &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;cuda&apos;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;is_available&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;cpu&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

tokenizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AutoTokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;EleutherAI/gpt-neo-2.7B&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; GPTNeoForCausalLM&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;EleutherAI/gpt-neo-2.7B&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

dataset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; LineByLineDataset&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
data_loader &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; DataLoader&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dataset&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;dataset&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                         num_workers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;num_workers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                         batch_size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;batch_size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                         drop_last&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

optimizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;optim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Adam&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parameters&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lr&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
scheduler &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;optim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lr_scheduler&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OneCycleLR&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;optimizer&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;optimizer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                                                max_lr&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                                                epochs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;num_epochs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                                                steps_per_epoch&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data_loader&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                                                anneal_strategy&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;linear&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; step&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; batch &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data_loader&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    input_ids&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; attention_masks&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; labels &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; batch

    input_ids &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; input_ids&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;device&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    attention_masks &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; attention_masks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;device&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    labels &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; labels&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;device&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    outputs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;input_ids&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;input_ids&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; attention_mask&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;attention_masks&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; labels&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;labels&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    loss &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; outputs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;loss

    optimizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zero_grad&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    loss&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;backward&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;utils&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clip_grad_norm_&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parameters&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gradient_clip_val&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    optimizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    scheduler&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;DeepSpeed Code&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; deepspeed
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;utils&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; DataLoader
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; transformers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; GPTNeoForCausalLM&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; AutoTokenizer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; LineByLineDataset

torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;distributed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_process_group&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;backend&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;nccl&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
deepspeed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init_distributed&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;nccl&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

device &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;device&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;cuda&apos;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cuda&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;is_available&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;cpu&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

tokenizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AutoTokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;EleutherAI/gpt-neo-2.7B&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; GPTNeoForCausalLM&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;EleutherAI/gpt-neo-2.7B&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;train_batch_size&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;fp16&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;enabled&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;zero_optimization&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;stage&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;contiguous_gradients&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;overlap_comm&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;offload_optimizer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;device&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;cpu&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;pin_memory&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;fast_init&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;optimizer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Adam&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;params&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;lr&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3e-05&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;betas&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;token number&quot;&gt;0.9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token number&quot;&gt;0.999&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;eps&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1e-8&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

dataset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; LineByLineDataset&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
data_loader &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; DataLoader&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dataset&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;dataset&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                         num_workers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;num_workers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                         batch_size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;batch_size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                         drop_last&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; optimizer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; deepspeed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;initialize&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                                              config_params&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                                              model_parameters&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parameters&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; step&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; batch &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data_loader&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    input_ids&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; attention_masks&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; labels &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; batch

    input_ids &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; input_ids&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;device&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    attention_masks &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; attention_masks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;device&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    labels &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; labels&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;device&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    outputs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;input_ids&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;input_ids&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; attention_mask&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;attention_masks&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; labels&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;labels&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    loss &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; outputs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;loss

    model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;backward&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loss&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;기존 코드에서 큰 변화 없이 몇 가지 사항만 수정해주면 deepspeed 적용이 가능합니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware ML - Wandb Image Log]]></title><description><![CDATA[Wandb (Weights & Bias) Image Log Wandb 라이브러리는 최근에 가장 편리하면서도 파워풀한 logging 라이브러리입니다. NLP에서 많이 쓰이는 PyTorch, PyTorch-Lightning, Huggingface…]]></description><link>https://sooftware.github.io/wandb_image/</link><guid isPermaLink="false">https://sooftware.github.io/wandb_image/</guid><pubDate>Wed, 13 Oct 2021 22:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Wandb (Weights &amp;#x26; Bias) Image Log&lt;/h1&gt;
&lt;p&gt;Wandb 라이브러리는 최근에 가장 편리하면서도 파워풀한 logging 라이브러리입니다.&lt;br&gt;
NLP에서 많이 쓰이는 PyTorch, PyTorch-Lightning, Huggingface Transformers 등에서도 쉽게 사용이 가능합니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/137149370-e8de77b9-83a2-46ea-89ca-d444ba258d80.png&quot; width=&quot;800&quot;&gt;.&lt;/p&gt;
&lt;p&gt;보통 이런 logging 라이브러리는 딥러닝 모델 학습시 Loss 혹은 Metric Score를 모니터링할 때 사용합니다.&lt;br&gt;
여기서 조금 더 모델 학습을 면밀하게 보기 위해 모델의 어텐션 맵을 그려본다거나, 생성한 Mel-Spectrogram을 그려본다거나 하는 등의 logging 방식도 생각해볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;예를 들어 100 스텝마다 모델의 어텐션 맵을 그려보면서 어텐션이 어떻게 학습 되는지를 확인할 수도 있고, 모델이 생성하는 Mel-Spectrogram을 이미지로 보면서 학습 진행 과정을 볼 수도 있습니다.&lt;/p&gt;
&lt;p&gt;실제로 well-made 딥러닝 학습 코드의 경우는 이런 어텐션 맵 등을 학습 중간중간 저장하도록 짜여져 있는 경우가 많습니다.&lt;/p&gt;
&lt;p&gt;그런데 리눅스 서버에서 학습하는 경우는 일일이 노트북으로 이미지를 옮겨서 확인하는 것도 귀찮습니다.&lt;/p&gt;
&lt;p&gt;그렇기 때문에 웹 기반으로 log가 관리되는 wandb의 경우는 이런 이미지를 스텝별로 저장해놓으면 상당히 유용합니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/137151370-5df2fd57-76f3-4351-9166-d98307810b33.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;위와 같이 모델이 생성한 Mel-Spectrogram, Attention Map 등을 확인해보면 모델이 학습되는 과정을 좀 더 확실하게 알 수 있습니다.&lt;/p&gt;
&lt;h2&gt;Wandb Image Log 찍는 법&lt;/h2&gt;
&lt;p&gt;Wandb로 image log를 찍는건 굉장히 간단합니다.&lt;/p&gt;
&lt;p&gt;pandas 라이브러리의 DataFrame을 이용해서 Confusion Matrix도 찍을 수 있습니다만, 여기서는 Image 찍는 법만 다루겠습니다.&lt;/p&gt;
&lt;p&gt;Image를 찍기 위해서는 matplotlib 라이브러리를 이용해서 이미지를 저장하고 해당 이미지 파일을 넘겨주기만 하면 됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; wandb
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; matplotlib&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pyplot &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; plt

outputs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; attention_map &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;inputs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

plt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;imshow&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;attention_map&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; aspect&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;auto&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; origin&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;lower&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; interpolation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;none&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
plt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;savefig&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;attention_map.png&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; figsize&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

wandb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;log&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;Attention Map&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        wandb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Image&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;attention_map.png&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 코드를 학습하면서 주기적으로 호출해주기만 하면 Attention Map이 어떻게 학습되어 가는지를 확인할 수 있습니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - NLP Metrics]]></title><description><![CDATA[NLP Metrics Confusion Matrix Confusion Matrix는 분류 모델을 평가할때 모델이 얼마나 정밀한지, 얼마나 실용적인 분류를 해냈는지, 얼마나 정확한 분류를 해냈는지에 대한 모든 내용을 포함하고 있습니다. Accuracy…]]></description><link>https://sooftware.github.io/metric/</link><guid isPermaLink="false">https://sooftware.github.io/metric/</guid><pubDate>Wed, 13 Oct 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;NLP Metrics&lt;/h1&gt;
&lt;h2&gt;Confusion Matrix&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136820363-585e74ec-3332-43da-abc3-7445bbb1f7c3.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;Confusion Matrix는 분류 모델을 평가할때 모델이 얼마나 정밀한지, 얼마나 실용적인 분류를 해냈는지, 얼마나 정확한 분류를 해냈는지에 대한 모든 내용을 포함하고 있습니다.&lt;/p&gt;
&lt;p&gt;Accuracy, Precision, Recall, F1-Score와 같은 성능 지표를 계산할 수 있습니다.&lt;/p&gt;
&lt;h3&gt;Accuracy&lt;/h3&gt;
&lt;p&gt;가장 간단하게 성능을 측정하는 방법인 Accuracy입니다.&lt;/p&gt;
&lt;p&gt;ex) Tunib-Eelctra Downstream tasks result&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136825941-8a8a5d65-4617-45fe-8337-0d8b8cf7557a.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;위와 같이 다양한 task에서 accuracy가 사용됩니다.&lt;/p&gt;
&lt;p&gt;Accuracy는 올바르게 예측된 데이터의 수를 전체 데이터의 수로 나눈 값입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136826193-11d3a8b7-f5a4-4d9e-8a51-f521de663270.png&quot; width=&quot;500&quot;&gt;
즉 간단하게 예측값 중 일치한게 몇개인지 확인하는 방법입니다.
&lt;h4&gt;사용법&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; torchmetrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;functional &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; accuracy
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; target &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; preds &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; accuracy&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;preds&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Recall&lt;/h3&gt;
&lt;p&gt;accuracy는 데이터에 따라 잘못된 통계를 나타낼 수도 있습니다. 극단적인 예를 들자면, 정답의 비율이 False와 True가 9:1일 경우, 모두 False로 예측해버리면 True가 많지 않기 때문에 매우 높은 accuracy를 얻을 수 있습니다.&lt;/p&gt;
&lt;p&gt;이럴 때 사용하는 방법이 바로 Recall입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136832571-70189d00-2e3d-4ab6-b74f-40b4b3289e60.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;Recall은 실제로 True인 데이터를 모델이 True라고 예측한 데이터의 수입니다. 즉 True에 대한 예측결과값만 계산하는 것입니다.&lt;/p&gt;
&lt;h4&gt;사용법&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; torchmetrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;functional &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; recall
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; preds  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; target &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; recall&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;preds&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; average&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;macro&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; num_classes&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.3333&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; recall&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;preds&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; average&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;micro&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.2500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;macro&lt;/code&gt;: 각 클래스에 대한 메트릭을 개별적으로 계산하고 클래스 전체의 metric 평균화
&lt;code class=&quot;language-text&quot;&gt;micro&lt;/code&gt;: 모든 샘플 및 클래스에 대해 전역적으로 metric 계산&lt;/p&gt;
&lt;h3&gt;Precision&lt;/h3&gt;
&lt;p&gt;역시 Recall도 한계가 있습니다. 정답의 비율이 False와 True가 9:1인 데이터를 다시 예시로 들면 모델이 전부 False로 예측한 것을 반대로 전부 True로 예측했다고 가정해보면 Recall이 1이 되는 것을 확인 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;이런 경우 precision을 통해 새로운 지표를 얻을 수 있습니다.&lt;/p&gt;
&lt;p&gt;이전에 Recall은 &lt;code class=&quot;language-text&quot;&gt;정답&lt;/code&gt;이 True인 데이터중에서 &lt;code class=&quot;language-text&quot;&gt;모델&lt;/code&gt;이 True로 예측한 데이터의 수라면, Precision은 &lt;code class=&quot;language-text&quot;&gt;모델&lt;/code&gt;이 True라고 예측한 데이터 중 &lt;code class=&quot;language-text&quot;&gt;정답&lt;/code&gt;이 True인 데이터의 수입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136833856-f031bca2-0014-42ca-936b-14427a46a294.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;Note: Precision과 recall은 서로 trade-off되는 관계입니다.&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;사용법&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; torchmetrics &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Precision
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; preds  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; target &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; precision &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Precision&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;average&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;macro&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; num_classes&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; precision&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;preds&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.1667&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; precision &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Precision&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;average&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;micro&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; precision&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;preds&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.2500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;F1 Score&lt;/h3&gt;
&lt;p&gt;ex) HyperCLOVA Experimental Results&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136829590-3f31851b-aa42-4921-89a1-0325f7cf253d.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;앞선 설명을 통해 정반대의 성격을 가진 Precision과 Recall을 확인 할 수 있었습니다. 이번엔 정 반대의 성격을 가진 두 지표를 응용한 F1 Score입니다.&lt;/p&gt;
&lt;p&gt;F1 Score는 precision과 recall의 조화평균입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136835253-77b7beeb-7f3e-4cf0-8db7-40c88b3b0097.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;일반적인 평균이 아닌 조화 평균을 계산하였는데, 그 이유는 precision과 recall이 &lt;code class=&quot;language-text&quot;&gt;0&lt;/code&gt;에 가까울수록 F1 score도 동일하게 낮은 값을 갖도록 하기 위함입니다.&lt;/p&gt;
&lt;h4&gt;사용법&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; torchmetrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;functional &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; f1
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; target &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; preds &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; f1&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;preds&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; num_classes&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.3333&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;EM(Exact Match)&lt;/h2&gt;
&lt;p&gt;EM은 말그대로 정확하게 전부 일치하는지 측정하는 simple한 metric입니다.&lt;/p&gt;
&lt;p&gt;모든 character가 일치하면 &lt;code class=&quot;language-text&quot;&gt;EM=1&lt;/code&gt;, 그 외의 경우는 모두 &lt;code class=&quot;language-text&quot;&gt;EM=0&lt;/code&gt;이 됩니다. EM=1인 sample수에 전체 sample수를 나눠 값을 구할 수 있습니다.&lt;/p&gt;
&lt;h2&gt;BLEU Score(Bilingual Evaluation Understudy Score)&lt;/h2&gt;
&lt;p&gt;BLEU는 기계 번역의 성능이 얼마나 뛰어난가를 측정하기 위해 사용되는 대표적인 방법으로 측정 기준은 n-gram과 precision에 기반합니다.&lt;/p&gt;
&lt;h3&gt;n-gram&lt;/h3&gt;
&lt;p&gt;n-gram은 n개의 연속적인 단어 나열을 의미합니다.&lt;/p&gt;
&lt;p&gt;ex) &lt;strong&gt;An adorable little boy is spreading smiles&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;1-gram(unigrams) : an, adorable, little, boy, is, spreading, smiles
2-gram(bigrams) : an adorable, adorable little, little boy, boy is, is spreading, spreading smiles
3-gram(trigrams) : an adorable little, adorable little boy, little boy is, boy is spreading, is spreading smiles
4-grams : an adorable little boy, adorable little boy is, little boy is spreading, boy is spreading smiles&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;1. 단어 개수 카운트로 측정하기(Unigram Precision)&lt;/h3&gt;
&lt;p&gt;단순하게 일치하는 단어의 개수로 성능을 측정하는 방법입니다.&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;ex)
번역기로 번역된 문장: Candidate, 사람이 직접 번역한 문장: Reference&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136810698-9fcee7a2-33b3-4a18-92a7-c8b0eb5ce40a.png&quot; width=&quot;700&quot;&gt;
&lt;h3&gt;2. Modified Unigram Precision&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Modified Unigram Precision은 중복되는 단어는 제거하여 측정하는 방법입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;Candidate : the the the the the the the

Reference1 : the cat is on the mat

Reference2 : there is a cat on the mat&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;예시의 candidate는 the만 7개나 나오는 말도 안되는 번역이지만 일반 Unigram Precision방법을 사용하면 1이라는 최고의 성능이 나오게 됩니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136811641-7380d02f-d983-4c68-87d4-4607c3d00ccf.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;따라서 Reference에 등장하는 단어의 max_count를 고려합니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136812473-3df9dfbb-f8df-474c-b160-3457162c3d24.png&quot; width=&quot;700&quot;&gt;
&lt;h3&gt;3. n-gram으로 확장&lt;/h3&gt;
&lt;p&gt;이번엔 단어의 순서를 고려하기 위해 unigram이 아닌 bigram이상의 n-gram을 고려하는 방법입니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;Candidate2 : the cat the cat on the mat

Reference1 : the cat is on the mat

Reference2 : there is a cat on the mat&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136819439-404d8c8c-944b-4475-b107-288b01844fb3.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;결과적으로 ca2의 바이그램 정밀도는 6분의 4가 됩니다.&lt;/p&gt;
&lt;p&gt;이렇게 n-gram을 이용해 성능을 평가하는 방법이 BLEU입니다.&lt;/p&gt;
&lt;h3&gt;사용법&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136819917-8cced83d-e9a0-4587-9fdc-51638e6bd6ff.png&quot; width=&quot;500&quot;&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; torchtext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;metrics &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; bleu_score
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; candidate_corpus &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;My&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;full&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pytorch&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;test&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Another&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Sentence&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; references_corpus &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;My&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;full&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pytorch&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;test&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Completely&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Different&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;No&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Match&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; bleu_score&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;candidate_corpus&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; references_corpus&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;0.8408964276313782&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;ROUGE(Recall-Oriented Understudy for Gisting Evaluation)&lt;/h2&gt;
&lt;p&gt;ROUGE는 텍스트 요약, 기계번역과 같은 task를 평가하기 위해 사용되는 대표적인 Metric입니다.&lt;/p&gt;
&lt;p&gt;이전에 설명 드렸던 BLEU가 n-gram precision에 기반한 지표라면, ROUGE는 이름 그대로 n-gram Recall에 기반해 계산됩니다.&lt;/p&gt;
&lt;h3&gt;1. ROUGE-N&lt;/h3&gt;
&lt;p&gt;ROUGE계산시 n-gram에 따라 다르게 계산하는 것이 ROUGE-N기법입니다.&lt;/p&gt;
&lt;p&gt;ex) ROUGE-1: unigram&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136845207-e98238bc-10f5-4d46-9a7c-c0e8e5ab5dd7.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;ex) ROUGE-2: bigram&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136845309-6376c71a-7450-4757-aa31-2ea20378b7db.png&quot; width=&quot;500&quot;&gt;
&lt;h3&gt;2. ROUGE-L&lt;/h3&gt;
&lt;p&gt;가장 긴 Sequence의 recall을 구하며, Sequence는 이어지지 않아도 됩니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136845529-e57f3563-a40b-494b-b671-8c631d5e0129.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;생성된 문장의 예시와 정답문장이 완전히 일치하지는 않지만, 떨어져 있는 Sequence 형태로 정답문장과 일치하기 때문에 1의 ROUGE-L score를 얻을 수 있습니다.&lt;/p&gt;
&lt;h3&gt;3. ROUGE-W&lt;/h3&gt;
&lt;p&gt;ROUGE-W는 ROUGE-L의 방법에서 연속적인 매칭(consecutive matches)에 가중치를 주는 방법입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136846008-e31e76bb-ae8c-4275-a254-c59cc292130f.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;ROUGE-L의 관점에서는 Y_1과 Y_2의 결과가 같지만,ROUGE-W의 관점에서는 consecutive matches로 이루어진 예시인 Y1이 더 좋은 결과가 됩니다.&lt;/p&gt;
&lt;h3&gt;4. ROUGE-S&lt;/h3&gt;
&lt;p&gt;ROUGE-S는 최대 2칸(bigram) 내에 위치하는 단어 쌍의 recall을 계산합니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136846246-741d10f1-5abe-410b-b5f4-f17a59351b42.png&quot; width=&quot;500&quot;&gt;
&lt;h3&gt;5. ROUGE-SU&lt;/h3&gt;
&lt;p&gt;ROUGE-SU는 ROUGE-S의 확장된 버전입니다.&lt;/p&gt;
&lt;p&gt;아래 예시의 경우 어순을 바꿨을 뿐, 같은 의미를 가진 문장임에도 ROUGE-S가 0이 되어버립니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;정답문장 : 류현진이 공을 던졌다.
생성문장 : 던졌다 공을 류현진이&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ROUGE-SU는 Unigram을 함께 계산하여 이를 보정해줍니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;정답문장 : ((류현진,공), (류현진,던졌다), (공,던졌다), 류현진, 공, 던졌다)
생성문장 : ((던졌다,공), (던졌다,류현진), (공,류현진), 류현진, 공, 던졌다)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136846643-e58feaac-857a-4e58-9ae0-2354f60741f4.png&quot; width=&quot;500&quot;&gt;
&lt;h3&gt;사용법&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; targets &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Is your name John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; preds &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;My name is John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; rouge &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ROUGEScore&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;   
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; pprint &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; pprint
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; pprint&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rouge&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;preds&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; targets&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;rouge1_fmeasure&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;rouge1_precision&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;rouge1_recall&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;rouge2_fmeasure&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;rouge2_precision&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;rouge2_recall&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;rougeL_fmeasure&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;rougeL_precision&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;rougeL_recall&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;rougeLsum_fmeasure&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;rougeLsum_precision&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token string&quot;&gt;&apos;rougeLsum_recall&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;CER(문자 오류율)&lt;/h2&gt;
&lt;p&gt;CER계산은 &lt;code class=&quot;language-text&quot;&gt;Levenshtein distance&lt;/code&gt;의 개념을 기반으로 합니다.&lt;/p&gt;
&lt;h3&gt;Levenshtein distance&lt;/h3&gt;
&lt;p&gt;Levenshtein distance는 두 문자열 시퀀스 간의 차이를 측정하는 거리 측정법입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136838740-658bf758-51b4-41a6-abda-dfc8698694a0.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;Levenshtein distance는 위와 같이 세 가지의 오류를 고려합니다.&lt;/p&gt;
&lt;p&gt;ex) &lt;code class=&quot;language-text&quot;&gt;mitten&lt;/code&gt; &amp;#x26; &lt;code class=&quot;language-text&quot;&gt;fitting&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;m itten → f itten ( m 을 f로 대체)
fitt e n → fitt i n ( e 를 i로 대체 )
fittin → fittin g ( 끝에 g 삽입 )&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;한 문자열을 다른 것으로 변환하려면 최소 3번의 과정의 필요하기 때문에 두 문자열간의 Levenshtein distance는 3입니다.&lt;/p&gt;
&lt;h4&gt;CER(공식)&lt;/h4&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136839223-106671a0-7c42-465d-9ede-68dffad95d4b.png&quot; width=&quot;500&quot;&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;S = substitutions
D = deletions
I = insertions
N = 전체 문자 수&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;즉 Levenshtein distance에 전체 문자 수를 나눈 값이 CER입니다.&lt;/p&gt;
&lt;h3&gt;WER(단어 오류율)&lt;/h3&gt;
&lt;p&gt;WER은 문단, 문장에서 사용되며 CER의 단위를 character가 아닌 워드 단위로 계산한 값입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/136839771-6b3bdf81-d8d7-4287-b7f5-e038b864df85.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;즉 한 문장을 다른 문장으로 변환하는데 필요한 단어의 Levenshtein distance에 전체 단어수를 나눈 값입니다.&lt;/p&gt;
&lt;h4&gt;사용법&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; predictions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;this is the prediction&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;there is an other sample&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; references &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;this is the reference&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;there is another one&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; wer&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;predictions&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;predictions&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; references&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;references&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Pearson correlation coefficient&lt;/h2&gt;
&lt;p&gt;Pearson correlation coefficient는 두 변수의 선형 상관 관계를 계량화한 것 입니다.&lt;/p&gt;
&lt;p&gt;결과값을 -1 ~ 1 사이의 값이며, 서로 비슷할수록 1에 가까워지고, 0일경우 연관x, -1에 가까워 질수록 정반대를 뜻합니다.&lt;/p&gt;
&lt;p&gt;Pearson 상관 계수는 이상치의 영향을 많이 받습니다. 따라서 이상치가 존재할 경우 상관 계수의 값이 크게 변경될 수 있으므로 사전에 이상치제거가 필요합니다.&lt;/p&gt;
&lt;h4&gt;사용법&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; torchmetrics&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;functional &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; pearson_corrcoef
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; target &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; preds &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; pearson_corrcoef&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;preds&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.9849&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Spearman’s correlation coefficient&lt;/h2&gt;
&lt;p&gt;Spearman’s correlation coefficient는 두 변수의 상관 관계를 계량화한 것 입니다.&lt;/p&gt;
&lt;p&gt;Pearson과 동일하게 -1 ~ 1 사이의 값을 가지며, 서로 비슷할수록 1에 가까워지고, 0일경우 연관x, -1에 가까워 질수록 정반대를 뜻합니다.&lt;/p&gt;
&lt;p&gt;피어슨 상관 계수와의 큰 차이점은 피어슨 상관 계수는 선형 상관 관계이지만 스피어만 상관계수는 그냥 상관 관계에 대한 값입니다. 따라서 두 변수가 꼭 선형적인 관계를 가질 필요가 없습니다.&lt;/p&gt;
&lt;h4&gt;사용법&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; torchmetrics &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; SpearmanCorrcoef
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; target &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; preds &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; spearman &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; SpearmanCorrcoef&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; spearman&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;preds&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;TASK별 metric정리&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;MNLI (matched or mismatched): Accuracy
MRPC: Accuracy and F1 score
QNLI: Accuracy
QQP: Accuracy and F1 score
RTE: Accuracy
SST-2: Accuracy
STS-B: Pearson Correlation Coefficient and Spearman&amp;#39;s_Rank_Correlation_Coefficient
WNLI: Accuracy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Reference&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wikidocs.net/31695&quot;&gt;https://wikidocs.net/31695&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eunsukimme.github.io/ml/2019/10/21/Accuracy-Recall-Precision-F1-score/&quot;&gt;https://eunsukimme.github.io/ml/2019/10/21/Accuracy-Recall-Precision-F1-score/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://torchmetrics.rtfd.io/en/latest/&quot;&gt;https://torchmetrics.rtfd.io/en/latest/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/pdf/2109.04650.pdf&quot;&gt;https://arxiv.org/pdf/2109.04650.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://supkoon.tistory.com/26&quot;&gt;https://supkoon.tistory.com/26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tunib-ai/tunib-electra&quot;&gt;https://github.com/tunib-ai/tunib-electra&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://qa.fastforwardlabs.com/no%20answer/null%20threshold/bert/distilbert/exact%20match/f1/robust%20predictions/2020/06/09/Evaluating_BERT_on_SQuAD.html#Exact-Match&quot;&gt;https://qa.fastforwardlabs.com/no%20answer/null%20threshold/bert/distilbert/exact%20match/f1/robust%20predictions/2020/06/09/Evaluating_BERT_on_SQuAD.html#Exact-Match&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lunch-box.tistory.com/109&quot;&gt;https://lunch-box.tistory.com/109&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[2021 SSDC 발표 - "TUNiB Electra 개발기"]]></title><description><![CDATA[2021 SSDC 발표 - “TUNiB Electra 개발기” 영광스럽게도 이번에 열리는 SSDC(구 SOSCON) - Samsung Software Developer Conference…]]></description><link>https://sooftware.github.io/ssdc_2021/</link><guid isPermaLink="false">https://sooftware.github.io/ssdc_2021/</guid><pubDate>Sun, 10 Oct 2021 11:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;2021 SSDC 발표 - “TUNiB Electra 개발기”&lt;/h1&gt;
&lt;a href=&quot;https://www.youtube.com/watch?v=_kiDegBib9E&amp;amp;t=20s&quot;&gt;
  &lt;img src=&quot;https://i.ytimg.com/vi/_kiDegBib9E/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&amp;amp;rs=AOn4CLDIQ54wdH_tJ2soD12VVoRWoL4REA&quot; width=&quot;500&quot;&gt;
&lt;/a&gt;
&lt;p&gt;영광스럽게도 이번에 열리는 SSDC(구 SOSCON) - Samsung Software Developer Conference 행사에서 발표를 하게 됐습니다.&lt;br&gt;
주제는 얼마전에 공개한 “TUNiB Electra 개발기” 입니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - 한국어 Tacotron2]]></title><description><![CDATA[한국어 Tacotron2 이번 포스팅에서는 Tacotron2 아키텍처로 한국어 TTS 시스템을 만드는 방법에 대해 다루겠습니다. Tacotron2 Tacotron2는 17년 12월 구글이 NATURAL TTS SYNTHESIS BY…]]></description><link>https://sooftware.github.io/korean_tacotron2/</link><guid isPermaLink="false">https://sooftware.github.io/korean_tacotron2/</guid><pubDate>Sun, 10 Oct 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;한국어 Tacotron2&lt;/h1&gt;
&lt;p&gt;이번 포스팅에서는 Tacotron2 아키텍처로 한국어 TTS 시스템을 만드는 방법에 대해 다루겠습니다.&lt;/p&gt;
&lt;h2&gt;Tacotron2&lt;/h2&gt;
&lt;p&gt;Tacotron2는 17년 12월 구글이 &lt;a href=&quot;https://arxiv.org/pdf/1712.05884.pdf&quot;&gt;NATURAL TTS SYNTHESIS BY CONDITIONING WAVENET ON MEL SPECTROGRAM
PREDICTIONS&lt;/a&gt; 논문에서 제안한 Text-To-Speech 모델입니다.&lt;/p&gt;
&lt;img src=&quot;https://pytorch.org/assets/images/tacotron2_diagram.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;Text-To-Speech 아키텍처는 크게 텍스트에서 Mel-Spectrogram을 생성하는 &lt;strong&gt;Mel-Network&lt;/strong&gt;와 Mel-Spectrogram에서
Audio Signal을 생성하는 &lt;strong&gt;Vocoder&lt;/strong&gt;로 이루어져 있습니다. Tacotron2는 Mel-Network에 해당하는 구조입니다.&lt;/p&gt;
&lt;p&gt;이 Tacotron2 논문에서 이미 Mel-Network는 성능이 상당히 좋아졌기 때문에 이후 연구들은 주로 Vocoder를 개선하거나
이 Tacotron2 구조를 개선해서 Multilingual, Cross-lingual, Multi-Speaker를 적용하는 연구가 많이 나왔습니다.&lt;/p&gt;
&lt;p&gt;지금까지도 대부분의 연구에 Tacotron2가 베이스가 된 만큼 자연어처리에 트랜스포머가 있다면 TTS에는 Tacotron2가 있다고 보면 될 것 같습니다.&lt;/p&gt;
&lt;h2&gt;NVIDIA Tacotron2&lt;/h2&gt;
&lt;p&gt;TTS의 어려운 점은 입문하기 위해서는 신호처리 개념이 많이 필요하다는 것입니다. 음성인식 같은 태스크도 어느 정도의 신호처리 개념이 필요하지만,
TTS 시스템은 조금 더 신호처리 쪽에 예민하기 때문에 더 많은 지식이 요구됩니다.&lt;/p&gt;
&lt;p&gt;음성인식 시스템의 경우 &lt;code class=&quot;language-text&quot;&gt;librosa&lt;/code&gt; 라이브러리에서 MFCC 혹은 Mel-Spectrogram과 같은 피쳐를 뽑아서 그냥 바로 사용해도
성능에 크게 문제가 있지는 않습니다만, TTS 시스템은 조금 더 정교하게 피쳐를 뽑아줄 필요가 있습니다.&lt;/p&gt;
&lt;p&gt;저도 처음에 Tacotron2를 구현해본다고 그냥 &lt;code class=&quot;language-text&quot;&gt;librosa&lt;/code&gt; 라이브러리에서 Mel-Spectrogram을 뽑아서 학습했다가 모델 성능이
좋지 않았던 경험이 있습니다.&lt;/p&gt;
&lt;p&gt;하지만 다행히도, NVIDIA에서 &lt;a href=&quot;https://github.com/NVIDIA/tacotron2&quot;&gt;Tacotron2&lt;/a&gt; 를 아주 잘 구현해서 오픈소스로 공개했습니다.
NVIDIA 구현체의 경우 &lt;a href=&quot;https://github.com/NVIDIA/apex&quot;&gt;apex&lt;/a&gt; 등을 이용해서 학습 최적화를 잘 해놔서 학습 속도도 빠르다는 장점이 있어서 현재는 많은 연구들에서도 Tacotron2를 쓰는 경우는 거의 NVIDIA 구현체를 사용하고 있을 정도로 표준이 됐습니다.&lt;/p&gt;
&lt;h2&gt;NVIDIA Tacotron2 Data Format&lt;/h2&gt;
&lt;p&gt;NVIDIA Tacotron2는 아래와 같은 데이터셋 포맷을 필요로 합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;train_filelist.txt&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/data/tts_datas/000001.wav|튜닙은 자연어처리 테크 스타트업입니다
/data/tts_datas/000002.wav|타코트론은 대표적인 음성합성 모델이에요
/data/tts_datas/000003.wav|음성합성 기술 어렵지 않아요
...
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;오디오는 22050Hz의 샘플링 레이트를 가지는 오디오가 필요하며, 위 예시처럼 &lt;code class=&quot;language-text&quot;&gt;오디오 경로&lt;/code&gt;와 &lt;code class=&quot;language-text&quot;&gt;해당하는 텍스트&lt;/code&gt;를 &lt;code class=&quot;language-text&quot;&gt;|&lt;/code&gt;로 구분한 형태의 txt 파일이 필요합니다.&lt;/p&gt;
&lt;h2&gt;NVIDIA Tacotron2 for Korean&lt;/h2&gt;
&lt;p&gt;NVIDIA Tacotron2 구현체는 대표적인 TTS 데이터셋인 &lt;a href=&quot;https://keithito.com/LJ-Speech-Dataset/&quot;&gt;LJ Speech&lt;/a&gt; 데이터를 예제로 제공합니다.&lt;/p&gt;
&lt;p&gt;LJ Speech 데이터셋은 영어 데이터셋이기 때문에 한국어 데이터셋인 &lt;a href=&quot;https://www.kaggle.com/bryanpark/korean-single-speaker-speech-dataset&quot;&gt;KSS&lt;/a&gt; 과 같은
데이터셋을 사용하기 위해서는 약간의 수정이 필요합니다.&lt;/p&gt;
&lt;p&gt;영어든 한국어든 음성 처리는 똑같습니다만, 텍스트 처리를 수정해주어야 합니다. NVIDIA 구현체에서는 해당 소스코드가 &lt;code class=&quot;language-text&quot;&gt;text&lt;/code&gt; 폴더에 구현이 되어 있습니다.&lt;/p&gt;
&lt;p&gt;여기서 우리가 구현해주어야 할건 &lt;code class=&quot;language-text&quot;&gt;text_to_sequence()&lt;/code&gt; 함수입니다. 해당 함수는  &lt;code class=&quot;language-text&quot;&gt;튜닙은 자연어처리 테크 스타트업입니다&lt;/code&gt;와 같은 텍스트를 입력으로 받아
토크나이징 및 숫자 표현으로 인코딩해주는 역할을 수행합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;text_to_sequence&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;


&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text_to_sequence&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;튜닙은 자연어처리 테크 스타트업입니다&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# [18, 38, 4, 41, 58, 13, 39, 45, 105, 14, 21, 13, 27, 45, 13, 25, 16, 25, 7, 41, 105, 18, 26, 17, 39, 105, 11, 39, 18, 21, 18, 39, 13, 25, 58, 13, 41, 58, 4, 41, 5, 21, 1]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;text_to_sequence()&lt;/code&gt; 함수는 크게 3가지 기능을 수행하면 됩니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;텍스트 클리닝&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;토크나이징&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;숫자 표현으로 인코&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;텍스트 클리닝&lt;/h3&gt;
&lt;p&gt;먼저 TTS 인풋으로 어떤 문자열이 들어올지 모르므로, 허용 가능한 문자들만 들어오도록 제한해야 합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;## 그까이꺼~ 그냥~ 대애애충! 하면 되지 $^$@]][ 않나...?
=&gt; 그까이꺼 그냥 대애애충! 하면 되지 않나?&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;그리고 한국어 TTS 구현시, 단위를 문자 단위가 아닌 자소(자음, 모음) 단위로 해주어야 성능이 더 좋다고 합니다.&lt;br&gt;
즉 &lt;code class=&quot;language-text&quot;&gt;국&lt;/code&gt;이란 문자가 있으면 이거를 &lt;code class=&quot;language-text&quot;&gt;ㄱㅜㄱ&lt;/code&gt;으로 쪼개어 주어야 합니다. 그리고 여기서 중요한 점은 국의 처음에 나온 &lt;code class=&quot;language-text&quot;&gt;ㄱ&lt;/code&gt;과
끝에 나온 &lt;code class=&quot;language-text&quot;&gt;ㄱ&lt;/code&gt;이 서로 다르다는 점입니다. 우리 눈에는 똑같은 &lt;code class=&quot;language-text&quot;&gt;ㄱ&lt;/code&gt;이지만, 컴퓨터 내에서는 초성과 종성을 다르게 처리할 수 있습니다.&lt;/p&gt;
&lt;p&gt;한국어 TTS 시스템에서는 이렇게 초성과 종성을 서로 다르게 표현해주어야 합니다. 다음 예제처럼 &lt;code class=&quot;language-text&quot;&gt;unicodedata&lt;/code&gt; 라이브러리를 사용하면 쉽게 적용 가능합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Normalize X&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;타코트론&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; t &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; end&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 타 코 트 론&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;NFKD Normalize&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; unicodedata

text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;타코트론&quot;&lt;/span&gt;
text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; unicodedata&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;normalize&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;NFKD&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; t &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; end&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# ㅌ ㅏ ㅋ ㅗ ㅌ ㅡ ㄹ ㅗ ㄴ &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이렇게 NFKD 방식으로 문자열을 분해해주게 되면 초성, 중성, 종성을 분리할 수 있습니다.&lt;br&gt;
참고: 이렇게 분리한 텍스트는 NFKC 방식으로 다시 문자 형태로 합칠 수 있습니다.&lt;/p&gt;
&lt;p&gt;아래는 제가 구현한 텍스트 클리닝 함수입니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; re
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; unicodedata

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normalize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; unicodedata&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;normalize&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;NFKD&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;upper&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;replace&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;%&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; unicodedata&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;normalize&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;NFKD&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;퍼센트&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    regex &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; unicodedata&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;normalize&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;NFKD&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;r&quot;[^ \u11A8-\u11FF\u1100-\u115E\u1161-\u11A70-9A-Z?!]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; re&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sub&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;regex&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; re&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sub&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; +&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; text&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;토크나이징 &amp;#x26; 인코딩&lt;/h3&gt;
&lt;p&gt;텍스트 클리닝을 했으면, 이제 토크나이징 및 인코딩을 수행해야 합니다.&lt;/p&gt;
&lt;p&gt;이미 앞의 텍스트 클리닝 과정에서 NFKD로 텍스트를 분해해놨기 때문에, 텍스트를 for문만 돌리면 쉽게 토크나이징이 가능합니다.&lt;/p&gt;
&lt;p&gt;하지만 토크나이징을 하면서 동시에 숫자 형태로 인코딩을 수행해주기 위해서는 Vocabulary를 먼저 정의해야합니다.
Vocabulary는 모델에 입력될 수 있는 모든 텍스트를 숫자와 1:1 매핑을 시켜주는 dictionary 형태로 생각해주시면 됩니다.&lt;/p&gt;
&lt;p&gt;저는 한국어 TTS 시스템에 사용할 Vocabulary를 다음과 같이 구성했습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;스페셜 토큰: _, ~ (pad, eos)&lt;/li&gt;
&lt;li&gt;초성: 0x1100 ~ 0x1113&lt;/li&gt;
&lt;li&gt;중성: 0x1161 ~ 0x1176&lt;/li&gt;
&lt;li&gt;종성: 0x11A8 ~ 0x11C3&lt;/li&gt;
&lt;li&gt;알파벳: ABCDEFGHIJKLMNOPQRSTUVWXYZ&lt;/li&gt;
&lt;li&gt;숫자: 0123456789&lt;/li&gt;
&lt;li&gt;특수문자: ?! (띄어쓰기 포함)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;해당 Vocabulary를 구성하는 코드는 아래와 같습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;CHOSUNGS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; _ &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x1100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x1113&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
JOONGSUNGS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; _ &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x1161&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x1176&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
JONGSUNGS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; _ &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x11A8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x11C3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
ALPHABETS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;&lt;/span&gt;
NUMBERS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0123456789&quot;&lt;/span&gt;
SPECIALS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; ?!&quot;&lt;/span&gt;

ALL_VOCABS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    CHOSUNGS&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    JOONGSUNGS&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    JONGSUNGS&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ALPHABETS&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    NUMBERS&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    SPECIALS
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
VOCAB_DICT &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;_&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;~&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; idx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; v &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ALL_VOCABS&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    VOCAB_DICT&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;v&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; idx &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;그리고 이렇게 정의한 &lt;code class=&quot;language-text&quot;&gt;VOCAB_DICT&lt;/code&gt;를 이용해서 아래와 같이 &lt;code class=&quot;language-text&quot;&gt;tokenize&lt;/code&gt; 함수를 구현할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;tokenize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; encoding&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    tokens &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; t &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; encoding&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            tokens&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;VOCAB_DICT&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            tokens&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; encoding&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        tokens&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;VOCAB_DICT&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;~&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        tokens&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;~&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; tokens&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;p&gt;전체 구현은 아래와 같습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;text/__init__.py&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; re
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; unicodedata

CHOSUNGS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; _ &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x1100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x1113&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
JOONGSUNGS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; _ &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x1161&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x1176&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
JONGSUNGS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; _ &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0x11A8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x11C3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
ALPHABETS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;&lt;/span&gt;
NUMBERS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0123456789&quot;&lt;/span&gt;
SPECIALS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; ?!&quot;&lt;/span&gt;

ALL_VOCABS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    CHOSUNGS&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    JOONGSUNGS&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    JONGSUNGS&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ALPHABETS&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    NUMBERS&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    SPECIALS
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
VOCAB_DICT &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;_&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;~&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; idx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; v &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ALL_VOCABS&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    VOCAB_DICT&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;v&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; idx &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;


&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normalize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; unicodedata&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;normalize&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;NFKD&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;upper&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;replace&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;%&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; unicodedata&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;normalize&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;NFKD&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;퍼센트&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    regex &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; unicodedata&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;normalize&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;NFKD&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;r&quot;[^ \u11A8-\u11FF\u1100-\u115E\u1161-\u11A70-9A-Z?!]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; re&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sub&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;regex&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; re&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sub&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; +&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; text


&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;tokenize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; encoding&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    tokens &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; t &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; encoding&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            tokens&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;VOCAB_DICT&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            tokens&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; encoding&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        tokens&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;VOCAB_DICT&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;~&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        tokens&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;~&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; tokens


&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;text_to_sequence&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; normalize&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    tokens &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; tokenize&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; encoding&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; tokens&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이렇게 새로 구현한 함수들을 사용하기 위해서는 &lt;code class=&quot;language-text&quot;&gt;hparams.py&lt;/code&gt;와 &lt;code class=&quot;language-text&quot;&gt;data_utils.py&lt;/code&gt;를 몇 군데 수정해주어야 하는데,
필요한 수정을 다 적용한 코드는 &lt;a href=&quot;https://github.com/sooftware/nvidia-tacotron2&quot;&gt;https://github.com/sooftware/nvidia-tacotron2&lt;/a&gt; 을 사용하시면 됩니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Docker란?]]></title><description><![CDATA[Docker 란? 도커는 컨테이너 기반의 오픈소스 가상화 플랫폼입니다. 배가 물건을 컨테이너에 넣어 운반하는 것처럼, 도커도 여러 가지 원하는 프로그램들을 컨테이너에 넣어 배포할 수 있다는 점이 비슷합니다. Docker 주요 개념…]]></description><link>https://sooftware.github.io/docker/</link><guid isPermaLink="false">https://sooftware.github.io/docker/</guid><pubDate>Sat, 09 Oct 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Docker 란?&lt;/h1&gt;
&lt;p&gt;도커는 컨테이너 기반의 오픈소스 가상화 플랫폼입니다. 배가 물건을 컨테이너에 넣어 운반하는 것처럼, 도커도 여러 가지 원하는 프로그램들을 컨테이너에 넣어 배포할 수 있다는 점이 비슷합니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/136175057-671761a9-710d-4c86-a001-02fa7b6ad754.png&quot; width=&quot;600&quot;&gt; 
&lt;h1&gt;Docker 주요 개념&lt;/h1&gt;
&lt;h2&gt;1. 이미지(Image)&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/136189202-23a30f1d-0668-4f13-ba36-02a88c22413e.PNG&quot; alt=&quot;1&quot;&gt;
사진은 &lt;a href=&quot;https://hub.docker.com/&quot;&gt;Docker hub&lt;/a&gt;에서 가져온 사진입니다.&lt;br&gt;
위의 사진에 있는 것처럼 각각 하나의 프로그램을 &lt;strong&gt;이미지&lt;/strong&gt;라고 부릅니다.&lt;/p&gt;
&lt;p&gt;이미지는 컨테이너 실행에 필요한 파일과 설정 값 등을 포함하고 있고 변하지 않습니다. 즉, 같은 이미지로 여러 개의 컨테이너를 생성할 수 있고, 컨테이너의 상태가 바뀌거나 컨테이너가 삭제되더라도 이미지는 변하지 않고 그대로 존재합니다.&lt;br&gt;
예를 들어, ubuntu 이미지는 ubuntu를 실행하기 위한 모든 파일을 가지고 있고, MySQL 이미지는 debian을 기반으로 MySQL을 실행하는데 필요한 파일과 실행 명령어, 포트 정보 등을 가지고 있습니다.&lt;/p&gt;
&lt;p&gt;이러한 Docker 이미지는 &lt;a href=&quot;https://hub.docker.com/&quot;&gt;Docker hub&lt;/a&gt;에 등록하거나 Docker Registry 저장소를 직접 만들어서 관리할 수 있습니다. 현재 공개된 도커 이미지는 50만개가 넘고, Docker hub의 이미지 다운로드 수는 80억회에 이른다고 합니다.&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;❓ &lt;strong&gt;Docker hub 와  Docker Registry 차이점&lt;/strong&gt;&lt;br&gt;
Docker Hub에서는 이미지를 저장하고 관리해줍니다. 그래서 많은 회사들이 Docker로 소프트웨어를 배포하고, 공개된 이미지들을 공유할 수 있습니다.&lt;br&gt;
GitHub와 동일하게 Docker Hub를 통해 이미지를 pull하여 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;Docker Registry는 공개된 방식이 아닌 비공개적으로 격리된 사설 저장소입니다.
Docker Registry 관련하여 더 자세한 내용은 &lt;a href=&quot;https://www.redhat.com/ko/topics/cloud-native-apps/what-is-a-container-registry&quot;&gt;여기&lt;/a&gt;를 참고해주세요.&lt;/p&gt;
&lt;br&gt;
&lt;h2&gt;2. 컨테이너(Container)&lt;/h2&gt;
&lt;p&gt;도커의 이미지가 실행된 상태입니다. OS를 가상화하는 것이 아니라 프로세스가 격리된 공간에서 동작하는 기술입니다.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Virtual Machine&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/136199998-b7459daf-4878-4362-9208-1411b6af2e1e.PNG&quot; alt=&quot;2&quot;&gt;&lt;br&gt;
호스트 OS위에 게스트 OS를 가상화하여 사용하는 방식입니다.&lt;br&gt;
이 방식은 여러가지 OS를 가상화 할 수 있고 비교적 사용법이 간단하지만 무겁고 느리다는 단점이 있습니다. 왜냐하면 Virtual Machine이 OS를 자체적으로 가지고 있어야해서 용량이 커지기 때문입니다.&lt;br&gt;
사진에 있는 Hypervisor는 VMware Workstation, Oracle VirtualBox 같은 것들 입니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;&lt;strong&gt;컨테이너(Container)&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/136199993-874fd26a-6b60-45b4-b71d-a486ec473302.PNG&quot; alt=&quot;3&quot;&gt;&lt;br&gt;
OS레벨은 공유하고, 프로세스를 격리 하는 방식입니다.&lt;br&gt;
즉, 어플리케이션 레벨에서는 각각의 어플리케이션을 격리해서 실행 할 수 있습니다. 그래서 하나의 서버에 여러개의 컨테이너를 실행하면 서로 영향을 미치지 않고 독립적으로 실행할 수 있고, CPU나 메모리는 프로세스가 필요한 만큼만 추가로 사용하기 때문에 성능적으로도&lt;br&gt;
거의 손실이 없습니다.&lt;br&gt;
참고로 리눅스에서는 이 방식을 리눅스 컨테이너(LXC)라고 하고 더 자세한 내용은 &lt;a href=&quot;https://linuxcontainers.org/&quot;&gt;여기&lt;/a&gt;를 참고해주세요.&lt;/p&gt;
&lt;br&gt;
&lt;h1&gt;Docker 설치&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://goddaehee.tistory.com/251&quot;&gt;Window10&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kplog.tistory.com/288&quot;&gt;Mac&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://khj93.tistory.com/entry/Docker-Docker-%EC%84%A4%EC%B9%98%EB%B6%80%ED%84%B0-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%8B%A4%ED%96%89%EA%B9%8C%EC%A7%80-%EA%B8%B0%EB%B3%B8-%EC%82%AC%EC%9A%A9%EB%B2%95&quot;&gt;Linux&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h1&gt;Docker 사용 방법&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/136222615-1d1c44ff-a0fe-412c-89cb-79a5a552f233.PNG&quot; alt=&quot;4&quot;&gt;&lt;/p&gt;
&lt;h3&gt;1. Image를 Docker hub에서 받아서 컨테이너 생성&lt;/h3&gt;
&lt;h4&gt;Docker Image Pull 받기&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker pull [Image Name]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;pytorch_lightning 같은 경우는 &lt;code class=&quot;language-text&quot;&gt;docker pull pytorchlightning/pytorch_lightning&lt;/code&gt; 입니다.&lt;br&gt;
Docker image는 &lt;a href=&quot;https://hub.docker.com/&quot;&gt;Docker Hub&lt;/a&gt;에서 확인할 수 있고, version 명시가 없을시 latest(최신버전)으로 pull 됩니다.&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/136233888-04cd5df2-6d50-4a01-8c26-fa78e08f714c.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;사실 run 명령어를 실행했을 때 사용할 이미지가 저장되어 있지 않다면 다운로드(pull)를 한 후, 컨테이너를 생성(create)하고 시작(start)됩니다. 그러면 언제 pull을 사용하는 것일까요?&lt;br&gt;
git과 동일하게 최신 버전으로 다시 받을 때 사용합니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;Docker Image list 확인&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker images


REPOSITORY        TAG                           IMAGE ID       CREATED        SIZE
ubuntu            16.04                         b6f507652425   5 weeks ago    135MB
pytorch/pytorch   1.7.1-cuda11.0-cudnn8-devel   7554ac65eba5   8 months ago   12.9GB&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Docker Image 삭제하기&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker rmi [IMAGE_ID]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;컨테이너 실행하기&lt;/h3&gt;
&lt;p&gt;도커를 실행하는 명령어는 다음과 같습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker run [OPTIONS] [IMAGE] [COMMAND] [ARGS]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;&lt;strong&gt;자주 사용하는 옵션들&lt;/strong&gt;&lt;br&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/136239050-c82f7b42-8199-4a95-80c5-1a7657b4ab12.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;br&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker run ubuntu:16.04
 
Unable to find image &apos;ubuntu:16.04&apos; locally
16.04: Pulling from library/ubuntu
58690f9b18fc: Pull complete
b51569e7c507: Pull complete
da8ef40b9eca: Pull complete
fb15d46c38dc: Pull complete
Digest: sha256:454054f5bbd571b088db25b662099c6c7b3f0cb78536a2077d54adc48f00cd68
Status: Downloaded newer image for ubuntu:16.04&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이렇게 컨테이너를 생성하고 ubuntu:16.04 이미지가 없으면 자동적으로 다운로드(pull)를 하고 컨테이너를 생성합니다. 하지만 컨테이너에 명령어를 전달하지 않았기 때문에 컨테이너는 생성되자마자 종료됩니다.&lt;br&gt;
왜냐하면 컨테이너는 프로세스이기 때문에, 실행중인 프로세스가 없으면 컨테이너는 종료됩니다.&lt;/p&gt;
&lt;br&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker run --rm -it ubuntu:16.04 /bin/bash&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이번에는 컨테이너 내부에 들어가기 위해 bash 쉘을 실행하고 키보드 입력을 위해 -it 옵션을 주고, 프로세스가 종료되면 컨테이너가 자동으로 삭제되도록 —rm 옵션도 추가해서 실행하였습니다.&lt;br&gt;
다운로드가 되어있기 때문에 이미지를 다운로드 하는 화면 없이 바로 실행이 되고, exit로 bash 쉘을 종료하면 컨테이너도 같이 종료됩니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;컨테이너 목록 확인하기&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker ps       # 실행중인 컨테이너 목록

CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS         PORTS     NAMES
c818c8466c46   ubuntu:16.04   &quot;/bin/bash&quot;   35 seconds ago   Up 4 seconds             kind_rosalind

&amp;lt;br&gt;

$ docker ps -a    # 실행중인 컨테이너와 종료된 컨테이너 목록

CONTAINER ID   IMAGE                                         COMMAND       CREATED          STATUS                       PORTS     NAMES
c818c8466c46   ubuntu:16.04                                  &quot;/bin/bash&quot;   42 seconds ago   Up 11 seconds                          kind_rosalind
33db0c9e3d20   pytorch/pytorch:1.7.1-cuda11.0-cudnn8-devel   &quot;/bin/bash&quot;   18 minutes ago   Exited (130) 4 minutes ago             patrick&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;컨테이너 중지하기&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker stop [CONTAINER_ID]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;컨테이너 제거하기&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker rm [CONTAINER_ID]
$ docker rm -v $(docker ps -a -q -f status=exited)  # 중지된 컨테이너 한번에 삭제&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;컨테이너 명령어 실행하기&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker exec [OPTIONS] [CONTAINER_ID] [COMMAND] [ARGS]
$ docker exec -it [CONTAINER_ID] /bin/bash &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;run은 컨테이너를 새로 만들어서 실행하고, exec는 실행중인 컨테이너에 명령어를 내린다는 차이점이 있습니다.
그래서 run일 때 [IMAGE] 였던 것이 [CONTAINER_ID]로 바꼈습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h2&gt;Docker Compose&lt;/h2&gt;
&lt;p&gt;지금까지는 도커를 커맨드라인에서 명령어로만 작업을 하였습니다. 지금은 간단한 작업이였지만, 여러 가지 설정이 추가되면 명령어가 금방 복잡해질 것 입니다.&lt;br&gt;
도커는 복잡한 설정을 쉽게 관리하기 위해 YAML방식의 설정파일을 이용한 &lt;a href=&quot;https://docs.docker.com/compose/&quot;&gt;Docker Compose&lt;/a&gt;라는 툴을 제공합니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;설치&lt;/h3&gt;
&lt;p&gt;Mac에서 Docker for Mac, Window에서 Docker for Windows를 설치했다면 자동으로 설치가 되고 리눅스의 경우에는 다음 명령어를 입력하여 설치하면 됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ curl -L &quot;https://github.com/docker/compose/releases/download/1.9.0/docker-compose-$(uname -s)-$(uname -m)&quot; -o /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose

$ docker-compose version  

docker-compose version 1.9.0, build 2585387
docker-py version: 1.10.6
CPython version: 2.7.9
OpenSSL version: OpenSSL 1.0.1t  3 May 2016&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;사용 방법&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ vi docker-compose.yaml

version: &apos;3.5&apos;  # YAML 파일 포맷 버전
services:
  patrick:  # 이름
    image: &apos;pytorch/pytorch:1.7.1-cuda11.0-cudnn8-devel&apos;
    shm_size: &apos;2gb&apos;
    command: &apos;nvidia-smi&apos;   # 컨테이너가 실행될 때 수행할 명령어, docker run에 있는 command와 동일
    runtime: nvidia
    volumes:
      - /home/patrick/:/home
    environment:
      - NVIDIA_VISIBLE_DEVICES=all&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;docker-compose up&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;정리&lt;/h3&gt;
&lt;p&gt;Huggingface transformers에서 모델을 쉽게 다운받아 사용할 수 있는 것처럼, docker도 hub에서 image를 쉽게 다운 받아 사용할 수 있습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h2&gt;2. Image를 직접 만들어서 컨테이너 생성&lt;/h2&gt;
&lt;p&gt;Dockerfile이라는 파일 자체 DSL(Domain-specific language)을 이용하여 이미지를 생성합니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;Dockerfile에 작성되는 명령 옵션&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;FROM : Docker Base Image (기반이 되는 이미지, &amp;lt;이미지 이름&gt;:&amp;lt;태그&gt; 형식으로 설정, ubuntu:18.04)
MAINTAINER : 메인테이너 정보 (작성자 정보)
RUN : Shell Script 또는 명령을 실행
CMD : 컨테이너가 시작될 때마다 실행할 명령어, Dockerfile에서 한번만 사용할 수 있습니다.
LABEL : 라벨 작성 (docker inspect 명령으로 label을 확인할 수 있습니다.)
EXPOSE : 호스트와 연결할 포트 번호를 설정한다.
ENV : 환경변수 설정
ADD : 파일 / 디렉터리 추가
COPY : 파일 복사
ENTRYPOINT : 컨테이너가 시작되었을 때 스크립트 실행
VOLUME : 볼륨 마운트
USER : 명령 실행할 사용자 권한 지정
WORKDIR : &quot;RUN&quot;, &quot;CMD&quot;, &quot;ENTRYPOINT&quot; 명령이 실행될 작업 디렉터리
ARG : Dockerfile 내부 변수
ONBUILD : 다른 이미지의 Base Image로 쓰이는 경우 실행될 명령 수행
SHELL : Default Shell 지정&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;1) Dockerfile 작성&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ vi Dockerfile
 
# 1. 우분투 설치
FROM ubuntu:18.04
# 2. 메타데이터 표시
LABEL &quot;purpose&quot;=&quot;practice&quot;
# 3. 업데이트
RUN apt-get update
# 4. 호스트에 있는 파일을 복사
COPY test.txt /var/www/html
# 5. 포트 80번 노출 지정
EXPOSE 80
# 6. 컨테이너 시작될 때마다 실행할 명령어
CMD /bin/bash&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;2) Dockerfile 빌드(이미지 생성)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker build -t mybuild:0.2 ./test_docker

Sending build context to Docker daemon  3.072kB
Step 1/6 : FROM ubuntu:18.04
 ---&gt; 5a214d77f5d7
Step 2/6 : LABEL &quot;purpose&quot;=&quot;practice&quot;
 ---&gt; Using cache
 ---&gt; 29c3986addc2
Step 3/6 : RUN apt-get update
 ---&gt; Using cache
 ---&gt; fa3808d331d9
Step 4/6 : COPY test.txt /var/www/html/
 ---&gt; f1430498cfa9
Step 5/6 : EXPOSE 80
 ---&gt; Running in 3cda5f1355bf
Removing intermediate container 3cda5f1355bf
 ---&gt; c3936aca4620
Step 6/6 : CMD /bin/bash
 ---&gt; Running in 4ac0bfe9d777
Removing intermediate container 4ac0bfe9d777
 ---&gt; c789deea53d4
Successfully built c789deea53d4
Successfully tagged mybuild:0.2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker images

REPOSITORY        TAG                           IMAGE ID       CREATED          SIZE
mybuild           0.2                           c789deea53d4   59 seconds ago   101MB
ubuntu            18.04                         5a214d77f5d7   5 days ago       63.1MB
ubuntu            16.04                         b6f507652425   5 weeks ago      135MB
pytorch/pytorch   1.7.1-cuda11.0-cudnn8-devel   7554ac65eba5   8 months ago     12.9GB&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;3) 컨테이너 실행&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker run -it --name patrick_build mybuild:0.2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker ps -a

CONTAINER ID   IMAGE                                         COMMAND                  CREATED              STATUS                            PORTS     NAMES
8cd50c3112cc   mybuild:0.2                                   &quot;/bin/sh -c /bin/bash&quot;   About a minute ago   Exited (127) About a minute ago             patrick_build
c818c8466c46   ubuntu:16.04                                  &quot;/bin/bash&quot;              52 minutes ago       Up 51 minutes                               kind_rosalind
33db0c9e3d20   pytorch/pytorch:1.7.1-cuda11.0-cudnn8-devel   &quot;/bin/bash&quot;              About an hour ago    Exited (130) 56 minutes ago                 patrick&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.docker.com/get-started/overview/&quot;&gt;https://docs.docker.com/get-started/overview/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com&quot;&gt;https://hub.docker.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linuxcontainers.org/&quot;&gt;https://linuxcontainers.org/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Page Rank란??]]></title><description><![CDATA[Page Rank 구글은 무엇을 기준으로 사이트를 보여주는 순서를 정할까요?? 구글에 특정 단어를 검색하면 다음과 같이 여러 사이트 들을 보여주는 것을 알 수 있습니다. 구글은 이런 사이트들에 점수를 부여해주는데, 여기서 부여된 점수들을 Page…]]></description><link>https://sooftware.github.io/page_rank/</link><guid isPermaLink="false">https://sooftware.github.io/page_rank/</guid><pubDate>Fri, 08 Oct 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Page Rank&lt;/h2&gt;
&lt;p&gt;구글은 무엇을 기준으로 사이트를 보여주는 순서를 정할까요??&lt;/p&gt;
&lt;p&gt;구글에 특정 단어를 검색하면 다음과 같이 여러 사이트 들을 보여주는 것을 알 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/135422554-b37c5f6f-aa73-48ff-9adf-f438e2017d80.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;구글은 이런 사이트들에 점수를 부여해주는데, 여기서 부여된 점수들을 Page Rank라고 부릅니다.&lt;/p&gt;
&lt;br&gt;
&lt;h2&gt;페이지 랭크를 부여하는 두 가지 원칙&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;다른 여러 페이지에 링크가 많을 경우&lt;/li&gt;
&lt;li&gt;영향력있는 사이트에 링크되어 있는 경우&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이 두가지 원칙을 따를 경우 점수가 높아진다!&lt;/p&gt;
&lt;br&gt; 
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/135423371-6dcdb6a6-8373-4113-b606-3c20a4a2166b.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;이 그림을 보시면 잘 이해가 되실 것 같아요.&lt;/p&gt;
&lt;p&gt;원칙1에 의해 B사이트는 다른 여러 페이지들에게 링크가 많아 높은 점수를 부여 받은 것을 볼 수 있습니다.
또한 C사이트는 B사이트 단 하나만 링크됐지만 원칙2에 의해 높은 점수를 부여 받은 것을 볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;그렇다면 이런 원칙을 따르기 위해서 어떻게 점수를 부여하는지 알아봅시다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/135425243-d2ac3b58-fdad-4bae-9087-29dc4458df93.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;예시로 4개의 각 사이트가 링크가 걸려있는 상황을 방향그래프로 나타내봤습니다.&lt;/p&gt;
&lt;p&gt;이제 누군가 한 사이트에 접속 후 링크를 따라 계속 이동한다고 가정해봅시다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/135426655-997c0101-e15f-4d3e-9e5c-b6397ce60315.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;최초 사이트1에서 이동을 한다면 링크가 하나밖에 없기 때문에 사이트2로 이동하게 되고 확률은 1이 됩니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/135426173-3de4ccdb-1d1c-40e9-b222-764ab6361a31.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;다음으로 사이트2에서 이동을 한다면 링크가 총 3개가 존재하기 때문에 각 사이트로 갈 확률이 3분의1이 되겠죠.&lt;/p&gt;
&lt;p&gt;이런 과정을 무한히 반복합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;그렇게 이런 과정을 계속 반복해서 각 사이트에 방문할 확률을 계산해보면, 놀랍게도 방문할 확률이 어떤 값에 수렴하게 됩니다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;즉 확률이 변하지 않는 순간이 오게 됩니다. 그리고 그 확률들을 바로 &lt;code class=&quot;language-text&quot;&gt;Page Rank&lt;/code&gt;라고 부릅니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;그렇다면 t번 이동 시 각 사이트에 방문할 확률을 한번 구해봅시다.&lt;/p&gt;
&lt;p&gt;먼저 처음 각 사이트에 방문할 확률을 임의로 정의해줍니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/135431438-122eede8-d624-424c-b431-3c86bb0d0871.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;그리고 1번 이동 후의 각 사이트에 방문할 확률을 정의합니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/135429147-84c33f68-b155-4297-bbaa-0e31aeb516e0.png&quot; width=&quot;500&quot;&gt;
&lt;br&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/135429323-ca929e20-e3c0-49e7-a451-0c8329da47fa.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;1번 이동 후 사이트1에 방문할 확률을 계산한 식을 살펴보면,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;사이트1에서 사이트1로 방문할 방법이 존재하지 않기 때문에 &lt;code class=&quot;language-text&quot;&gt;a x 0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;사이트2에서 사이트1로 이동할 확률은 3분의 1이기 때문에 &lt;code class=&quot;language-text&quot;&gt;b x (1/3)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;사이트3에서 사이트1로 이동할 확률은 2분의 1이기 때문에 &lt;code class=&quot;language-text&quot;&gt;c x (1/2)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;사이트4에서 사이트1로 이동할 확률은 2분의 1이므로 &lt;code class=&quot;language-text&quot;&gt;d x (1/2)&lt;/code&gt;가 됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;br&gt;
&lt;p&gt;이렇게 모두 계산하면 최종적으로 다음과 같은 행렬이 하나 만들어지게 됩니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/135430069-f00d9926-bb58-4422-918d-f1f43931a7e2.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;각 행이 동일한 변수를 사용하기 때문에 행렬곱 형태로 변환해 최종적으로 다음과 같은 식을 얻을 수 있습니다.&lt;/p&gt;
&lt;br&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/135433241-da28268d-f48d-4834-9b73-80f998cd8f28.png&quot; width=&quot;500&quot;&gt;
&lt;br&gt;
&lt;p&gt;마찬가지로 동일한 논리에 따르면 2번 이동했을 때 각 사이트에 방문할 확률은 1번 이동했을 때의 상황에만 영향을 받게됩니다.&lt;/p&gt;
&lt;p&gt;따라서 2번 이동했을 때의 행렬을 구해보면  다음과 같이 얻음을 알 수 있습니다.&lt;/p&gt;
&lt;br&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/135436391-6c6fc4dc-61f2-40d6-bb77-5201c3828831.png&quot; width=&quot;500&quot;&gt;
&lt;br&gt;
&lt;p&gt;자 이제 어느정도 반복되는 것을 알 수 있겠죠? 조금 더 직관적으로 볼 수 있도록 정의를 해봅시다.&lt;/p&gt;
&lt;br&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/135569435-074a1875-b0b7-4ebd-bf03-ef0fcee727c6.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;고정된 사이트에 이동할 확률을 전이행렬 P, 그리고 각 사이트에 t번 방문할 확률을 X(t)로 정의하면 최종적으로&lt;/p&gt;
&lt;br&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/135570317-2c124923-8304-4eab-9e6e-c5d253a31baf.png&quot; width=&quot;300&quot;&gt;
&lt;p&gt;이렇게 깔끔하게 정리가 됩니다.&lt;/p&gt;
&lt;p&gt;이 식을 이용해서 수렴된 각 사이트의 확률을 구하고 Page Rank값을 정의하는 것입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;검증&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;import numpy as np

P = np.array(
    [[0, 1 / 3, 1 / 2, 1 / 2],
     [1, 0, 0, 0],
     [0, 1 / 3, 0, 1 / 2],
     [0, 1 / 3, 1 / 2, 0]]
)

X = np.array([0.3, 0.2, 0.3, 0.2])

for idx, _ in enumerate(range(30)):
    X = P.dot(X)
    print(&quot;----&quot;, idx, &quot;----&quot;)
    print(X)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;마지막 식을 numpy라이브러리를 이용해 구현해봤습니다. 해당 코드를 실행하면&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;---- 15 ----
...
...
...
[0.29999997 0.30000007 0.20000074 0.19999922]
---- 16 ----
[0.3        0.29999997 0.19999963 0.20000039]
---- 17 ----
[0.3        0.3        0.20000019 0.19999981]
---- 18 ----
[0.3        0.3        0.1999999  0.20000009]
---- 19 ----
[0.3        0.3        0.20000005 0.19999995]
---- 20 ----
[0.3        0.3        0.19999998 0.20000002]
---- 21 ----
[0.3        0.3        0.20000001 0.19999999]
---- 22 ----
[0.3        0.3        0.19999999 0.20000001]
---- 23 ----
[0.3 0.3 0.2 0.2]
---- 24 ----
[0.3 0.3 0.2 0.2]
---- 25 ----
[0.3 0.3 0.2 0.2]
...
...
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이런 결과값을 얻을 수 있는데, 23번째 연산부터 값이 수렴하는 것을 알 수 있습니다.&lt;/p&gt;
&lt;h2&gt;reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=PGeBhnHxg0E&quot;&gt;https://www.youtube.com/watch?v=PGeBhnHxg0E&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.secmem.org/blog/2019/07/21/pagerank/&quot;&gt;http://www.secmem.org/blog/2019/07/21/pagerank/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sooftware ML - BentoML]]></title><description><![CDATA[BentoML Machine Learning Serving 라이브러리인 BentoML 사용방법에 대해 정리합니다. image 주요 특징 Online / Offline Serving Flask 기반 모델보다 100배의 처리량을 가지고, Adaptive…]]></description><link>https://sooftware.github.io/bentoml/</link><guid isPermaLink="false">https://sooftware.github.io/bentoml/</guid><pubDate>Tue, 28 Sep 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;BentoML&lt;/h1&gt;
&lt;p&gt;Machine Learning Serving 라이브러리인 BentoML 사용방법에 대해 정리합니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/134802579-71c3c3d6-bb96-431a-80fd-ab13595c80d4.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;h2&gt;주요 특징&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Online / Offline Serving&lt;/li&gt;
&lt;li&gt;Flask 기반 모델보다 100배의 처리량을 가지고, Adaptive Micro Batching 메커니즘을 활용&lt;/li&gt;
&lt;li&gt;모델 관리를 위한 웹 대시보드 존재&lt;/li&gt;
&lt;li&gt;정말 많은 ML 프레임워크를 지원함(transformers, pytorch-lightning도 지원)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;❓ &lt;strong&gt;Online Serving 이란?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Online Serving은 API 서빙, 실시간 요청에 따른 반응을 합니다.&lt;/li&gt;
&lt;li&gt;Batch 처리가 불가능하고, 동시 여러 요청에 대한 확장 대책이 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;❓ &lt;strong&gt;Offline Serving 이란?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;특정 주기로 서빙 하는 것을 말한다.&lt;/li&gt;
&lt;li&gt;Batch로 많은 양을 한꺼번에 처리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;❓ &lt;strong&gt;Adaptive Micro Batching 이란?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;모델 서빙시 개별 추론 요청을 조절할 수 있는 작은 배치 단위로 처리하는 것.&lt;/li&gt;
&lt;li&gt;BentoML은 HTTP 처리 데이터 처리과정까지 Micro batching 지원을 한다.&lt;/li&gt;
&lt;li&gt;최대 배치 사이즈와 인퍼런스의 latency 제한을 설정할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/134803241-893745bf-191b-47ec-9faa-a54c87c71ab7.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;그림과 같이 request가 들어올 때 request을 하나씩 처리하는 것이 아니라 여러 개를 한번에 처리하여 응답하고 있는 것을 확인할 수 있다.&lt;br&gt;
이는 지정한 latency를 넘지 않는 선에서 request들을 합해서 배치 처리한다.&lt;br&gt;
이후 API로 오는 request는 다음 micro Batch로 받아서 배치간은 비동기식 처리를 진행한다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;bentoml.api(mb_max_batch_size=1000, mb_max_latency=10000)&lt;/code&gt; 함수를 사용해서 최대 배치 사이즈와 인퍼런스의 latency 제한을 설정할 수 있다.&lt;br&gt;
위의 값은 디폴트 값이고 latency 단위는 milliseconds이다.&lt;/p&gt;
&lt;h2&gt;설치&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;pip install bentoml&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;사용 방법&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;모델 학습&lt;/li&gt;
&lt;li&gt;Prediction Service Class 생성&lt;/li&gt;
&lt;li&gt;Prediction Service에 학습한 모델 저장&lt;/li&gt;
&lt;li&gt;Serving&lt;/li&gt;
&lt;li&gt;Prediction Request&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;1. 모델 학습&lt;/h3&gt;
&lt;p&gt;예시는 transformers 프레임워크를 통해 gpt2 모델을 사용합니다.
코드를 main.py로 저장&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; transformers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; AutoModelWithLMHead&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; AutoTokenizer

model_name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gpt2&quot;&lt;/span&gt;
model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AutoModelWithLMHead&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gpt2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
tokenizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AutoTokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gpt2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;2. Prediction Service Class 생성&lt;/h3&gt;
&lt;p&gt;코드를 gpt.py로 저장&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; bentoml
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; bentoml&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;adapters &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; JsonInput
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; bentoml&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;frameworks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;transformers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; TransformersModelArtifact


&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@bentoml&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pip_packages&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;transformers==3.1.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;torch==1.6.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@bentoml&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;artifacts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;TransformersModelArtifact&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gptModel&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TransformerService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bentoml&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;BentoService&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@bentoml&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;api&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;JsonInput&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; batch&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;predict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; parsed_json&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        src_text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; parsed_json&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;artifacts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gptModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;model&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        tokenizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;artifacts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gptModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;tokenizer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        input_ids &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;src_text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; return_tensors&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;pt&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        output &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;generate&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;input_ids&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; max_length&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        output &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;decode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;output&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; skip_special_tokens&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; output&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;BentoService Class를 상속하여 Prediction Service Class를 생성함.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;@api&lt;/code&gt; 데코레이터를 통해 API의 input, output, batch 유무 등을 설정할 수 있음.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;@artifacts&lt;/code&gt; 데코레이터에서는 BentoML에서 미리 만든 Artifact를 사용함. &lt;code class=&quot;language-text&quot;&gt;transformers&lt;/code&gt; 프레임워크는 &lt;code class=&quot;language-text&quot;&gt;TransformersModelArtifact&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Scikit-Learn&lt;/code&gt; 프레임워크는 &lt;code class=&quot;language-text&quot;&gt;SklearnModelArtifact&lt;/code&gt;처럼 프레임워크마다 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;TransformersModelArtifact(&quot;gptModel&quot;)&lt;/code&gt; 여기서 ‘gptModel’은 Prediction Service Class에서 부를 이름, 3번 main.py에서도 “gptModel”로 pack하는 것을 볼 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;@env&lt;/code&gt; 데코레이터를 통해 환경설정을 한다. &lt;code class=&quot;language-text&quot;&gt;env(pip_packages=[&quot;transformers==3.1.0&quot;, &quot;torch==1.6.0&quot;])&lt;/code&gt;로 패키지 버전을 명시해줄 수도 있고, &lt;code class=&quot;language-text&quot;&gt;@env(infer_pip_packages=True)&lt;/code&gt;로 요구되는 pip dependencies와 버전을 자동적으로 찾게 할 수도 있다. 이를 통해 requirements.txt를 생성해준다. 이외에도 conda/Docker를 활용 할 수도 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. Prediction Service에 학습한 모델 저장&lt;/h3&gt;
&lt;p&gt;1번에 main.py에 코드 추가.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; transformers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; AutoModelWithLMHead&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; AutoTokenizer
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; gpt &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; TransformerService


model_name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gpt2&quot;&lt;/span&gt;
model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AutoModelWithLMHead&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gpt2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
tokenizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AutoTokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gpt2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

service &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; TransformerService&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

artifact &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;model&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;tokenizer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; tokenizer&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
service&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pack&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gptModel&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; artifact&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

saved_path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; service&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;save&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;main.py 스크립트 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;python main.py&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;실행하면 다음과 같은 메세지가 출력됨&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[2021-09-26 17:45:55,819] INFO - BentoService bundle &apos;TransformerService:20210926174550_16DCF9&apos; saved to: C:\Users\sangchun\bentoml\repository\TransformerService\20210926174550_16DCF9&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;bentoml 폴더에 가면 logs, repository 폴더가 생성된다.&lt;br&gt;
repository로 가면 Prediction Service Class 이름인 TransformerService로 폴더가 있고 안에 Dockerfile, requirements.txt 등이 저장되어있다.&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/134807019-3104f46d-100f-40ea-9342-5cc50c3c4d6f.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;h2&gt;4. Serving&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;bentoml serve TransformerService:latest&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/134807518-c774b014-567f-4288-a782-fd3fc41677f9.png&quot; alt=&quot;image&quot;&gt;&lt;br&gt;
localhost:5000으로 접근하면 Swagger UI를 확인할 수 있음.&lt;/p&gt;
&lt;h2&gt;5. Prediction Request&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;curl command 사용&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;curl -i \
  --header &quot;Content-Type: application/json&quot; \
  --request POST \
  --data &apos;{&quot;text&quot;: &quot;my name is&quot;}&apos; \
  http://localhost:5000/predict&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;python requests 라이브러리 사용&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; requests
response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http://127.0.0.1:5000/predict&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; json&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;my name is&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/134807328-274b1f43-e9b5-499e-9f76-ea01293ba233.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;browser에서 직접 Prediction&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/134808135-97bdcb96-f315-45a0-9f84-ff14441b71a5.png&quot; alt=&quot;image&quot;&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/134808208-ba93182c-b377-4317-a824-db858aad017e.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;h2&gt;Yatai 서버&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;BentoML&lt;/strong&gt;에서는 model serving api만 제공하는 것이 아니라 BentoML에서 실행되는 각종 모델들을 관리해주는 &lt;strong&gt;Yatai&lt;/strong&gt; 서비스도 지원한다.&lt;/p&gt;
&lt;p&gt;Yatai는 Model Management Component로 Repository에 저장된 모델, 배포된 모델을 보여준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;bentoml yatai-service-start&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Docker로 실행하려면&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;docker run \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v ~/bentoml:/bentoml \
  -p 3000:3000 \
  -p 50051:50051 \
  bentoml/yatai-service:latest&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;localhost:3000에 접근하면 저장된 모델을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/134808309-a2caa51b-0912-4097-b175-1c51fce11391.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;Detail을 클릭하면 세부 내용이 나온다.&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/134807943-c0208f0f-3e45-40f2-9b5c-95cc41611d8a.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;이렇게 Yatai를 이용하면 모델을 web UI로 쉽게 관리할 수 있다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Uniform Length Batching in PyTorch]]></title><description><![CDATA[Uniform Length Batching in PyTorch 전체 토큰 길이가 비슷한 인풋끼리 배치를 이루어주는 방식 그냥 랜덤하게 배치를 묶어주면 길이가 한 데이터를 제외하고는 평균 길이가 10인데 한 데이터 길이가 10…]]></description><link>https://sooftware.github.io/uniform_length_batching/</link><guid isPermaLink="false">https://sooftware.github.io/uniform_length_batching/</guid><pubDate>Tue, 28 Sep 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Uniform Length Batching in PyTorch&lt;/h1&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/130908773-73f38a84-041c-4c13-b102-3dba09493785.png&quot; width=&quot;600&quot;&gt;  
&lt;ul&gt;
&lt;li&gt;전체 토큰 길이가 비슷한 인풋끼리 배치를 이루어주는 방식&lt;/li&gt;
&lt;li&gt;그냥 랜덤하게 배치를 묶어주면 길이가 한 데이터를 제외하고는 평균 길이가 10인데 한 데이터 길이가 100인 경우 나머지 데이터들도 모두 100까지 패딩을 채워줘야하는 비효율이 발생함&lt;/li&gt;
&lt;li&gt;실제로 랜덤하게 배치를 묶어버리면 예시보다도 더 큰 비효율이 발생하는 경우가 많음&lt;/li&gt;
&lt;li&gt;학습 속도 개선 및 장비 활용도 측면에서 길이가 비슷한 인풋끼리 배치를 묶어주게 되면 많이 개선됨&lt;/li&gt;
&lt;li&gt;유일한 단점은 배치는 최대한 비빔밥처럼 골고루 섞여야 좋다고 하는데, 길이가 비슷한 놈들끼리 묶인다는 바이어스를 주게되므로 성능에 영향을 미칠수도 있다는 의견도 꽤 있으나 학습 속도 및 장비 활용도 측면에서 상당한 이득을 주기 때문에 많이 사용되는 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;PyTorch Dataset Class&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ExampleDataset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;utils&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Dataset&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; datas&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ExampleDataset&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__init__&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;inputs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; datas&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;inputs&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;labels &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; datas&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;labels&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__len__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;inputs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__getitem__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; idx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;inputs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;labels&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;PyTorch Dataset 클래스는 input, label 페어를 &lt;code class=&quot;language-text&quot;&gt;__getitem__()&lt;/code&gt; 메서드로 리턴해주는 역할을 수행&lt;/li&gt;
&lt;li&gt;여기서 &lt;code class=&quot;language-text&quot;&gt;__getitem__()&lt;/code&gt;은 &lt;code class=&quot;language-text&quot;&gt;idx&lt;/code&gt;를 파라미터로 받게 되는데, 넘겨지는 인덱스에 따라 다른 데이터를 리턴해주는 방식&lt;/li&gt;
&lt;li&gt;이러한 점을 이용해서 넘겨지는 idx 순서만 셔플해주면 쉽게 데이터를 셔플해서 가져올 수 있음 (이러한 역할을 해주는 놈이 &lt;code class=&quot;language-text&quot;&gt;Sampler&lt;/code&gt; 클래스)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 이렇게 0부터 차례차례 순서로 idx를 건네줄수도 있지만&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 단순하게 idx 순서만 셔플함으로써 데이터를 가져오는 순서를 쉽게 셔플할 수 있음&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Bucketing Sampler&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/135025302-e762a16b-4eb9-40b9-8908-da502df014db.png&quot; width=&quot;500&quot;&gt;
&lt;ul&gt;
&lt;li&gt;데이터를 완전 무작위하게 셔플하는게 아니라, 어떤 기준으로 버킷에 담아두고 셔플시, 이 버킷을 셔플하는 방식의 Sampler&lt;/li&gt;
&lt;li&gt;이렇게 하게 되면 묶이는 배치는 유지하면서도 모델 학습에 들어가는 순서는 셔플이 되므로 어떤 기준으로 배치를 묶는 경우 많이 사용되는 방식&lt;/li&gt;
&lt;li&gt;구현은 아래처럼 간단하게 가능
&lt;ul&gt;
&lt;li&gt;self.bins를 2차원 list로 만들어서 안에 담긴 list들이 버킷 역할을 함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BucketingSampler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Sampler&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data_source&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;utils&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Dataset&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; batch_size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;BucketingSampler&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__init__&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data_source&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data_source &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; data_source
        ids &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data_source&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bins &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ids&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; batch_size&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ids&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; batch_size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__iter__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; ids &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bins&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;yield&lt;/span&gt; ids

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__len__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bins&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; epoch&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        np&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shuffle&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bins&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Uniform Length Batching Sampler&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Uniform Length Batching은 위의 Bucketing Sampler에서 토큰 길이를 기준으로 sorting 로직만 추가해주면 됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UniformLengthBatchingSampler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Sampler&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data_source&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;utils&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Dataset&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; batch_size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;UniformLengthBatchingSampler&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__init__&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data_source&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data_source &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; data_source
        &lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# 여기에 토큰 길이 기준으로 sorting하는 로직만 추가해주면 끝&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
        ids &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data_source&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bins &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ids&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; batch_size&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ids&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; batch_size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__iter__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; ids &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bins&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;yield&lt;/span&gt; ids

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__len__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bins&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; epoch&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        np&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shuffle&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bins&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;collate_fn&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PyTorch에서 배치로 묶인 인풋을 처리하는 로직이 담긴 함수&lt;/li&gt;
&lt;li&gt;보통 여기서 길이가 다른 인풋들에 대하여 padding을 추가하고 텐서형으로 변환하는 코드가 수행됨.&lt;/li&gt;
&lt;li&gt;Uniform Length Batching을 수행하기 위해서는 &lt;code class=&quot;language-text&quot;&gt;Sampler&lt;/code&gt;에서 묶일 때까지 패딩을 추가하면 안 되기 때문에 &lt;code class=&quot;language-text&quot;&gt;collate_fn&lt;/code&gt;을 정의해주어야함.&lt;/li&gt;
&lt;li&gt;구현 예시&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;collate_fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;batch&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;seq_length_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    max_seq_sample &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;batch&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;seq_length_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    max_seq_size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;max_seq_sample&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    batch_size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;batch&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    input_ids &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;batch_size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; max_seq_size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fill_&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    attention_masks &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;batch_size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; max_seq_size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fill_&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    labels &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;batch_size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; max_seq_size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fill_&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; idx &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;batch_size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        sample &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; batch&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        sample_input_ids &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sample&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        sample_attention_masks &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sample&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        sample_labels &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sample&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

        input_ids&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;narrow&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sample_input_ids&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;copy_&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;LongTensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sample_input_ids&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        attention_masks&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;narrow&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sample_attention_masks&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;copy_&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;LongTensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sample_attention_masks&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        labels&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;narrow&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sample_labels&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;copy_&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;LongTensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sample_labels&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;input_ids&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; input_ids&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;attention_mask&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; attention_masks&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;labels&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; labels&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;How to apply?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;이렇게 정의한 &lt;code class=&quot;language-text&quot;&gt;Sampler&lt;/code&gt;와 &lt;code class=&quot;language-text&quot;&gt;collate_fn&lt;/code&gt;은 &lt;code class=&quot;language-text&quot;&gt;DataLoader&lt;/code&gt; 클래스 생성시 넘겨주면 적용이 됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;trainset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ExampleDataset&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;train_datas&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
sampler &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; UniformLengthBatchingSampler&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;trainset&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; batch_size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

train_loader &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; DataLoader&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    dataset&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;trainset&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    sampler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;sampler&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    shuffle&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    collate_fn&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;collate_fn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[React 기반 개인 웹페이지 배포하기 (gatsby)]]></title><description><![CDATA[React 기반 개인 웹페이지 배포하기 이번 글에서는 react…]]></description><link>https://sooftware.github.io/react_homepage/</link><guid isPermaLink="false">https://sooftware.github.io/react_homepage/</guid><pubDate>Wed, 22 Sep 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;React 기반 개인 웹페이지 배포하기&lt;/h2&gt;
&lt;p&gt;이번 글에서는 react를 이용해서 개인 웹페이지 제작부터 웹페이지 배포, 그리고 자신이 원하는 도메인 이름으로 적용까지를 다뤄보겠습니다.&lt;br&gt;
지금 보시는 &lt;code class=&quot;language-text&quot;&gt;sooftware.io&lt;/code&gt;와 같은 홈페이지를 제작하는 방법이라고 생각하시면 될 것 같습니다.&lt;/p&gt;
&lt;h2&gt;React 기반 오픈소스 찾기&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134343629-3e301e42-50de-43e5-ba18-ab13582e931c.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;리액트는 자바스크립트 라이브러리의 하나로서 간단히 말하면 react 기반으로 웹페이지를 만들면
스마트폰 어플리케이션에서도 보기 좋게 나오게 해주는 좋은 라이브러리라고 보시면 됩니다.&lt;/p&gt;
&lt;p&gt;코드를 하나만 짜면 웹, 앱이 한 번에 해결되기 때문에 최근에는 많은 분들이 react 기반으로 웹페이지를 제작하는 경우가 많은 것 같습니다.&lt;/p&gt;
&lt;p&gt;react를 잘 다루시는 개발자라면 개인 웹페이지 만드는것쯤은 뚝-딱 만드시겠지만, 꼭 웹개발자 분들만 개인 웹페이지를 만들고 싶으신 건 아니기 때문에,
react를 하나도 모르더라도 지금 보시는 페이지와 같은 개인 웹페이지를 만드는 방법에 대해 알아볼까 합니다.&lt;/p&gt;
&lt;p&gt;다행히도 깃허브에 &lt;code class=&quot;language-text&quot;&gt;react-blog&lt;/code&gt; 정도의 키워드만 검색하더라도 상당히 많은 코드를 볼 수 있습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134343925-24160a6a-5d85-4954-a38a-f32289376680.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;저희는 이 중 &lt;a href=&quot;https://github.com/scttcper/gatsby-casper&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;gatsby-casper&lt;/code&gt;&lt;/a&gt; 라는 오픈소스를 이용해보겠습니다.&lt;/p&gt;
&lt;p&gt;많은 블로그 테마를 찾아봤는데, 디자인이 마음에 안 들거나, 커스터마이징이 어렵거나, 이미지 삽입이 어렵다거나 하는 애로사항이 있었는데,
이 테마는 디자인, 커스터마이징, 이미지 삽입 등이 손쉽다는 장점이 있습니다.&lt;/p&gt;
&lt;p&gt;특히 몇몇 테마는 이미지 삽입시 400x400 사이즈만 지원한다던가 하는 등 기능적으로 아쉬운 부분이 많았는데, 해당 테마는 어떤 사이즈의 이미지던지
알아서 조절해주는 점 등이 편리했습니다.&lt;/p&gt;
&lt;p&gt;해당 테마는 &lt;a href=&quot;https://gatsby-casper.netlify.app/&quot;&gt;이곳&lt;/a&gt; 에서 데모 사이트를 구경하실 수 있습니다.&lt;/p&gt;
&lt;p&gt;이 외에도 개인적으로 마음에 들었던 사이트들을 아래에 정리했습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://mldangelo.com/about/&quot;&gt;https://mldangelo.com/about/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gatsby-starter-personal-blog.greglobinski.com/&quot;&gt;https://gatsby-starter-personal-blog.greglobinski.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://riyazweb.dev/&quot;&gt;https://riyazweb.dev/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ryan-floyd.com/&quot;&gt;https://www.ryan-floyd.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mehdibha.codehub.tn/&quot;&gt;https://www.mehdibha.codehub.tn/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;환경설정&lt;/h2&gt;
&lt;p&gt;해당 테마를 적용하기 위해서는 &lt;code class=&quot;language-text&quot;&gt;nodejs&lt;/code&gt;와 &lt;code class=&quot;language-text&quot;&gt;npm&lt;/code&gt; 설치가 필요합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nodejs &amp;#x26; NPM 정의&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Node.js®는 Chrome V8 JavaScript 엔진으로 빌드된 JavaScript 런타임입니다.
Node.js는 이벤트 기반, Non 블로킹 I/O 모델을 사용해 가볍고 효율적입니다. 
Node.js의 패키지 생태계인 npm은 세계에서 가장 큰 오픈 소스 라이브러리 생태계이기도 합니다.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위와 같이 정의가 되어 있긴 한데, 쉽게 말하면 &lt;code class=&quot;language-text&quot;&gt;nodejs&lt;/code&gt;는  JavaScript 기반으로 구성된 서버 사이드 서비스를 JavaScript로 구현할 수 있게 만든 런타임이고, &lt;code class=&quot;language-text&quot;&gt;npm&lt;/code&gt;은 &lt;code class=&quot;language-text&quot;&gt;nodejs&lt;/code&gt; 기반의 모듈을 모아둔 집합 저장소이다.&lt;/p&gt;
&lt;h3&gt;Nodejs &amp;#x26; NPM 설치&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;Nodejs&lt;/code&gt;와 &lt;code class=&quot;language-text&quot;&gt;npm&lt;/code&gt;은 &lt;a href=&quot;https://nodejs.org/en/&quot;&gt;여기&lt;/a&gt;서 다운로드 가능합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node js &amp;#x26; npm 설치 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ node -v
v14.17.6
$ npm -v
6.14.15&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 명령어를 실행했을 때, 정상적으로 버젼이 나오면 설치가 완료된 겁니다.&lt;/p&gt;
&lt;h3&gt;Gatsby 설치&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;Gatsby&lt;/code&gt;란 React 기반의 정적 페이지 생성 프레임워크입니다. 여기서는 지금 당장 필요한 라이브러리 중 하나 정도로 생각하고 넘어갑시다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ npm install -g gatsby-cli&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;해당 명령어 실행시 가끔 npm audit 어쩌고 하는 글이 나오면서 설치가 실패할 수가 있습니다.&lt;br&gt;
그러면 아래 명령어로 실행하면 됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ npm install -g gatsby-cli --no-audit&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Quick Start&lt;/h2&gt;
&lt;p&gt;환경설정이 완료됐으면, 이제 실제로 코드를 실행해봅시다.&lt;/p&gt;
&lt;p&gt;먼저 git을 이용해서 해당 코드를 clone 합니다. (git 설치는 스킵)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ cd $WORKING_DIRECTORY
$ git clone https://github.com/scttcper/gatsby-casper.git
$ cd gatsby-casper&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;다음은 해당 웹페이지 구성에 필요한 requirements를 설치합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ npm install --no-audit&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;설치가 완료되면 웹페이지를 실행합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ npm start&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;해당 명령어까지 문제없이 실행됐다면 &lt;a href=&quot;http://localhost:8000/&quot;&gt;http://localhost:8000/&lt;/a&gt; 로 접속하면 아래와 같은 화면을 볼 수 있습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134347816-a5bd9336-dda5-4b90-8935-2355675391a2.png&quot; width=&quot;700&quot;&gt;
&lt;h2&gt;Customizing&lt;/h2&gt;
&lt;p&gt;이제는 해당 웹페이지를 본인 스타일로 커스터마이징 해봅시다.&lt;/p&gt;
&lt;h3&gt;1. 대문 이미지 &amp;#x26; 글 수정&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134353098-994b95e9-6a61-45f8-9955-57779101cbe5.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;먼저 저 &lt;code class=&quot;language-text&quot;&gt;ghost&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;The professional publishing platform&lt;/code&gt;라고 써져 있는 부분을 커스터마이징 해봅시다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;$CASPER_GATSBY_DIR/src/website-config.ts&lt;/code&gt; 파일을 엽니다.&lt;br&gt;
아래로 내리다보면 아래 같은 코드가 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; WebsiteConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Ghost&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;The professional publishing platform&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;coverImage&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;img/blog-cover.png&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;logo&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;img/ghost-logo.png&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;en&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;siteUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://gatsby-casper.netlify.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;facebook&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://www.facebook.com/ghost&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;twitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://twitter.com/tryghost&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;showSubscribe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;mailchimpAction&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;https://twitter.us19.list-manage.com/subscribe/post?u=a89b6987ac248c81b0b7f3a0f&amp;amp;amp;id=7d777b7d75&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;mailchimpName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;b_a89b6987ac248c81b0b7f3a0f_7d777b7d75&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;mailchimpEmailFieldName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;MERGE0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;googleSiteVerification&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GoogleCode&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;footer&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;is based on Gatsby Casper&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;showAllTags&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;title&lt;/code&gt;: 웹 페이지 탭에 뜨는 텍스트&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;description&lt;/code&gt;: 대문에 나오는 description 텍스트&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;coverImage&lt;/code&gt;: 대문 배경 이미지&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;logo&lt;/code&gt;: description 위에 있는 이미지 (ghost라고 써져 있는 이미지)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;등등 위 내용을 본인이 원하는대로 수정해주시면 됩니다.&lt;/p&gt;
&lt;h3&gt;2. NavBar 수정&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134353166-00a2913d-d72a-4281-a640-bbd73818353e.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;페이지 상단에 있는 메뉴를 커스터마이징 해봅시다.&lt;br&gt;
해당 내용은 &lt;code class=&quot;language-text&quot;&gt;$CASPER_GATSBY_DIR/src/header/SiteNav.tsx&lt;/code&gt;에서 수정 가능합니다.&lt;/p&gt;
&lt;p&gt;해당 파일에서 &lt;code class=&quot;language-text&quot;&gt;nav-current&lt;/code&gt;를 검색하면 아래 코드들이 나옵니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;li role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;menuitem&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Link to&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/&quot;&lt;/span&gt; activeClassName&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;nav-current&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    Home
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Link&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;li&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;li role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;menuitem&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Link to&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/about&quot;&lt;/span&gt; activeClassName&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;nav-current&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    About
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Link&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;li&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;li role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;menuitem&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Link to&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/tags/getting-started/&quot;&lt;/span&gt; activeClassName&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;nav-current&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    Getting Started
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Link&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;li&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;딱 보면 아시겠지만, 위에 있는 Home, About, Getting Started를 눌렀을 때 어느 링크로 보낼지에 대한 내용이 있는 코드입니다.&lt;br&gt;
&lt;code class=&quot;language-text&quot;&gt;/&lt;/code&gt;는 베이스 링크 기준이므로 &lt;code class=&quot;language-text&quot;&gt;/about&lt;/code&gt;은 베이스링크 + about 링크입니다. (제 사이트에서는 sooftware.io/about/)&lt;/p&gt;
&lt;p&gt;저 링크에 &lt;a href=&quot;http://www.google.com&quot;&gt;www.google.com&lt;/a&gt; 등 어떤 링크를 넣어도 동작합니다.&lt;/p&gt;
&lt;h3&gt;3. Social Link 수정&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134353245-c9549b8e-ace0-4c34-b5e9-3ac4487401db.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;이 테마를 보면 페이스북, 트위터 favicon을 볼 수 있습니다.&lt;br&gt;
해당 favicon을 누르면 정해진 링크로 이동됩니다.&lt;br&gt;
이 링크를 깃허브, 페이스북, 링크드인으로 바꿔보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;$CASPER_GATSBY_DIR/src/website-config.ts&lt;/code&gt; 파일을 수정합시다.&lt;br&gt;
&lt;code class=&quot;language-text&quot;&gt;WebsiteConfig&lt;/code&gt; 클래에 github, linkedin을 추가하고 twitter는 날려버립시다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Before&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WebsiteConfig&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
    facebook&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/**
     * full url, no username
     */&lt;/span&gt;
    twitter&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;After&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WebsiteConfig&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
    facebook&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/**
    * full url, no username
    */&lt;/span&gt;
    github&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/**
    * full url, no username
    */&lt;/span&gt;
    linkedin&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;그리고 같은 파일 아래쪽에 &lt;code class=&quot;language-text&quot;&gt;WebsiteConfig&lt;/code&gt; 변수를 다음과 같이 수정합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; config&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; WebsiteConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
  facebook&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://www.facebook.com/sooftware95&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  github&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://www.github.com/sooftware&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  linkedin&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://www.linkedin.com/in/Soo-hwan/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;먼저 favicon을 쉽게 가져오기 위해 &lt;code class=&quot;language-text&quot;&gt;react-icons&lt;/code&gt;를 설치합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ npm install react-icons --no-audit&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;$CASPER_GATSBY_DIR/src/header/SiteNav.tsx&lt;/code&gt;의 아래 코드를 수정합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Before&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Facebook &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;../icons/facebook&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Twitter &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;../icons/twitter&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;After&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; FaFacebook&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; FaGithub&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; FaLinkedinIn &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react-icons/fa&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;그리고 밑으로 내려서 아래 코드를 다음과 같이 수정합시다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Before&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;twitter &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;a
      css&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;SocialLink&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      href&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;twitter&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      title&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Twitter&quot;&lt;/span&gt;
      target&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;_blank&quot;&lt;/span&gt;
      rel&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;noopener noreferrer&quot;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Twitter &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;a&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;After&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;github &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;a
      css&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;SocialLink&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      href&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;github&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      title&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Github&quot;&lt;/span&gt;
      target&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;_blank&quot;&lt;/span&gt;
      rel&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;noopener noreferrer&quot;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;FaGithub &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;a&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;그럼 아래같이 깃허브, 링크드인이 추가된 것을 볼 수 있습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134356415-3459fecd-5dc2-4085-9d8a-621cf23ebf91.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;이러한 favicon들은 &lt;a href=&quot;https://react-icons.github.io/react-icons/&quot;&gt;https://react-icons.github.io/react-icons/&lt;/a&gt; 가면 제공되는 icon들을 확인할 수 있습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134357055-838e95b0-f7e7-4192-ba8e-efd46fe721d3.png&quot; width=&quot;600&quot;&gt;
&lt;h3&gt;4. 포스트 수정&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134357244-b605c591-4fec-4a3d-9979-a51b03cf4291.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;다음으로 포스팅을 추가/수정 해봅시다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;$CASPER_GATSBY_DIR/src/content/&lt;/code&gt;에 가면 현재 올라와있는 포스트 관련한 마크다운 파일과 이미지 폴더가 있습니다.&lt;/p&gt;
&lt;p&gt;해당 마크다운 파일 맨 위에 아래와 같은 형식만 유지하고 아래는 기존 마크다운 문법을 유지해서 글을 작성하면 됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;---
title: &apos;2020년 회고&apos;
author: [Soohwan Kim]
tags: [retrospect]
image: img/2020.png
date: &apos;2020-12-31T10:00:00.000Z&apos;
draft: false
---&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 형식에는 포스트의 타이틀, 작성자 및 작성 날짜와 대표 이미지 등을 설정할 수 있습니다.&lt;/p&gt;
&lt;h2&gt;Github 업로드&lt;/h2&gt;
&lt;p&gt;커스터마이징까지 완료했으면 해당 파일들을 깃허브에 업로드합니다.&lt;br&gt;
꼭 깃허브에 업로드해야되는 것은 아닙니다만, 현재 글에서는 배포와 업데이트의 편리을 위해 깃허브 업로드를 추천드립니다.&lt;/p&gt;
&lt;p&gt;깃허브 업로드는 생략하겠습니다.&lt;/p&gt;
&lt;h2&gt;Deployment (배포)&lt;/h2&gt;
&lt;p&gt;커스터마이징까지 완료했으면 이제 해당 페이지를 배포해봅시다.&lt;br&gt;
자신이 가진 컴퓨터로 블로그 서버를 이용해도 되지만 일반적으로는 cpu 서버를 대여해서 배포합니다.&lt;/p&gt;
&lt;p&gt;AWS, GCP 등이 대표적입니다만, 최근에는 &lt;a href=&quot;https://app.netlify.com/&quot;&gt;Netlify&lt;/a&gt;라는 서비스를 이용하면 쉽게 웹페이지 배포가 가능합니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134358858-20d8cdba-5a8c-4577-ab01-2f86cca8fd45.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;Netlify 홈페이지에서 우측 상단에 Sign up 버튼을 눌러 회원가입을 합니다.&lt;br&gt;
이미 회원이신 분들은 Log in 버튼으로 로그인하시면 되겠습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134358989-ffc79e5a-6e70-477f-8a3e-70b179e44aa5.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;이 때 깃허브 아이디와 연동해서 가입하면 여러가지로 편리하기 때문에 깃허브 아이디가 있으시다면 깃허브와 연동하는 것을 추천합니다.&lt;/p&gt;
&lt;p&gt;가입 및 이메일 인증까지 끝내가 netlify로 들어가게 되면 아래 화면으로 접속됩니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134359237-05cae5a6-145b-48d8-bfa9-aafae9b9b367.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;저기서 우리는 New site from Git 버튼을 눌러줍니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134359972-c02b0bca-490b-451f-b5a1-da1c17ab0820.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;그러면 위와 같은 화면이 뜨게 됩니다.&lt;br&gt;
여기서 GitHub를 선택하고 레포를 선택해줍니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134360288-adfeb583-ecac-4db1-b0ec-ec7a5a35f0e4.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;그렇게 설정을 하고 다시 netlify 기본 페이지로 돌아오면 위와 같은 deploy 목록에 하나가 뜨게 됩니다.&lt;/p&gt;
&lt;p&gt;오른쪽 &lt;code class=&quot;language-text&quot;&gt;&gt;&lt;/code&gt; 버튼을 누르면 deploy 진행 상황에 대한 log를 볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;log에서 아래와 같이 &lt;code class=&quot;language-text&quot;&gt;Netlify Build Complete&lt;/code&gt;가 뜨게 되면 성공적으로 배포에 성공한겁니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134361914-d75e2f7d-dc1d-4830-987b-1ae5980f7313.png&quot; width=&quot;400&quot;&gt;  
&lt;p&gt;배포에 성공하고 deploy한 프로젝트에 들어가면 아래 화면의 &lt;code class=&quot;language-text&quot;&gt;https://sooftware.io&lt;/code&gt;가 적혀있는 쪽에 본인만의 사이트 링크가 있을겁니다.&lt;br&gt;
저는 커스텀 도메인을 적용했기 때문에 저런 링크가 뜨지만 따로 적용하지 않은 경우 &lt;code class=&quot;language-text&quot;&gt;https://[PROJECT_NAME].netlify.app&lt;/code&gt; 형식으로 웹페이지 주소가 형성됩니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134362178-74d1c716-464e-4007-a6c0-6f5cfceab1f4.png&quot; width=&quot;400&quot;&gt;
&lt;h2&gt;Custom Domain&lt;/h2&gt;
&lt;p&gt;이제 배포한 웹페이지 주소를 커스텀 도메인으로 설정해봅시다.&lt;br&gt;
도메인을 사용하기 위해서는 도메인 구입이 필요합니다.&lt;/p&gt;
&lt;p&gt;저는 hosting.kr이라는 사이트에서 도메인을 구입했습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134363042-35854d97-6d71-41f3-a290-428dcd881bb2.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;위 사이트의 &lt;code class=&quot;language-text&quot;&gt;검색할 도메인을 입력하세요&lt;/code&gt; 쪽에 원하는 도메인을 입력하면 해당 도메인 사용여부 및 가격이 나오게 됩니다.&lt;/p&gt;
&lt;p&gt;아래는 sooftware를 검색했을 때의 결과입니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134363258-4ade15f5-b221-4fb3-86bb-59637c33f3c8.png&quot; width=&quot;400&quot;&gt;  
&lt;p&gt;원하는 도메인을 구입하고 나면 다시 netlify로 돌아갑니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134363707-9f2e0b3c-ee59-4af5-a233-5cff179d98fe.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;위 페이지에서 &lt;code class=&quot;language-text&quot;&gt;Domatin setting&lt;/code&gt;을 들어갑니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134363947-7b4d54ee-4567-4b42-90aa-a4f65b389728.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;여기서 Add domain alias로 구입한 도메인 링크를 추가하고 몇 가지 인증 절차만 수행해주게 되면 sooftware.io 와 같은 커스텀 도메인이 적용이 되게됩니다.&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/scttcper/gatsby-casper&quot;&gt;https://github.com/scttcper/gatsby-casper&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Textless NLP]]></title><description><![CDATA[Textless NLP: Generating expressive speech from raw audio paper / code / pre-train model / blog Name: Generative Spoken Language Model (GSLM…]]></description><link>https://sooftware.github.io/Textledd NLP: Generating expressive speech from raw audio/</link><guid isPermaLink="false">https://sooftware.github.io/Textledd NLP: Generating expressive speech from raw audio/</guid><pubDate>Sun, 19 Sep 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Textless NLP: Generating expressive speech from raw audio&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2102.01192&quot;&gt;paper&lt;/a&gt; / &lt;a href=&quot;https://github.com/pytorch/fairseq/tree/master/examples/textless_nlp/gslm&quot;&gt;code / pre-train model&lt;/a&gt; / &lt;a href=&quot;https://ai.facebook.com/blog/textless-nlp-generating-expressive-speech-from-raw-audio&quot;&gt;blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Name: Generative Spoken Language Model (GSLM)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Intro&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;BERT, RoBERTa, GPT-3 등 최근 몇 년간 &lt;code class=&quot;language-text&quot;&gt;텍스트&lt;/code&gt;에 집중된 NLP 모델들이 발전되어 왔음.&lt;/li&gt;
&lt;li&gt;이건 분명한 한계다. 텍스트에 대한 디펜던시를 깨야한다.&lt;/li&gt;
&lt;li&gt;언어 == 문자가 아니다. speech가 있다.&lt;/li&gt;
&lt;li&gt;그래서 우리 GSLM이 텍스트에 대한 디펜던시를 깰 수 있는 가능성을 보였다.&lt;/li&gt;
&lt;li&gt;음성 프롬프트 시대의 시작을 알린다.&lt;/li&gt;
&lt;li&gt;음성을 프롬프트로 주면 뒤이어서 인공지능이 말을 계속 이어서 말하는 모델의 등장!&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;음성을 입력으로 하는 NLP 어플리케이션들은 ASR =&gt; NLP를 거쳐야 했음.&lt;/li&gt;
&lt;li&gt;ASR의 정확도가 100%가 아니기 때문에 분명한 정보의 오류가 존재함.&lt;/li&gt;
&lt;li&gt;우리는 여기서 ASR + NLP 구조가 아닌 Speech to Speech로 간다.&lt;/li&gt;
&lt;li&gt;Text나 label 없이 only 음성만으로 학습한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Textless NLP’s benefits&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;언어 상관없이 학습이 가능해질 가능성이 높아짐&lt;/li&gt;
&lt;li&gt;텍스트로 표현이 안되는 말의 뉘앙스, 감정 등의 정보를 반영할 수 있음&lt;/li&gt;
&lt;li&gt;텍스트 레이블링 혹은 ASR 학습 없이 모델을 학습할 수 있음&lt;/li&gt;
&lt;li&gt;유아들이 어떻게 언어를 배우고 말을 시작하는지를 알 수 있다(? 과연?)&lt;/li&gt;
&lt;li&gt;처음으로 텍스트 없이 audio to audio 번역 시스템이 가능해졌다!&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Data&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;6,000시간의 Libri-Light와 LibriSpeech 데이터셋 (인코더 학습)&lt;/li&gt;
&lt;li&gt;LibriSpeech and LJSpeech (디코더(TTS System) 학습)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Model&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134018698-f46507a0-c375-4f6f-a67f-63e6ca2a9240.png&quot; width=&quot;600&quot;&gt;  
&lt;ul&gt;
&lt;li&gt;Encoder (S2u)
&lt;ul&gt;
&lt;li&gt;Speech를 인풋으로 받아서 discrete unit(pseudo-text라고 부름)으로 인코딩&lt;/li&gt;
&lt;li&gt;unit은 k-means clustering으로 나눔.&lt;/li&gt;
&lt;li&gt;인코더로는 CPC, wav2vec 2.0, HuBERT를 사용 (좋은 acoustic encoder들이라고 보시면 됨)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;uLM
&lt;ul&gt;
&lt;li&gt;unit sequence를 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Decoder (u2S)
&lt;ul&gt;
&lt;li&gt;TTS System (Tacotron2 사용)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;여기서 unit(pseudo-text)은 letter or phoneme과 매핑되지는 않음.&lt;/li&gt;
&lt;li&gt;100 이상의 유닛일 때 좋은 성능을 보였으며 unit은 보통 음소보다 짧은 단위를 인코딩했음.&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://scontent-gmp1-1.xx.fbcdn.net/v/t39.2365-6/241223788_398469455180920_2630499539056655858_n.jpg?_nc_cat=107&amp;amp;ccb=1-5&amp;amp;_nc_sid=ad8a9d&amp;amp;_nc_ohc=rfiDlgtmTcYAX-EraG5&amp;amp;_nc_ht=scontent-gmp1-1.xx&amp;amp;oh=1c96a38f6af0ada3774380e4fd6110e6&amp;amp;oe=61489C23&quot; width=&quot;600&quot;&gt;
&lt;ul&gt;
&lt;li&gt;생성한 음성은 pre-trained ASR 모델로 인식해서 성능 측정&lt;/li&gt;
&lt;li&gt;Pre-trained LM으로 텍스트 성능 측정&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Result&lt;/h2&gt;
&lt;img src=&quot;https://scontent-gmp1-1.xx.fbcdn.net/v/t39.2365-6/241364732_225715579507676_6485051182702467200_n.jpg?_nc_cat=108&amp;amp;ccb=1-5&amp;amp;_nc_sid=ad8a9d&amp;amp;_nc_ohc=h45PImsz8SkAX-kM1rz&amp;amp;_nc_ht=scontent-gmp1-1.xx&amp;amp;oh=88949e5b3a057a6e42b8266d03171ac7&amp;amp;oe=61492788&quot; width=&quot;600&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Unit의 수가 모델 성능에 큰 영향을 미침.&lt;/li&gt;
&lt;li&gt;Unit 수가 커질수록 Acoustic의 성능은 좋아졌음. (PER이 낮아졌다)&lt;/li&gt;
&lt;li&gt;LM 점수도 비슷한 경향이었으나, 너무 많은 unit을 사용하면 오히려 안 좋았음. (NLP에서 vocab의 적당한 사이즈가 좋은 이유와 비슷한 것 같음)&lt;/li&gt;
&lt;li&gt;어떤 인코더 모델이냐에 따라 다른 결과가 나옴. HuBERT 성능이 가장 좋았음.&lt;/li&gt;
&lt;li&gt;이렇게 자동으로 측정한 성능이 사람이 평가했을 때와 correlation이 높았음. (좋은 성능 지표)&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[TUNiB Electra 공개]]></title><description><![CDATA[이번에 저희 튜닙에서 공들여 만든 TUNiB Electra 모델을 공개했습니다 !! 🎉 🎉 이번 공개에서는 한-영 bilingual 모델과 한국어 모델을 각각 Small/Base 사이즈로 공개했으며, HuggingFace transformers…]]></description><link>https://sooftware.github.io/tunib_electra/</link><guid isPermaLink="false">https://sooftware.github.io/tunib_electra/</guid><pubDate>Sat, 18 Sep 2021 15:11:55 GMT</pubDate><content:encoded>&lt;p&gt;이번에 저희 튜닙에서 공들여 만든 &lt;strong&gt;TUNiB Electra&lt;/strong&gt; 모델을 공개했습니다 !! 🎉 🎉&lt;/p&gt;
&lt;p&gt;이번 공개에서는 한-영 bilingual 모델과 한국어 모델을 각각 Small/Base 사이즈로 공개했으며, HuggingFace &lt;a href=&quot;https://github.com/huggingface/transformers&quot;&gt;transformers&lt;/a&gt; 라이브러리로 쉽게 이용이 가능합니다.&lt;/p&gt;
&lt;p&gt;해당 깃허브는 &lt;a href=&quot;https://github.com/tunib-ai/tunib-electra&quot;&gt;이곳&lt;/a&gt; 에서 확인하실 수 있으며, TUNiB Electra에 대한 자세한 내용은 회사 블로그에 글을 작성했습니다.&lt;br&gt;
해당 포스트는 &lt;a href=&quot;https://tunib.notion.site/TECH-2021-09-18-TUNiB-Electra-3eba9f55859d4992a085a64c600dc150&quot;&gt;이곳&lt;/a&gt; 에서 확인하실 수 있습니다.&lt;/p&gt;
&lt;p&gt;데이터 수집부터 전처리, 모델 학습 및 실험까지 공들인 끝에 TUNiB Electra를 공개할 수 있었습니다. 공들인 만큼 많은 분들께 도움이 됐으면 좋겠습니다. 많이 많이 이용해주세요 ! 🤗&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware ML - PyTorch Lightning]]></title><description><![CDATA[PyTorch Lightning 대표적인 딥러닝 프레임워크로 , 가 있습니다. 최근에는 보다 를 선호하는 유저가 많아지는 것 같습니다.
PyTorch Lightning 은 PyTorch에 대한 High-level…]]></description><link>https://sooftware.github.io/pytorch_lightning/</link><guid isPermaLink="false">https://sooftware.github.io/pytorch_lightning/</guid><pubDate>Fri, 17 Sep 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;PyTorch Lightning&lt;/h2&gt;
&lt;p&gt;대표적인 딥러닝 프레임워크로 &lt;code class=&quot;language-text&quot;&gt;pytorch&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;tensorflow&lt;/code&gt;가 있습니다. 최근에는 &lt;code class=&quot;language-text&quot;&gt;tensorflow&lt;/code&gt;보다 &lt;code class=&quot;language-text&quot;&gt;pytorch&lt;/code&gt;를 선호하는 유저가 많아지는 것 같습니다.
PyTorch Lightning 은 PyTorch에 대한 High-level 인터페이스를 제공하는 오픈소스 Python 라이브러리입니다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;pytorch-lightning&lt;/code&gt;을 사용하면, 코드가 깔끔하고 간결해지며, 주어진 포맷에만 맞게 작성하면 &lt;code class=&quot;language-text&quot;&gt;pytorch-lightning&lt;/code&gt;에서 제공하는 다양한 기능을 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;이번 포스팅에서는 &lt;code class=&quot;language-text&quot;&gt;pytorch-lightning&lt;/code&gt;의 기본적인 사용 방법을 기록합니다.&lt;/p&gt;
&lt;h3&gt;Step 0: Install&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;pip install pytorch-lightning&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Step 1: Define a LightningModule&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; torch &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; nn
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;functional &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; F
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; torchvision &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; transforms
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; torchvision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;datasets &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; MNIST
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;utils&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; DataLoader&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; random_split
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; pytorch_lightning &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; pl


&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LitAutoEncoder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pl&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;LightningModule&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__init__&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encoder &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Sequential&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Linear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReLU&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Linear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;decoder &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Sequential&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Linear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReLU&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Linear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# prediction/inference&lt;/span&gt;
        embedding &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encoder&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; embedding

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;training_step&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; batch&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; batch_idx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# train loop, forward와 독립적으로 실행합니다.&lt;/span&gt;
        x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; batch
        x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;view&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        z &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encoder&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        x_hat &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;decoder&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;z&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        loss &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; F&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mse_loss&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x_hat&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;log&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;train_loss&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; loss&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 
        &lt;span class=&quot;token comment&quot;&gt;# 디폴트는 TensorBoardLogger에 기록되는데, WandbLogger로만 바꿔주면 wandb를 사용할 수 있습니다. &lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# loss뿐만 아니라 다른 파라미터도 wandb로 보고 싶으시면 똑같이 log를 찍어주면 됩니다.&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; loss
        
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;validation_step&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; batch&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; batch_idx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; batch
        y_hat &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        val_loss &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; F&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cross_entropy&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y_hat&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; val_loss
        
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;test_step&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; batch&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; batch_idx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; batch
        y_hat &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        loss &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; F&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cross_entropy&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y_hat&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; loss
  
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;configure_optimizers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        optimizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;optim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Adam&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parameters&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lr&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1e-3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; optimizer&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Step 2: Train&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;dataset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; MNIST&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;getcwd&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; download&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; transform&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;transforms&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ToTensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
train&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; random_split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dataset&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;55000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

autoencoder &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; LitAutoEncoder&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
trainer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pl&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Trainer&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
trainer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fit&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;autoencoder&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DataLoader&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;train&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DataLoader&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;val&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;이렇게하면 학습이 시작됩니다. 하지만, 가장 기초적인 방법으로 학습을 진행한 것이기 때문에 기능들을 조금 더 알아보겠습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h2&gt;Define a LightningDataModule&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;YourLightningDataModule&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pl&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;LightningDataModule&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__init__&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
   
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;prepare_data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  
       &lt;span class=&quot;token comment&quot;&gt;# DDP/TPU에서 모든 process가 prepare_data 메소드를 통과하지 않기 때문에 stage로 나누면 안됩니다.&lt;/span&gt;
       &lt;span class=&quot;token comment&quot;&gt;# good&lt;/span&gt;
       download_data&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
       tokenize&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
       etc&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

       &lt;span class=&quot;token comment&quot;&gt;# bad&lt;/span&gt;
       self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; data_split
       self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;some_state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; some_other_state&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
       self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;something &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;


    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; stage&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Optional&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 
       &lt;span class=&quot;token comment&quot;&gt;# setup은 모든 process에서 호출된다. train, validate, test, and predict로 데이터를 나눈다.&lt;/span&gt;
       data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Load_data&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
       self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataset&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;train&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Dataset&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
       self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataset&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;valid&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Dataset&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
       self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataset&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;test&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Dataset&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;train_dataloader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; AudioDataLoader&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            dataset&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataset&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;train&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            num_workers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            batch_size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;val_dataloader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; AudioDataLoader&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            dataset&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataset&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;valid&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            num_workers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            batch_size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;test_dataloader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; AudioDataLoader&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            dataset&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataset&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;test&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            num_workers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            batch_size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;pl.Trainer&lt;/h2&gt;
&lt;p&gt;아래는 gpu-fp16 Trainer 예시입니다. Trainer에 대한 더 자세한 사용법은 &lt;a href=&quot;https://github.com/PyTorchLightning/pytorch-lightning/blob/master/pytorch_lightning/trainer/trainer.py#L91-L344&quot;&gt;여기&lt;/a&gt;를 참고하시면 좋습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;trainer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pl&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Trainer&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
              precision&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;                    &lt;span class=&quot;token comment&quot;&gt;# Double precision (64), full precision (32) or half precision (16)&lt;/span&gt;
              accelerator&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;dp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;                  &lt;span class=&quot;token comment&quot;&gt;# Distributed_backend (dp, ddp, etc ...)&lt;/span&gt;
              gpus&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;                          &lt;span class=&quot;token comment&quot;&gt;# GPU 개수&lt;/span&gt;
              accumulate_grad_batches&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;       &lt;span class=&quot;token comment&quot;&gt;# Gradient를 몇 개의 배치동안 누적해서 계산할 것인지&lt;/span&gt;
              amp_backend&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;apex&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;              &lt;span class=&quot;token comment&quot;&gt;# mixed precision backend to use (“native” or “apex”)&lt;/span&gt;
              auto_select_gpus&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;           &lt;span class=&quot;token comment&quot;&gt;# 사용가능한 GPU를 알아서 잡아준다.&lt;/span&gt;
              check_val_every_n_epoch&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;       &lt;span class=&quot;token comment&quot;&gt;# 몇 개의 epoch마다 validation 할 것 인지&lt;/span&gt;
              gradient_clip_val&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;           &lt;span class=&quot;token comment&quot;&gt;# Gradient clipping을 얼마로 할 것인지&lt;/span&gt;
              logger&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;WandbLogger&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;project&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;YOUR_PROJECT_NAME&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;        &lt;span class=&quot;token comment&quot;&gt;# 로그 선택&lt;/span&gt;
              auto_scale_batch_size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binsearch&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;                    &lt;span class=&quot;token comment&quot;&gt;# 메모리에 적합한 가장 큰 배치 사이즈를 찾아준다.&lt;/span&gt;
              max_epochs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;                                        &lt;span class=&quot;token comment&quot;&gt;# 최대 epoch 수&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Train&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;autoencoder &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; LitAutoEncoder&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
data_module &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; YourLightningDataModule&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
trainer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pl&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Trainer&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

trainer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fit&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;autoencoder&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data_module&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Tokenizer]]></title><description><![CDATA[Tokenization 문장에서 의미있는 단위로 나누는 작업을 라고 한다. 문자 단위 토큰화 문자 단위로 토큰화를 하는 것이다. 한글 음절 수는 모두 11,172개이므로 알파벳, 숫자, 기호 등을 고려한다고 해도 단어 사전의 크기는 기껏해야 1…]]></description><link>https://sooftware.github.io/tokenizer/</link><guid isPermaLink="false">https://sooftware.github.io/tokenizer/</guid><pubDate>Mon, 13 Sep 2021 23:46:37 GMT</pubDate><content:encoded>&lt;h2&gt;Tokenization&lt;/h2&gt;
&lt;p&gt;문장에서 의미있는 단위로 나누는 작업을 &lt;code class=&quot;language-text&quot;&gt;토큰화&lt;/code&gt;라고 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;문자 단위 토큰화&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;문자 단위로 토큰화를 하는 것이다.&lt;/li&gt;
&lt;li&gt;한글 음절 수는 모두 11,172개이므로 알파벳, 숫자, 기호 등을 고려한다고 해도 단어 사전의 크기는 기껏해야 15,000개를 넘기 어렵다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;장점&lt;/code&gt; : 모든 문자를 포함시켜서 &lt;code class=&quot;language-text&quot;&gt;UNK&lt;/code&gt;토큰이 잘 발생하지 않는다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;단점&lt;/code&gt; : 의미 있는 단위가 되기 어렵고, 상대적으로 시퀀스가 길어진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;어제 카페 갔었어 &gt; 어, 제, 카, 페, 갔, 었, 어
어제 카페 갔었는데요 &gt; 어, 제, 카, 페, 갔, 었, 는, 데, 요&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;단어 단위 토큰화&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;단어 단위로 토큰화를 하는 것이다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;장점&lt;/code&gt; : 공백으로 쉽게 분리할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;단점&lt;/code&gt; : 모든 단어들을 다 포함시키기에는 단어 사전의 크기가 상당히 크다. 이는 메모리 문제를 야기!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;어제 카페 갔었어 &gt; 어제, 카페, 갔었어
어제 카페 갔었는데요 &gt; 어제, 카페, 갔었는데요&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;서브워드 단위 토큰화&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;문자 단위와 단어 단위 토큰화의 중간에 있는 형태이다.&lt;/li&gt;
&lt;li&gt;“자주 등장한 단어는 그대로 두고, 자주 등장하지 않은 단어는 의미있는 서브 워드 토큰들로 분절한다” 라는 원칙에 기반을 둔 알고리즘&lt;/li&gt;
&lt;li&gt;단어 사전의 크기를 지나치게 늘리지 않으면서도 &lt;code class=&quot;language-text&quot;&gt;UNK&lt;/code&gt; 문제를 해결할 수 있다.&lt;/li&gt;
&lt;li&gt;희귀 단어, 신조어와 같은 문제를 완화시킬 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;서브워드 기반 토크나이저&lt;/h2&gt;
&lt;h3&gt;BPE(Byte-Pair Encoding)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;BPE(Byte pair encoding) 알고리즘은 1994년에 제안된 데이터 압축 알고리즘&lt;/li&gt;
&lt;li&gt;연속적으로 가장 많이 등장한 글자의 쌍을 찾아서 하나의 글자로 병합하는 방식을 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;aaabdaaabac    # 가장 자주 등장하고 있는 바이트의 쌍(byte pair)은 &apos;aa&apos; , Z=aa
ZabdZabac      # Y=ab
ZYdZYac        # X=ZY
XdXac          # 더 이상 병합할 바이트의 쌍이 없으므로 최종 결과로 하여 종료&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;&lt;a href=&quot;https://arxiv.org/abs/1508.07909&quot;&gt;자연어 처리에서의 BPE&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;글자(charcter) 단위에서 점차적으로 단어 집합(vocabulary)을 만들어 내는 Bottom up 방식의 접근을 사용&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;BPE는 일반적으로 훈련 데이터를 단어 단위로 분절하는 Pre-tokenize 과정을 거쳐야한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pre-tokenize는 공백 단위나 규칙 기반으로 수행될 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Example)&lt;br&gt;
&lt;code class=&quot;language-text&quot;&gt;(&apos;hug&apos;, 10), (&apos;pug&apos;, 5), (&apos;pun&apos;, 12), (&apos;bun&apos;, 4), (&apos;hugs&apos;, 5)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Pre-tokenize를 거쳐서 나온 단어들이라 하고 여기서 정수 값은 각 단어가 얼마나 등장했는지를 나타내는 값이다.&lt;br&gt;
이때 기본 사전은 [‘b’, ‘g’, ‘h’, ‘n’, ‘p’, ‘s’, ‘u’] 이다.&lt;br&gt;
기본 사전을 기반으로 단어들을 쪼개면 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;(&apos;h&apos; &apos;u&apos; &apos;g&apos;, 10), (&apos;p&apos; &apos;u&apos; &apos;g&apos;, 5), (&apos;p&apos; &apos;u&apos; &apos;n&apos;, 12), (&apos;b&apos; &apos;u&apos; &apos;n&apos;, 4), (&apos;h&apos; &apos;u&apos; &apos;g&apos; &apos;s&apos;, 5)&lt;/code&gt;&lt;br&gt;
“hu”는 총 15번, “ug”는 총 20번이 나와 가장 많이 등장한 쌍은 “ug”가 되고 “u”와 “g”를 합친 “ug”를 사전에 새로 추가한다.&lt;br&gt;
그럼 이때 기본 사전은 [‘b’, ‘g’, ‘h’, ‘n’, ‘p’, ‘s’, ‘u’, ‘ug’] 이다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;(&apos;h&apos; &apos;ug&apos;, 10), (&apos;p&apos; &apos;ug&apos;, 5), (&apos;p&apos; &apos;u&apos; &apos;n&apos;, 12), (&apos;b&apos; &apos;u&apos; &apos;n&apos;, 4), (&apos;h&apos; &apos;ug&apos; &apos;s&apos;, 5)&lt;/code&gt;&lt;br&gt;
또 가장 많이 나온 쌍은 16번 등장한 “un”이므로, “un”을 사전에 추가한다. 그 다음은 15번 등장한 “hug”이므로 “hug”도 사전에 추가한다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;(&apos;hug&apos;, 10), (&apos;p&apos; &apos;ug&apos;, 5), (&apos;p&apos; &apos;un&apos;, 12), (&apos;b&apos; &apos;un&apos;, 4), (&apos;hug&apos; &apos;s&apos;, 5)&lt;/code&gt;&lt;br&gt;
기본 사전은 [‘b’, ‘g’, ‘h’, ‘n’, ‘p’, ‘s’, ‘u’, ‘ug’, ‘un’, ‘hug’]가 됩니다.
이렇게 처음에는 글자 단위였던 것이 의미있는 서브워드 토큰들로 분절할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://arxiv.org/pdf/1909.03341.pdf&quot;&gt;Byte-level BPE(BBPE)&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/133186594-e4f0a5d8-65a2-4ba5-b6a2-09be7bdc6757.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf&quot;&gt;GPT-2 논문&lt;/a&gt;에서 바이트를 사전의 기본 단위로 사용하는 트릭을 사용&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;GPT-2 모델은 256개의 기본 바이트 토큰과 &lt;code class=&quot;language-text&quot;&gt;&amp;lt;end-of-text&gt;&lt;/code&gt; 토큰 그리고 50,000 개의 서브 워드를 더해 총 50,257 개의 단어 집합(vocabulary)을 가진다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;256 바이트셋으로 모든 텍스트를 표현할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;UNK&lt;/code&gt; 문제없이 모든 텍스트를 분절할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;multilingual일 때, 언어들 사이에서 vocabulary 공유를 가장 많이 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/133136459-f1b4fdbf-d9d4-4976-842e-c00cbf657624.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;WordPiece&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1810.04805&quot;&gt;BERT&lt;/a&gt;에서 활용된 서브 워드 토크나이저 알고리즘&lt;/li&gt;
&lt;li&gt;BPE와 마찬가지로 사전을 코퍼스 내 등장한 캐릭터들로 초기화 한 후, 사용자가 지정한 횟수 만큼 서브 워드를 병합하는 방식으로 훈련&lt;/li&gt;
&lt;li&gt;하지만 WordPiece는 BPE와 같이 가장 많이 등장한 쌍을 병합하는 것이 아니라, 병합되었을 때 코퍼스의 Likelihood를 가장 높이는 쌍을 병합하게 된다.&lt;/li&gt;
&lt;li&gt;즉, WordPiece에서는 코퍼스 내에서 “ug”가 등장할 확률을 “u”와 “g”가 각각 등장할 확률을 곱한 값으로 나눈 값이 다른 쌍보다 클 경우 해당 쌍을 병합하게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/54731898/133140262-f0afdedc-e54e-4564-a88d-134163c0a219.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;또 이 학생의 집에서 병든 소를 도축했던 35살 남성도 탄저병에 걸린 것으로 확인됐습니다.&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;[&apos;또&apos;, &apos;이&apos;, &apos;학생&apos;, &apos;##의&apos;, &apos;집&apos;, &apos;##에&apos;, &apos;##서&apos;, &apos;병든&apos;, &apos;소&apos;, &apos;##를&apos;, &apos;도축&apos;, &apos;##했&apos;, &apos;##던&apos;, &apos;35&apos;, &apos;##살&apos;, &apos;남성&apos;, &apos;##도&apos;, &apos;탄&apos;, &apos;##저&apos;, &apos;##병&apos;, &apos;##에&apos;, &apos;걸린&apos;, &apos;것&apos;, &apos;##으로&apos;, &apos;확인&apos;, &apos;##됐&apos;, &apos;##습&apos;, &apos;##니다&apos;, &apos;.&apos;]&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;br&gt;
&lt;h3&gt;Unigram&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;서브 워드에서 시작해 점차 사전을 줄여나가는 top-down 방식으로 진행&lt;/li&gt;
&lt;li&gt;매 스텝마다 Unigram은 주어진 코퍼스와 현재 사전에 대한 Loss를 측정한다.&lt;/li&gt;
&lt;li&gt;또한 각각의 서브 워드에 대해 해당 서브 워드가 코퍼스에서 제거되었을 때, Loss가 얼마나 증가하는지를 측정하여 Loss를 가장 조금 증가시키는 p 개 토큰을 제거한다. (p는 보통 전체 사전 크기의 10-20% 값으로 설정)&lt;/li&gt;
&lt;li&gt;해당 과정을 사용자가 원하는 사전 크기를 지니게 될 때 까지 반복하게 되고, 기본 캐릭터들은 반드시 사전에서 제거되지 않고 유지되어야한다.&lt;/li&gt;
&lt;li&gt;매번 같은 토큰 리스트를 반환하는 BPE, WordPiece와 달리 Unigram은 다양한 토큰 리스트가 생길 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;SentencePiece&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;지금까지 살펴본 모든 방법들은 공백을 기준으로 단어를 분절할 수 없기 때문에 Pre-tokenize 과정을 필요로 했다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;하지만 sentencepiece는 공백을 기준으로 단어를 분절할 수 있기 때문에 Pre-tokenize 과정이 필요없다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;또한 디코딩 과정에서 모든 토큰들을 붙여준 후,  메타스페이스(”▁”)만 공백으로 바꿔주면 되기 때문에 원상복구가 가능하다는 특징이 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;BPE 혹은 Unigram을 적용하여 사전을 구축하게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;또 이 학생의 집에서 병든 소를 도축했던 35살 남성도 탄저병에 걸린 것으로 확인됐습니다.&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;[&apos;▁또&apos;, &apos;▁이&apos;, &apos;▁학생&apos;, &apos;의&apos;, &apos;▁집에서&apos;, &apos;▁병&apos;, &apos;든&apos;, &apos;▁소&apos;, &apos;를&apos;, &apos;▁&apos;, &apos;도&apos;, &apos;축&apos;, &apos;했던&apos;, &apos;▁35&apos;, &apos;살&apos;, &apos;▁남성&apos;, &apos;도&apos;, &apos;▁탄&apos;, &apos;저&apos;, &apos;병&apos;, &apos;에&apos;, &apos;▁걸린&apos;, &apos;▁것으로&apos;, &apos;▁확인&apos;, &apos;됐&apos;, &apos;습니다&apos;, &apos;.&apos;]&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;br&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wikidocs.net/22592&quot;&gt;https://wikidocs.net/22592&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://huggingface.co/transformers/master/tokenizer_summary.html&quot;&gt;https://huggingface.co/transformers/master/tokenizer_summary.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://karter.io/huggingface&quot;&gt;https://karter.io/huggingface&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ratsgo.github.io/nlpbook/docs/preprocess/bpe/&quot;&gt;https://ratsgo.github.io/nlpbook/docs/preprocess/bpe/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/pdf/1508.07909.pdf&quot;&gt;https://arxiv.org/pdf/1508.07909.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[정규표현식 (regex)]]></title><description><![CDATA[정규 표현식 정규표현식(regular expression)은 일종의 문자를 표현하는 공식으로, 특정 규칙이 있는 문자열 집합을 추출할 때 자주 사용되는 기법입니다. 주로 Prograaming Language나 Text Editor…]]></description><link>https://sooftware.github.io/regex/</link><guid isPermaLink="false">https://sooftware.github.io/regex/</guid><pubDate>Wed, 08 Sep 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;정규 표현식&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;정규표현식(regular expression)은 일종의 문자를 표현하는 공식으로, 특정 규칙이 있는 문자열 집합을 추출할 때 자주 사용되는 기법입니다.&lt;/li&gt;
&lt;li&gt;주로 Prograaming Language나 Text Editor등에서 문자열의 검색과 치환을 위한 용도로 쓰이고 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;메타문자&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;. ^ $ * + ? {} [] \ | ()&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;메타문자는 문자를 설명하기 위한 문자로, 문자의 구성을 설명하기 위해 원래의 의미가 아닌 다른 의미로 쓰이는 문자를 말합니다.&lt;/li&gt;
&lt;li&gt;정규표현식에서는 위와 같은 메타문자를 사용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;정규표현식: &lt;code class=&quot;language-text&quot;&gt;[]&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;문자 클래스인 &lt;code class=&quot;language-text&quot;&gt;[]&lt;/code&gt;는 &lt;code class=&quot;language-text&quot;&gt;&quot;[] 사이의 문자들과 매치&quot;&lt;/code&gt;라는 의미를 가지며, &lt;code class=&quot;language-text&quot;&gt;[]&lt;/code&gt;사이에는 어떤 문자도 들어갈 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;[abc]&lt;/code&gt;라면 이 표현식의 의미는 &lt;code class=&quot;language-text&quot;&gt;&quot;a, b, c 중 한 개의 문자와 매치&quot;&lt;/code&gt;를 뜻합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;예시) &lt;code class=&quot;language-text&quot;&gt;[abc]&lt;/code&gt;가 &lt;code class=&quot;language-text&quot;&gt;&quot;a&quot;, &quot;before&quot;, &quot;dude&quot;&lt;/code&gt;와 어떻게 매치되는지 살펴보겠습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;a&lt;/code&gt;는 정규식과 일치하는 문자인 &lt;code class=&quot;language-text&quot;&gt;a&lt;/code&gt;가 있으므로 매치&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;before&lt;/code&gt;는 정규식과 일치하는 문자인 &lt;code class=&quot;language-text&quot;&gt;b&lt;/code&gt;가 있으므로 매치&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;dude&lt;/code&gt;는 정규식과 일치하는 문자인 &lt;code class=&quot;language-text&quot;&gt;a, b, c&lt;/code&gt;중 어느 하나도 포함하고 있지 않으므로 매치되지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;정규표현식: &lt;code class=&quot;language-text&quot;&gt;하이픈(-), 캐럿(^)&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;하이픈(-)은 두 문자 사이의 범위(from - to)를 의미, 캐럿(^)은 반대를 의미합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;[a-zA-Z]&lt;/code&gt;: 알파벳 모두 매치&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;[0-9]&lt;/code&gt;: 숫자 매치&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;[^0-9]&lt;/code&gt;: 숫자가 아닌 문자만 매치
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;[]&lt;/code&gt;안에서는 부정의 의미로 사용&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;[]&lt;/code&gt;가 없으면 문자열의 처음을 뜻함(끝은 $로 표시)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;문자클래스&lt;code class=&quot;language-text&quot;&gt;[]&lt;/code&gt;안에는 어떤 문자나 메타 문자도 사용할 수 있지만 &lt;code class=&quot;language-text&quot;&gt;^&lt;/code&gt;는 반대(not)의 의미로 사용되기 때문에 조심해야합니다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;정규표현식: &lt;code class=&quot;language-text&quot;&gt;\역슬래쉬&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;[0-9]&lt;/code&gt;또는 &lt;code class=&quot;language-text&quot;&gt;[a-zA-Z]&lt;/code&gt;와 같은 정규표현식은 &lt;code class=&quot;language-text&quot;&gt;\역슬래쉬&lt;/code&gt;를 이용해 간단하게 표현할 수 있습니다. 이번엔 &lt;code class=&quot;language-text&quot;&gt;\역슬래쉬&lt;/code&gt;를 사용한 별도의 표기법들에 대해 알아보겠습니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;\d&lt;/code&gt; - 숫자와 매치, &lt;code class=&quot;language-text&quot;&gt;[0-9]&lt;/code&gt;와 동일한 표현식이다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;\D&lt;/code&gt; - 숫자가 아닌 것과 매치, &lt;code class=&quot;language-text&quot;&gt;[^0-9]&lt;/code&gt;와 동일한 표현식이다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;\s&lt;/code&gt; - whitespace 문자와 매치, &lt;code class=&quot;language-text&quot;&gt;[ \t\n\r\f\v]&lt;/code&gt;와 동일한 표현식이다. 맨 앞의 빈 칸은 공백문자(space)를 의미한다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;\S&lt;/code&gt; - whitespace 문자가 아닌 것과 매치, &lt;code class=&quot;language-text&quot;&gt;[^\t\n\r\f\v]&lt;/code&gt;와 동일한 표현식이다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;\w&lt;/code&gt; - 문자+숫자(alphanumeric)와 매치, &lt;code class=&quot;language-text&quot;&gt;[a-zA-Z0-9_]&lt;/code&gt;와 동일한 표현식이다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;\W&lt;/code&gt; - 문자+숫자(alphanumeric)가 아닌 문자와 매치, &lt;code class=&quot;language-text&quot;&gt;[^a-zA-Z0-9_]&lt;/code&gt;와 동일한 표현식이다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;\s&lt;/code&gt; - 스페이스(공백문자), 탭과 매치, &lt;code class=&quot;language-text&quot;&gt;[\t\n\f\r]&lt;/code&gt;과 동일한 표현식이다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;\S&lt;/code&gt; - 스페이스 외 문자와 매치, &lt;code class=&quot;language-text&quot;&gt;[^\t\n\f\r]&lt;/code&gt;과 동일한 표현식이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;대문자로 사용된 것은 소문자의 반대임을 추측할 수 있습니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;또한 정규식 상의 특별한 의미가 있는 문자들을 문자 그대로 쓸 때 앞에 붙혀 사용됩니다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;정규표현식: ‘Dot(.)’&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;줄바꿈 문자인 &lt;code class=&quot;language-text&quot;&gt;\n&lt;/code&gt;을 제외한 모든 문자와 매치됨을 의미합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;다음 정규식을 보겠습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;a.b&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 정규식의 의미는 &lt;code class=&quot;language-text&quot;&gt;&quot;a + 모든문자 + b&quot;&lt;/code&gt;와 같습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;즉 a와b라는 문자 사이에 어떤 문자가 들어가도 모두 매치가 된다는 의미입니다.
&lt;ul&gt;
&lt;li&gt;예시로 &lt;code class=&quot;language-text&quot;&gt;&quot;aab&quot;, &quot;a0b&quot;, &quot;abc&quot;&lt;/code&gt;를 보겠습니다.
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;aab&lt;/code&gt;는 가운데 문자 &lt;code class=&quot;language-text&quot;&gt;a&lt;/code&gt;가 모든 문자를 의미하는 &lt;code class=&quot;language-text&quot;&gt;.&lt;/code&gt;과 일치하므로 정규식과 매치됩니다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;a0b&lt;/code&gt;도 동일하게 가운데 문자 &lt;code class=&quot;language-text&quot;&gt;0&lt;/code&gt;이 모든 문자를 의미하는 &lt;code class=&quot;language-text&quot;&gt;.&lt;/code&gt;과 일치하므로 정규식과 매치됩니다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;abc&lt;/code&gt;는 &lt;code class=&quot;language-text&quot;&gt;a&lt;/code&gt;와 &lt;code class=&quot;language-text&quot;&gt;b&lt;/code&gt;사이에 어떤 문자가 존재하지 않기 때문에 위 정규식과 매치되지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그렇다면 이 정규식은 어떨까요?&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;a[.]b&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;앞서 설명드렸다 싶이 문자클래스&lt;code class=&quot;language-text&quot;&gt;[]&lt;/code&gt;는 내부에 메타문자가 들어가더라도 문자 그대로 인식해주는 특징을 갖고 있습니다.
따라서 &lt;code class=&quot;language-text&quot;&gt;a.b&lt;/code&gt;와 매치되고 &lt;code class=&quot;language-text&quot;&gt;a0b&lt;/code&gt;와 같은 문자열은 매치되지 않습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;정규표현식: 반복 관련 메타 문자 &lt;code class=&quot;language-text&quot;&gt;* + ? {}&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;반복(*)
&lt;ul&gt;
&lt;li&gt;메타문자 &lt;code class=&quot;language-text&quot;&gt;*&lt;/code&gt;은 &lt;code class=&quot;language-text&quot;&gt;*&lt;/code&gt;바로 앞에 있는 문자가 0부터 무한대로 반복될 수 있다는 의미입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;ca*t&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;위 정규식은 &lt;code class=&quot;language-text&quot;&gt;c + a(0번 이상 반복) + t&lt;/code&gt;라는 것을 알 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ct&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;cat&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;caaaat&lt;/code&gt; 모두 매치됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;반복(+)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;반복을 나타내는 또 다른 문자인 &lt;code class=&quot;language-text&quot;&gt;+&lt;/code&gt;입니다. &lt;code class=&quot;language-text&quot;&gt;+&lt;/code&gt;는 &lt;code class=&quot;language-text&quot;&gt;*&lt;/code&gt;과 달리 최소 1번 이상 반복될 때 사용합니다. 즉 &lt;code class=&quot;language-text&quot;&gt;*&lt;/code&gt;은 반복횟수가 0부터 시작, &lt;code class=&quot;language-text&quot;&gt;+&lt;/code&gt;는 반복횟수가 1부터 시작됩니다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ct&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;cat&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;caaat&lt;/code&gt;중 &lt;code class=&quot;language-text&quot;&gt;ct&lt;/code&gt;는 매치되지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;반복({m,n})&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;{}&lt;/code&gt;는 원하는 반복횟수를 지정하고 싶을 때 사용됩니다. m에서 n까지 반복, m이상인 경우, n이하인 경우 등 자유롭게 원하는 만큼 조절이 가능합니다.
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;{m}&lt;/code&gt;: 반드시 m번 반복
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ca{2}t&lt;/code&gt;: “c + a(반드시 2번 반복) + t”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;{m, n}&lt;/code&gt;: m~n회 반복
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ca{2, 5}t&lt;/code&gt;: “c + a(2~5회 반복) + t”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;{m,}, {,n}&lt;/code&gt;: m회 이상 반복, n회 이하 반복&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;반복(?)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;?&lt;/code&gt;는 반복은 아니지만 비슷한 개념으로 &lt;code class=&quot;language-text&quot;&gt;{0, 1}&lt;/code&gt;과 같은 의미를 지닙니다. 즉, 문자가 있거나 없거나 둘 다 매치 되는 경우입니다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ab?c&lt;/code&gt; : “a + b(있어도 되고 없어도 된다) + c”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;*&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;+&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;?&lt;/code&gt;메타 문자는 모두 &lt;code class=&quot;language-text&quot;&gt;{m, n}&lt;/code&gt; 형태로 고쳐 쓰는 것이 가능하지만 가급적 이해하기 쉽고 간결한 &lt;code class=&quot;language-text&quot;&gt;*&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;+&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;?&lt;/code&gt;메타 문자를 사용하는 것이 좋습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;ex) 주민등록번호 정규표현식&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;/^\d{2}[0-1]\d{1}[0-3]\d{1}\-[1-4]\d{6}$/&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;^&lt;/code&gt;: Start of String&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;\d{3}&lt;/code&gt;: 1-2번째(년도) 숫자 0-9&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;[0-1]&lt;/code&gt;: 3번째(월도 앞자리) 0,1&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;\d{1}&lt;/code&gt;: 4번째(월도 뒷자리) 숫자 0-9&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;[0-3]&lt;/code&gt;: 5번째(일자 앞자리) 0,1,2,3&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;\d{1}&lt;/code&gt;: 6번째(일자 뒷자리) 숫자 0-9&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;\-&lt;/code&gt; : 7번째(구분자) -&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;[1-4]&lt;/code&gt;: 8번째(성별) 90년대생 1,2 2000년대생 3,4&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;\d{6}&lt;/code&gt;: 9-14번째(뒷자리 6자리) 숫자 0-9&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;$&lt;/code&gt;: End of String&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h2&gt;파이썬과 정규표현식&lt;/h2&gt;
&lt;p&gt;파이썬은 정규 표현식을 지원하기 위해 re(regular expression)모듈을 제공합니다.&lt;/p&gt;
&lt;p&gt;Usage&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;import re
pattern = re.compile(&amp;quot;정규식&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;re.compile을 사용하여 정규 표현식을 컴파일합니다. re.compile의 결과인 객체 &lt;code class=&quot;language-text&quot;&gt;pattern&lt;/code&gt;에 입력한 정규식의 대한 정보가 담겨있습니다.&lt;/p&gt;
&lt;p&gt;이제 &lt;code class=&quot;language-text&quot;&gt;pattern&lt;/code&gt;객체를 이용해 문자열 검색을 수행해보겠습니다. 컴파일된 패턴 객체는 다음과 같은 4가지 메서드를 제공합니다.
&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/133471058-446759bb-eeeb-4000-b6ef-6ca795be12df.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;import re
p = re.compile(&amp;#39;[a-z]+&amp;#39;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 코드를 실행해 생성된 객체 &lt;code class=&quot;language-text&quot;&gt;p&lt;/code&gt;로 메서드를 살펴보겠습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;match&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;match 메서드는 문자열의 처음부터 정규식과 매치되는지 조사하며, 반환값으로 match 객체를 돌려줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; m = p.match(&amp;quot;python&amp;quot;)
&amp;gt;&amp;gt;&amp;gt; print(m)
&amp;lt;_sre.SRE_Match object at 0x01F3F9F8&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;python&lt;/code&gt;문자열은 &lt;code class=&quot;language-text&quot;&gt;[a-z]+&lt;/code&gt;정규식에 부합되므로 match 객체를 돌려줍니다.&lt;/p&gt;
&lt;p&gt;따라서 파이썬 정규식 프로그램은 다음과 같이 작성해 매치 여부를 확인합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;p = re.compile(정규표현식)
m = p.match(문자열)

if m:
    print(&amp;quot;정규식 일치&amp;quot;)
else:
    print(&amp;quot;정규식 불일치&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;search&lt;/h3&gt;
&lt;p&gt;동일하게 컴파일된 객체 p를 갖고 이번엔 search 메서드를 수행해보겠습니다. 예시를 통해 match와의 차이점을 확인해보시면 좋을 것 같습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; m = p.search(&amp;quot;3 python&amp;quot;)
&amp;gt;&amp;gt;&amp;gt; print(m)
&amp;lt;_sre.SRE_Match object at 0x01F3FA30&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;3 python&lt;/code&gt;문자열은 첫번째 문자가 숫자이므로 match메서드에서는 None을 반환합니다. 하지만 search메서드는 문자열의 처음부터 검색하는 것이 아니라 문자열 전체를 검색하기 때문에 “python”문자열과 매치돼서 match객체를 반환하게 됩니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;findall&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;findall&lt;/code&gt; 메서드는 이름 그대로 문자열에서 정규식과 일치하는 부분을 찾아 리스트로 반환시켜줍니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; result = p.findall(&amp;quot;life is too short&amp;quot;)
&amp;gt;&amp;gt;&amp;gt; print(result)
[&amp;#39;life&amp;#39;, &amp;#39;is&amp;#39;, &amp;#39;too&amp;#39;, &amp;#39;short&amp;#39;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;정규식과 일치하는 부분인 각 단어들이 반환되는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;finditer&lt;/h3&gt;
&lt;p&gt;finditer는 findall과 동일하지만 그 결과로 반복 가능한 객체를 돌려줍니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; result = p.finditer(&amp;quot;life is too short&amp;quot;)
&amp;gt;&amp;gt;&amp;gt; print(result)
&amp;lt;callable_iterator object at 0x01F5E390&amp;gt;
&amp;gt;&amp;gt;&amp;gt; for r in result: print(r)
...
&amp;lt;_sre.SRE_Match object at 0x01F3F9F8&amp;gt;
&amp;lt;_sre.SRE_Match object at 0x01F3FAD8&amp;gt;
&amp;lt;_sre.SRE_Match object at 0x01F3FAA0&amp;gt;
&amp;lt;_sre.SRE_Match object at 0x01F3F9F8&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;반복 가능한 객체가 포함하는 각각의 요소는 match 객체입니다.&lt;/p&gt;
&lt;br&gt;
&lt;h2&gt;match 객체의 메서드&lt;/h2&gt;
&lt;p&gt;계속 반환받아왔던 match객체를 써먹어야겠죠? 이번엔 match객체의 메서드들에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/59256704/133474331-97272bd8-2286-45c7-b026-db5e6948cb8f.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;다음 예시로 살펴보겠습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; m = p.match(&amp;quot;python&amp;quot;)
&amp;gt;&amp;gt;&amp;gt; m.group()
&amp;#39;python&amp;#39;
&amp;gt;&amp;gt;&amp;gt; m.start()
0
&amp;gt;&amp;gt;&amp;gt; m.end()
6
&amp;gt;&amp;gt;&amp;gt; m.span()
(0, 6)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;예상된 결과값입니다. 만약 match메서드를 사용해 반환된 match메서드라면 start()의 결과값은 항상 0일 것입니다. match메서드는 항상 문자열의 시작부터 조사하기 때문이죠.&lt;/p&gt;
&lt;p&gt;만약 search 메서드를 사용했다면 start()값은 다르게 나올 것입니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; m = p.search(&amp;quot;3 python&amp;quot;)
&amp;gt;&amp;gt;&amp;gt; m.group()
&amp;#39;python&amp;#39;
&amp;gt;&amp;gt;&amp;gt; m.start()
2
&amp;gt;&amp;gt;&amp;gt; m.end()
8
&amp;gt;&amp;gt;&amp;gt; m.span()
(2, 8)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이처럼 문자열에서 정규식이 해당되는 부분의 첫 시작지점이 나오게 됩니다.&lt;/p&gt;
&lt;p&gt;※ 모듈 단위로 수행&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; m = re.match(&amp;#39;[a-z]+&amp;#39;, &amp;quot;python&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;다음과 같이 축약된 형태로도 사용가능합니다.&lt;/p&gt;
&lt;br&gt;
&lt;h2&gt;컴파일 옵션&lt;/h2&gt;
&lt;p&gt;정규식을 컴파일할 때 다음 옵션을 사용할 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DOTALL(S) - . 이 줄바꿈 문자를 포함하여 모든 문자와 매치할 수 있도록 한다.&lt;/li&gt;
&lt;li&gt;IGNORECASE(I) - 대소문자에 관계없이 매치할 수 있도록 한다.&lt;/li&gt;
&lt;li&gt;MULTILINE(M) - 여러줄과 매치할 수 있도록 한다. (^, $ 메타문자의 사용과 관계가 있는 옵션이다)&lt;/li&gt;
&lt;li&gt;VERBOSE(X) - verbose 모드를 사용할 수 있도록 한다. (정규식을 보기 편하게 만들수 있고 주석등을 사용할 수 있게된다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;옵션을 사용할 때는 &lt;code class=&quot;language-text&quot;&gt;re.DOTALL&lt;/code&gt;처럼 전체 옵션이름을 써도 되고, &lt;code class=&quot;language-text&quot;&gt;re.S&lt;/code&gt;처럼 약어를 써도 됩니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;DOTALL, S&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;.&lt;/code&gt;메타 문자가 줄바꿈 문자&lt;code class=&quot;language-text&quot;&gt;\n&lt;/code&gt;도 포함시키도록 하고 싶다면 &lt;code class=&quot;language-text&quot;&gt;re.DOTALL&lt;/code&gt;또는 &lt;code class=&quot;language-text&quot;&gt;re.S&lt;/code&gt;옵션을 사용해 정규식을 컴파일하면 됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; p = re.compile(&amp;#39;a.b&amp;#39;, re.DOTALL)
&amp;gt;&amp;gt;&amp;gt; m = p.match(&amp;#39;a\nb&amp;#39;)
&amp;gt;&amp;gt;&amp;gt; print(m)
&amp;lt;_sre.SRE_Match object at 0x01FCF3D8&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;re.DOTALL&lt;/code&gt;옵션으로 &lt;code class=&quot;language-text&quot;&gt;\n&lt;/code&gt;도 매치시키는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;IGNORECASE, I&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;re.IGNORECASE&lt;/code&gt; 또는 &lt;code class=&quot;language-text&quot;&gt;re.I&lt;/code&gt; 옵션은 대소문자 구별 없이 매치를 수행할 때 사용하는 옵션입니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; p = re.compile(&amp;#39;[a-z]&amp;#39;, re.I)
&amp;gt;&amp;gt;&amp;gt; p.match(&amp;#39;python&amp;#39;)
&amp;lt;_sre.SRE_Match object at 0x01FCFA30&amp;gt;
&amp;gt;&amp;gt;&amp;gt; p.match(&amp;#39;Python&amp;#39;)
&amp;lt;_sre.SRE_Match object at 0x01FCFA68&amp;gt;
&amp;gt;&amp;gt;&amp;gt; p.match(&amp;#39;PYTHON&amp;#39;)
&amp;lt;_sre.SRE_Match object at 0x01FCF9F8&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;[a-z]&lt;/code&gt; 정규식은 소문자만을 의미하지만 re.I옵션으로 대소문자 구별없이 매치되는 것을 볼 수 있습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;MULTILINE, M&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;^&lt;/code&gt;은 문자열의 처음, &lt;code class=&quot;language-text&quot;&gt;$&lt;/code&gt;은 문자열의 마지막을 의미합니다. 자세한 설명 전에 다음 예시를 살펴보겠습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;import re
p = re.compile(&amp;quot;^python\s\w+&amp;quot;)

data = &amp;quot;&amp;quot;&amp;quot;python one
life is too short
python two
you need python
python three&amp;quot;&amp;quot;&amp;quot;

print(p.findall(data))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;결과&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;[&amp;#39;python one&amp;#39;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;결과를 보면 알겠지만 &lt;code class=&quot;language-text&quot;&gt;^&lt;/code&gt;메타 문자에 의해 python이라는 문자열을 사용한 첫 번째 줄만 매치된 것을 알 수 있습니다.&lt;/p&gt;
&lt;p&gt;하지만 &lt;code class=&quot;language-text&quot;&gt;^&lt;/code&gt;메타 문자를 문자열 전체의 처음이 아니라 각 라인의 처음으로 인식시키고 싶은 경우가 있을 것입니다. 이럴 때 사용하는 옵션이 바로 &lt;code class=&quot;language-text&quot;&gt;re.MULTILINE&lt;/code&gt; 옵션입니다.&lt;/p&gt;
&lt;p&gt;위 코드에 &lt;code class=&quot;language-text&quot;&gt;re.MULTILINE&lt;/code&gt;옵션을 추가해보겠습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;import re
p = re.compile(&quot;^python\s\w+&quot;, re.MULTILINE)

data = &quot;&quot;&quot;python one
life is too short
python two
you need python
python three&quot;&quot;&quot;

print(p.findall(data))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;결과&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;[&amp;#39;python one&amp;#39;, &amp;#39;python two&amp;#39;, &amp;#39;python three&amp;#39;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;다음과 같이 &lt;code class=&quot;language-text&quot;&gt;^&lt;/code&gt;메타 문자가 문자열의 각 줄마다 적용되는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;VERBOSE, X&lt;/h3&gt;
&lt;p&gt;여태 봐왔듯이 정규식은 굉장히 가독성이 안좋은 것을 알 수 있습니다. 이런 정규식의 가독성을 조금이나마 해결해주기 위한 옵션이 바로 &lt;code class=&quot;language-text&quot;&gt;VERBOSE&lt;/code&gt;입니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;charref = re.compile(r&amp;#39;&amp;amp;[#](0[0-7]+|[0-9]+|x[0-9a-fA-F]+);&amp;#39;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;charref = re.compile(r&amp;quot;&amp;quot;&amp;quot;
 &amp;amp;[#]                # Start of a numeric entity reference
 (
     0[0-7]+         # Octal form
   | [0-9]+          # Decimal form
   | x[0-9a-fA-F]+   # Hexadecimal form
 )
 ;                   # Trailing semicolon
&amp;quot;&amp;quot;&amp;quot;, re.VERBOSE)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;첫 번째와 두 번째 예를 비교해보면 패턴 객체인 &lt;code class=&quot;language-text&quot;&gt;charref&lt;/code&gt;는 모두 동일한 역할을 합니다. 하지만 두번째처럼 주석을 적고 여러 줄로 표현하는 것이 가독성이 좋은 것을 알 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;re.VERBOSE&lt;/code&gt;옵션은 문자열에 사용된 whitespace가 컴파일시 제거되며, #을 이용해 주석문을 달 수 있습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h2&gt;백슬래시 문제&lt;/h2&gt;
&lt;p&gt;정규표현식을 파이썬에서 사용할 때 혼란을 주는 요소가 있습니다. 바로 백슬래시인데요.&lt;/p&gt;
&lt;p&gt;예를들어 &lt;code class=&quot;language-text&quot;&gt;\section&lt;/code&gt; 문자열을 찾기 위한 정규식을 만든다고 가정해봅시다.&lt;/p&gt;
&lt;p&gt;우리의 의도와 달리 &lt;code class=&quot;language-text&quot;&gt;\s&lt;/code&gt;문자가 whitespace로 해석되어 의도한 대로 매치가 이루어지지 않습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;[ \t\n\r\f\v]ection&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;즉 이 것과 같은 의미를 가지게 됩니다.&lt;/p&gt;
&lt;p&gt;우리가 의도한 결과를 얻기 위해선 다음과 같이 변경해줘야 됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;\\section&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;그런데 파이썬에서는 파이썬 문자열 리터럴 규칙에 따라 &lt;code class=&quot;language-text&quot;&gt;\\&lt;/code&gt;이 &lt;code class=&quot;language-text&quot;&gt;\&lt;/code&gt;로 변경되어 &lt;code class=&quot;language-text&quot;&gt;\section&lt;/code&gt;이 전달됩니다.&lt;/p&gt;
&lt;p&gt;따라서 우리가 원하는 결과를 얻기위해서 무려 &lt;code class=&quot;language-text&quot;&gt;\\\\&lt;/code&gt;처럼 백슬래시를 4개나 사용해야됩니다.&lt;/p&gt;
&lt;p&gt;이러한 문제를 해결하기 위해 파이썬 정규식에는 Raw String 규칙이 생겨났습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;p = re.compile(r&amp;#39;\\section&amp;#39;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;다음과 같이 &lt;code class=&quot;language-text&quot;&gt;r&lt;/code&gt;을 문자열 앞에 붙혀 Raw String임을 알려줄 수 있습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;정규표현식: 그룹&lt;/h3&gt;
&lt;p&gt;그룹화는 말 그대로 그룹으로 묶어주는 것입니다. 지금까지 사용했던 정규식들은 한 문자에만 적용됐습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; re.findall(&amp;#39;12+&amp;#39;, &amp;#39;12 1212 1222&amp;#39;)
[&amp;#39;12&amp;#39;, &amp;#39;12&amp;#39;, &amp;#39;12&amp;#39;, &amp;#39;1222&amp;#39;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;1212&lt;/code&gt;와 같은 문자를 찾고 싶은데, &lt;code class=&quot;language-text&quot;&gt;12&lt;/code&gt;혹은 &lt;code class=&quot;language-text&quot;&gt;1222&lt;/code&gt;만 찾아지는 경우입니다. 즉 메타문자 &lt;code class=&quot;language-text&quot;&gt;+&lt;/code&gt;가 &lt;code class=&quot;language-text&quot;&gt;2&lt;/code&gt;에만 적용된 것입니다.&lt;/p&gt;
&lt;p&gt;만약 우리가 &lt;code class=&quot;language-text&quot;&gt;12&lt;/code&gt;가 반복되는 문자를 찾고싶다면 &lt;code class=&quot;language-text&quot;&gt;12&lt;/code&gt;를 소괄호로 그룹화 시켜주면 됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;print(re.match(&amp;#39;(12)+&amp;#39;, &amp;#39;1212&amp;#39;))
print(re.search(&amp;#39;(12)+&amp;#39;, &amp;#39;1212&amp;#39;))
print(re.findall(&amp;#39;(12)+&amp;#39;, &amp;#39;1212&amp;#39;))
print(re.fullmatch(&amp;#39;(12)+&amp;#39;, &amp;#39;1212&amp;#39;))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;결과&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;lt;_sre.SRE_Match object; span=(0, 4), match=&amp;#39;1212&amp;#39;&amp;gt;
&amp;lt;_sre.SRE_Match object; span=(0, 4), match=&amp;#39;1212&amp;#39;&amp;gt;
[&amp;#39;12&amp;#39;]
&amp;lt;_sre.SRE_Match object; span=(0, 4), match=&amp;#39;1212&amp;#39;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;우리가 원하는 &lt;code class=&quot;language-text&quot;&gt;1212&lt;/code&gt;를 잘 찾은 것을 볼 수 있습니다.
그런데 re.findall의 결과가 이상합니다. 어째서 &lt;code class=&quot;language-text&quot;&gt;[&apos;12&apos;]&lt;/code&gt;가 나온 것일까요??&lt;/p&gt;
&lt;p&gt;이는 바로 괄호가 가진 다른 기능인 캡처 때문입니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;정규표현식: 캡처&lt;/h3&gt;
&lt;p&gt;캡처란 원하는 부분만을 추출하고 싶을 때 사용하는 것입니다. 예를들어 &lt;code class=&quot;language-text&quot;&gt;yyyy-mm-dd&lt;/code&gt;와 같이 날짜를 나타내는 문자열 중 월, 일을 각각 따로 빼서 쓰고 싶다면 &lt;code class=&quot;language-text&quot;&gt;mm&lt;/code&gt;과 &lt;code class=&quot;language-text&quot;&gt;dd&lt;/code&gt;부분에 캡처기능을 사용하면 됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;print(re.findall(&amp;#39;\d{4}-(\d\d)-(\d\d)&amp;#39;, &amp;#39;2028-07-28&amp;#39;))
print(re.findall(&amp;#39;\d{4}-(\d\d)-(\d\d)&amp;#39;, &amp;#39;1999/05/21 2018-07-28 2019.01.01&amp;#39;))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;결과&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;[(&amp;#39;07&amp;#39;, &amp;#39;28&amp;#39;)]
[(&amp;#39;07&amp;#39;, &amp;#39;28&amp;#39;)]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;정규식의 내용과 일치하고, 월과 일에 해당하는 부분만 따로 빠졌음을 알 수 있습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;groups()&lt;/h3&gt;
&lt;p&gt;기존에 match객체에서 일치되는 문자열을 반환하는 &lt;code class=&quot;language-text&quot;&gt;group()&lt;/code&gt;메서드를 알아봤었습니다.
&lt;code class=&quot;language-text&quot;&gt;group()&lt;/code&gt;과는 다르게 &lt;code class=&quot;language-text&quot;&gt;groups()&lt;/code&gt;메서드는 명시적으로 캡처(&lt;code class=&quot;language-text&quot;&gt;()&lt;/code&gt;로 감싼 부분)한 부분을 반환합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; m = re.search(&amp;#39;\d{4}-(\d?\d)-(\d?\d)&amp;#39;, &amp;#39;1868-12-10&amp;#39;)
&amp;gt;&amp;gt;&amp;gt; print(m)
&amp;lt;_sre.SRE_Match object; span=(0, 10), match=&amp;#39;1868-12-10&amp;#39;&amp;gt;
&amp;gt;&amp;gt;&amp;gt; print(m.group())
1868-12-10
&amp;gt;&amp;gt;&amp;gt; print(m.groups())
(&amp;#39;12&amp;#39;, &amp;#39;10&amp;#39;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이처럼 캡처시킨 부분을 반환시키는 것을 볼 수 있습니다. 또한 &lt;code class=&quot;language-text&quot;&gt;group()&lt;/code&gt;메서드로 부터 캡처된 내용을 추출할 수도 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;m.group(): 1868-12-10
m.group(0): 1868-12-10
m.group(1): 12
m.group(2): 10
m.groups(): (&amp;#39;12&amp;#39;, &amp;#39;10&amp;#39;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;비 캡처 그룹&lt;/h3&gt;
&lt;p&gt;그렇다면 그룹화를 위해 소괄호를 반드시 써야 되는데, 굳이 캡처하고 싶지는 않을 때가 있습니다. 그럴 경우에 바로 비캡쳐그룹을 사용합니다.&lt;/p&gt;
&lt;p&gt;비캡처그룹은 &lt;code class=&quot;language-text&quot;&gt;(?:&amp;lt;regex&gt;)&lt;/code&gt;와 같이 사용됩니다. 아까 원하는 결과였던 &lt;code class=&quot;language-text&quot;&gt;1212&lt;/code&gt;대신 &lt;code class=&quot;language-text&quot;&gt;12&lt;/code&gt;가 출력됐던 예제를 다시 가져와 적용시켜보겠습니다.&lt;/p&gt;
&lt;p&gt;기존 코드&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; print(re.findall(&amp;#39;(12)+&amp;#39;, &amp;#39;1212&amp;#39;))
[&amp;#39;12&amp;#39;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;변경 코드&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; print(re.findall(&amp;#39;(?:12)+&amp;#39;, &amp;#39;1212&amp;#39;))
[&amp;#39;1212&amp;#39;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이런 식으로 비 캡처 그룹을 생성시켜 원하는 결과를 얻을 수 있습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;(숫자): 앞서 일치된 문자열을 다시 비교&lt;/h3&gt;
&lt;p&gt;앞뒤가 똑같은 세글자 단어를 찾아봅시다. ex)토마토, ABA&lt;/p&gt;
&lt;p&gt;이를 위해선 조금 전 사용했던 캡처가 꼭 필요합니다. 하지만 캡처된 문자열을 접근하기 위해선 한번의 match 과정이 필요했습니다.&lt;/p&gt;
&lt;p&gt;하지만 정규식 내에서 캡처된 그룹에 접근하는 방법도 존재합니다. 바로 &lt;code class=&quot;language-text&quot;&gt;\(숫자)&lt;/code&gt;입니다.
&lt;code class=&quot;language-text&quot;&gt;\ &lt;/code&gt;이후에 등장하는 숫자번호(N)가 바로 캡처 그룹의 번호로 즉 N번째의 그룹을 재참조한다는 의미입니다.&lt;/p&gt;
&lt;p&gt;예시를 하나 살펴보겠습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; print(re.search(r&amp;#39;(\w)\w\1&amp;#39;, &amp;#39;토마토 ABC aba xyxy &amp;#39;).group())
토마토
&amp;gt;&amp;gt;&amp;gt; print(re.findall(r&amp;#39;(\w)\w\1&amp;#39;, &amp;#39;토마토 ABC aba xyxy &amp;#39;))
[&amp;#39;토&amp;#39;, &amp;#39;a&amp;#39;, &amp;#39;x&amp;#39;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;첫번째는 우리가 원하는 답이지만 search는 하나밖에 찾지 못하므로 완벽한 답이 아닙니다.&lt;/p&gt;
&lt;p&gt;두번째 또한 &lt;code class=&quot;language-text&quot;&gt;()&lt;/code&gt;에 의해서 캡처 그룹만을 반환돼 우리가 원하지 않는 결과를 보입니다.&lt;/p&gt;
&lt;p&gt;이런 문제를 해결하기 위해서 캡처를 하나 더 만들어 줍니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; print(re.findall(r&amp;#39;((\w)\w\2)&amp;#39;, &amp;#39;토마토 ABC aba xyxy &amp;#39;))
[&amp;#39;토마토&amp;#39;, &amp;#39;aba&amp;#39;, &amp;#39;xyx&amp;#39;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;여기서 재참조부가 &lt;code class=&quot;language-text&quot;&gt;\2&lt;/code&gt;인 이유는 우리가 참조해야될 &lt;code class=&quot;language-text&quot;&gt;(\w)&lt;/code&gt;그룹이 바깥 괄호로 인해 두번째 그룹으로 변경됐기 때문입니다.
따라서 우리는 &lt;code class=&quot;language-text&quot;&gt;\1&lt;/code&gt;이 아닌 &lt;code class=&quot;language-text&quot;&gt;\2&lt;/code&gt;를 입력해줘야 됩니다.&lt;/p&gt;
&lt;p&gt;이러한 &lt;code class=&quot;language-text&quot;&gt;\1&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;\2&lt;/code&gt;와 같은 것들을 비 명명 그룹이라고 합니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;명명 그룹&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;\(숫자)&lt;/code&gt;와 같은 방법은 간편하지만 눈에 잘 들어오지 않습니다.&lt;/p&gt;
&lt;p&gt;많은 프로그래밍 언어의 정규표현식은 명명 그룹 기능을 지원합니다.
언어마다 쓰는 방법이 다르지만, 파이썬 기준으로는 &lt;code class=&quot;language-text&quot;&gt;(?P&amp;lt;name&gt;regex)&lt;/code&gt;형식으로 씁니다.&lt;/p&gt;
&lt;p&gt;이번에도 예시를 하나 살펴보겠습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;match_obj = re.match(
    r&amp;#39;(?P&amp;lt;year&amp;gt;\d{4})-(?P&amp;lt;month&amp;gt;\d\d)-(?P&amp;lt;day&amp;gt;\d\d) (?P=year)\.(?P=month)\.(?P=day)&amp;#39;,
    &amp;#39;2018-07-28 2018.07.28&amp;#39;)

print(match_obj.group())
print(match_obj.groups())
print(match_obj.group(1))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;결과&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;2018-07-28 2018.07.28
(&amp;#39;2018&amp;#39;, &amp;#39;07&amp;#39;, &amp;#39;28&amp;#39;)
2018&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이런 식으로 기존 비명명 방식은 그룹의 번호를 지정해줘야 됐지만, 명명그룹은 하나의 변수처럼 그룹을 정의해 재참조해가며 사용할 수 있습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;정규표현식: 치환&lt;/h3&gt;
&lt;p&gt;파이썬의 &lt;code class=&quot;language-text&quot;&gt;replace&lt;/code&gt;메서드는 정규식 패턴에 대응하는 문자열을 찾아주지 못합니다. 따라서 &lt;code class=&quot;language-text&quot;&gt;re.sub&lt;/code&gt;메서드가 필요합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; print(re.sub(pattern=&amp;#39;Gorio&amp;#39;, repl=&amp;#39;Ryan&amp;#39;, count=2, \
             string=&amp;#39;Gorio, Gorio, Gorio keep a straight face.&amp;#39;))
Ryan, Ryan, Gorio keep a straight face.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;re.sub&lt;/code&gt;메서드의 파라미터를 살펴보겠습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;pattern: 매치시킬 패턴 
repl: 변경할 문자
string: 적용 문자열
count: 치환개수(최대값)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;번외로 &lt;code class=&quot;language-text&quot;&gt;re.subn&lt;/code&gt;메서드는 치환된 문자열과 더불어 치환된 개수의 튜플을 반환합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;(&amp;#39;Ryan, Ryan, Gorio keep a straight face.&amp;#39;, 2)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;re.sub&lt;/code&gt;에 이전에 보았던 &lt;code class=&quot;language-text&quot;&gt;\(숫자)&lt;/code&gt;를 이용할 수도 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; print(re.sub(&amp;#39;(\d{4})-(\d{2})-(\d{2})&amp;#39;, 
             r&amp;#39;\1.\2.\3&amp;#39;,
             &amp;#39;1900-01-01&amp;#39;))
1900.01.01&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;yyyy-mm-dd 형식을 yyyy.mm.dd 형식으로 변경됐습니다. 비명명방식이 된다면 명명방식도 가능하겠죠??&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; print(re.sub(&amp;#39;(?P&amp;lt;year&amp;gt;\d{4})-(?P&amp;lt;month&amp;gt;\d{2})-(?P&amp;lt;day&amp;gt;\d{2})&amp;#39;,
             &amp;#39;\g&amp;lt;year&amp;gt;.\g&amp;lt;month&amp;gt;.\g&amp;lt;day&amp;gt;&amp;#39;,
             &amp;#39;1900-01-01&amp;#39;))
1900.01.01&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;정규표현식: split&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;re.sub&lt;/code&gt;말고도 유용한 함수인 &lt;code class=&quot;language-text&quot;&gt;re.split&lt;/code&gt;입니다. 이 메서드는 파이썬 문자열의 기본 메서드인 &lt;code class=&quot;language-text&quot;&gt;split&lt;/code&gt;과 매우 유사합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;&amp;gt;&amp;gt;&amp;gt; print(re.split(&amp;#39;&amp;lt;[^&amp;lt;&amp;gt;]*&amp;gt;&amp;#39;,
               &amp;#39;&amp;lt;html&amp;gt; Wow &amp;lt;head&amp;gt; header &amp;lt;/head&amp;gt; &amp;lt;body&amp;gt; Hey &amp;lt;/body&amp;gt; &amp;lt;/html&amp;gt;&amp;#39;))
[&amp;#39;&amp;#39;, &amp;#39; Wow &amp;#39;, &amp;#39; header &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; Hey &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;&amp;#39;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;정규식에 일치하는 부분을 기준으로 split이 되는 것을 볼 수 있습니다.&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;정규표현식: 연산을 섞은 치환&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;re.sub&lt;/code&gt;를 쓸 때 일치부에 나타나지도 않고, literal text에도 나타나지 않는 문자열로 치환하고 싶은 경우가 있을 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;re.sub&lt;/code&gt;는 인자 repl을 받을때 함수로도 받을 수 있습니다. 함수는 인자로 match 객체를 받으며 문자열을 반환해야 합니다.&lt;/p&gt;
&lt;p&gt;예를 들어 소수로 표현된 숫자를 찾은다음 퍼센티지로 변환하는 것을 정규식으로 써보겠습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;def convert_percentage(match_obj):
    number = float(match_obj.group())
    return str(number * 100) + &amp;#39;%&amp;#39;

print(re.sub(pattern=r&amp;#39;\b0\.\d+\b&amp;#39;,
             repl=convert_percentage,
             string=&amp;#39;Red 0.250, Green 0.001, Blue 0.749, Black 1.5&amp;#39;))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;결과&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;Red 25.0%, Green 0.1%, Blue 74.9%, Black 1.5&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;정규표현식: 조건문&lt;/h3&gt;
&lt;p&gt;정규표현식도 까다롭지만 조건문을 만들어 줄 수 있습니다. 정규표현식에서의 조건문은 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;조건문은, 캡처 그룹을 사용해 앞에서 문자열이 일치되었는지 아닌지에 따라 다음 부분에서는 다른 일치 조건을 제시해야 할 때 쓰입니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;angular2html&quot;&gt;&lt;pre class=&quot;language-angular2html&quot;&gt;&lt;code class=&quot;language-angular2html&quot;&gt;(?(숫자)맞으면|아니면)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;여기서 숫자는 캡처와 비슷합니다. 앞에서 재참조부를 쓸 때 &lt;code class=&quot;language-text&quot;&gt;\1&lt;/code&gt;과 같이 썼는데, 조건문에서는 단지 &lt;code class=&quot;language-text&quot;&gt;(1)&lt;/code&gt;로 바뀐 것입니다.&lt;/p&gt;
&lt;p&gt;예시로, &lt;code class=&quot;language-text&quot;&gt;(a)?b(?(1)c|d)&lt;/code&gt;를 살펴보겠습니다. 이건 &lt;code class=&quot;language-text&quot;&gt;abc|bd&lt;/code&gt;와 같습니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;먼저 &lt;code class=&quot;language-text&quot;&gt;a&lt;/code&gt;를 검사합니다. 만약 찾는 문자열에 ‘a’가 있으면 첫 번째 명시적 캡처에는 ‘a’가 들어가고, ‘a’가 없으면, 빈 문자열이 (1)에 저장됩니다.&lt;/li&gt;
&lt;li&gt;다음으로 &lt;code class=&quot;language-text&quot;&gt;b&lt;/code&gt;입니다. 만약 ‘b’가 없으면 정규식은 일치하지 않습니다. ‘b’가 있다고 가정하겠습니다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;(?(1)c|d)&lt;/code&gt; 이 조건문은 (1)에 값이 존재하면 c, 존재하지 않으면 d를 뜻합니다. 즉 a가 존재했었다면 &lt;code class=&quot;language-text&quot;&gt;abc&lt;/code&gt;가 완성되고, a가 존재하지 않았다면 &lt;code class=&quot;language-text&quot;&gt;bd&lt;/code&gt;가 완성됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;br&gt;
&lt;h1&gt;reference&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://greeksharifa.github.io/&quot;&gt;https://greeksharifa.github.io/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wikidocs.net/4308&quot;&gt;https://wikidocs.net/4308&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Streamlit]]></title><description><![CDATA[Streamlit The fastest way to build data apps in Python github repository: https://github.com/streamlit/streamlit tutorial: https://docs…]]></description><link>https://sooftware.github.io/streamlit/</link><guid isPermaLink="false">https://sooftware.github.io/streamlit/</guid><pubDate>Mon, 30 Aug 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Streamlit&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;The fastest way to build data apps in Python&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;img src=&quot;https://streamlit.io/images/brand/streamlit-logo-secondary-colormark-darktext.svg&quot; width=&quot;700&quot;&gt;
&lt;ul&gt;
&lt;li&gt;github repository: &lt;a href=&quot;https://github.com/streamlit/streamlit&quot;&gt;https://github.com/streamlit/streamlit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;tutorial: &lt;a href=&quot;https://docs.streamlit.io/en/stable/getting_started.html&quot;&gt;https://docs.streamlit.io/en/stable/getting_started.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;streamlit&lt;/code&gt;는 파이썬 기반으로 손쉽게 웹 어플리케이션을 개발하는 오픈소스입니다. 웹에 대한 이해 없이도 간단한 파이썬 코드만으로 대부분의 웹 어플리케이션 구현이 가능합니다. 간단한 데이터 Visualization 혹은 인공지능 모델 시연 등 여러 분야에 활용될 수 있을 것 같습니다.&lt;/p&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Install command&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ pip install streamlit
$ streamlit hello&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;  👋 Welcome to Streamlit!

  If you&apos;re one of our development partners or you&apos;re interested in getting
  personal technical support or Streamlit updates, please enter your email
  address below. Otherwise, you may leave the field blank.

  Email: sh951011@gmail.com

  Privacy Policy:
  As an open source project, we collect usage statistics. We cannot see and do
  not store information contained in Streamlit apps. You can find out more by
  reading our privacy policy at: https://streamlit.io/privacy-policy

  If you&apos;d like to opt out of usage statistics, add the following to
  ~/.streamlit/config.toml, creating that file if necessary:

    [browser]
    gatherUsageStats = false


  Welcome to Streamlit. Check out our demo in your browser.

  Local URL: http://localhost:8501
  Network URL: http://192.168.35.186:8501

  Ready to create your own Python apps super quickly?
  Head over to https://docs.streamlit.io

  May you create awesome apps!&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Get Started&lt;/h2&gt;
&lt;h3&gt;Create your first Streamlit app&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;first_app.py&lt;/code&gt;를  만들고 streamlit를 import 합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; streamlit &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; st
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; pandas &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; pd&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;pandas&lt;/code&gt;는 데이터프레임을 다루는 예시를 보여주기 위해 import 합니다.&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;st.write()&lt;/code&gt;을 사용합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;My first app&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;write&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Here&apos;s our first attempt at using data to create a table:&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;write&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pd&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;DataFrame&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;first column&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;second column&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;st.write()&lt;/code&gt;는 &lt;code class=&quot;language-text&quot;&gt;str&lt;/code&gt; 타입뿐만 아니라 &lt;code class=&quot;language-text&quot;&gt;pandas&lt;/code&gt;의 &lt;code class=&quot;language-text&quot;&gt;DataFrame&lt;/code&gt;도 손쉽게 write 할 수 있습니다.&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Run by streamlit&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ streamlit run first_app.py&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/132123087-47e303cc-bdaf-4550-ab4a-d802807c3cb9.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;여기까지만 해도 &lt;code class=&quot;language-text&quot;&gt;streamlit&lt;/code&gt;을 활용하면 상당히 편리하게 데이터를 보여줄 수 있습니다. 다음으로는 &lt;code class=&quot;language-text&quot;&gt;streamlit&lt;/code&gt;을 이용해서 데이터 visualization하는 방법에 대해 살펴보겠습니다.&lt;/p&gt;
&lt;h3&gt;Draw charts and maps&lt;/h3&gt;
&lt;p&gt;웹 어플리케이션에 bar chart, line chart, map을 추가하는 법을 대해 배워봅시다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Draw a line chart&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;파이썬에서는 &lt;code class=&quot;language-text&quot;&gt;matplotlib&lt;/code&gt;과 같은 라이브러리를 이용하면 쉽게 line chart를 그릴 수 있습니다만, 웹 어플리케이션에서 이런 이미지를 띄우려면 상황에 따라 복잡해질 수도 있습니다. 하지만 &lt;code class=&quot;language-text&quot;&gt;streamlit&lt;/code&gt;에서는 &lt;code class=&quot;language-text&quot;&gt;st.line_chart()&lt;/code&gt; 메서드로 편리하게 line chart를 추가할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;chart_data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pd&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;DataFrame&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
     np&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;randn&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
     columns&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;a&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;b&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;c&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;line_chart&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;chart_data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/132123628-b96bdf1c-caf1-4821-89ca-2a5ecaa9ee1a.png&quot; width=&quot;400&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Plot a map&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;지도 역시 마찬가지입니다. 노 베이스로 지도를 그린다면 굉장히 어려운 프로젝트입니다만, &lt;code class=&quot;language-text&quot;&gt;streamlit&lt;/code&gt;에서는 지도 역시 &lt;code class=&quot;language-text&quot;&gt;st.map()&lt;/code&gt; 메서드로 편리하게 지원합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;map_data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pd&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;DataFrame&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    np&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;randn&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;37.76&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;122.4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    columns&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;lat&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;lon&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;map_data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/132123664-f8b4cc20-99b2-4045-b9a7-188f7fed5b22.png&quot; width=&quot;400&quot;&gt;
&lt;h3&gt;Add interactivity with widgets&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;streamlit&lt;/code&gt;은 체크박스, 버튼, 슬라이더 등 여러 interactive 위젯 API를 제공합니다. &lt;code class=&quot;language-text&quot;&gt;streamlit&lt;/code&gt;에서 제공하는 모든 API는 &lt;a href=&quot;https://docs.streamlit.io/en/stable/api.html&quot;&gt;여기&lt;/a&gt;에서 확인할 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Checkbox show/hide data&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;st.checkbox()&lt;/code&gt;를 이용하면 체크박스를 이용해서 데이터 show/hide 설정을 할 수 있습니다. &lt;code class=&quot;language-text&quot;&gt;st.checkbox()&lt;/code&gt;는 위젯명을 argument로 받아서 처리합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;checkbox&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Show dataframe&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    chart_data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pd&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;DataFrame&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
       np&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;randn&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
       columns&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;a&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;b&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;c&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    chart_data&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/132123949-a1b434bb-4d28-4fa2-8431-9e88eb9ee372.png&quot; width=&quot;250&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Selectbox for options&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;st.selectbox()&lt;/code&gt;는 &lt;code class=&quot;language-text&quot;&gt;pandas.Series&lt;/code&gt;를 입력으로 받아서 옵션을 선택받게 할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; streamlit &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; st
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; pandas &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; pd

st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;TUNiBerse&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
option &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selectbox&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;당신의 직책을 선택해주세요.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
     pd&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Series&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;CEO&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;AI Engineer&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Intern&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Product Manager&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token string&quot;&gt;&apos;You selected: &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; option&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/132124085-9ebe7fe4-9e73-434b-82f0-d6e0c34d7c32.png&quot; width=&quot;600&quot;&gt;
&lt;h3&gt;Lay out your app&lt;/h3&gt;
&lt;p&gt;웹 어플리케이션을 구현할 때 중요한 점 중 하나를 레이아웃입니다. 어떻게 화면을 구성하냐에 따라서 더 깔끔하고 직관적이게 보일 수가 있습니다. &lt;code class=&quot;language-text&quot;&gt;streamlit&lt;/code&gt;은 이런 기능 또한 손쉽게 다룰 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Selectbox를 사이드로&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;방금 앞에서 했던 selectbox를 사이드로 옮기고 싶다면 어떻게 해야할까요? &lt;code class=&quot;language-text&quot;&gt;streamlit&lt;/code&gt;에서는 아래와 같이 간단하게 구현 가능합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; streamlit &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; st
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; pandas &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; pd

st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;TUNiBerse&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
option &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sidebar&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selectbox&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;당신의 직책을 선택해주세요.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
     pd&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Series&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;CEO&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;AI Engineer&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Intern&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Product Manager&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token string&quot;&gt;&apos;You selected: &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; option&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/132124325-2436bb57-85d4-4be4-b90a-41968ecce758.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;위와 같이 &lt;code class=&quot;language-text&quot;&gt;streamlit&lt;/code&gt;에서 제공하는 대부분의 element는 &lt;code class=&quot;language-text&quot;&gt;st.sidebar. [element_name]()&lt;/code&gt; 포맷으로 사용 가능합니다. 위의 위젯 외에도 button, expander 등 여러 위젯이 있으니 다양하게 사용해보시길 바랍니다.&lt;/p&gt;
&lt;h3&gt;Show progress&lt;/h3&gt;
&lt;p&gt;이번에는 웹페이지에 진행현황을 표시해봅시다. &lt;code class=&quot;language-text&quot;&gt;st.progress()&lt;/code&gt;를 이용하면 아래처럼 쉽게 사용이 가능합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; time

&lt;span class=&quot;token string&quot;&gt;&apos;Starting a long computation...&apos;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Add a placeholder&lt;/span&gt;
latest_iteration &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;empty&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
bar &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; st&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;progress&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;# Update the progress bar with each iteration.&lt;/span&gt;
  latest_iteration&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&apos;Iteration &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  bar&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;progress&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token string&quot;&gt;&apos;...and now we\&apos;re done!&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/132124609-1dc526b4-5e3c-438b-8e38-4374aa6739f2.png&quot; width=&quot;600&quot;&gt;
&lt;h2&gt;Share your app&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;streamlit&lt;/code&gt;으로 개발한 app은 &lt;strong&gt;Streamlit Cloud&lt;/strong&gt;로 deploy, manage, share가 모두 가능합니다. 현재 Streamlit Cloud는 초대를 받은 멤버에 한해서 사용이 가능합니다. &lt;a href=&quot;https://streamlit.io/sharing-sign-up&quot;&gt;Request an invite&lt;/a&gt;에 몇 가지 사항을 제출하고 사용해주시면 됩니다.&lt;/p&gt;
&lt;p&gt;다음 3 스텝으로 간단하게 구현 가능합니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Put your app in a public Github repo (and make sure it has a requirements.txt!)&lt;/li&gt;
&lt;li&gt;Sign into share.streamlit.io&lt;/li&gt;
&lt;li&gt;Click ‘Deploy an app’ and then paste in your GitHub URL&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title><![CDATA[2021 LangCon 발표 - "한국어 음성 인식: KoSpeech 개발기부터 OpenSpeech 개발기까지"]]></title><description><![CDATA[2021 LangCon 발표 - “한국어 음성 인식: KoSpeech 개발기부터 OpenSpeech 개발기까지” 올해로 3회째를 맞는 LangCon에 발표자로 참석해 “한국어 음성 인식: KoSpeech 개발기부터 OpenSpeech…]]></description><link>https://sooftware.github.io/langcon_2021/</link><guid isPermaLink="false">https://sooftware.github.io/langcon_2021/</guid><pubDate>Sat, 28 Aug 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;2021 LangCon 발표 - “한국어 음성 인식: KoSpeech 개발기부터 OpenSpeech 개발기까지”&lt;/h1&gt;
&lt;div class=&quot;gatsby-resp-iframe-wrapper&quot; style=&quot;padding-bottom: 56.25%; position: relative; height: 0; overflow: hidden; margin-bottom: 1rem&quot; &gt; &lt;iframe src=&quot;https://www.youtube.com/embed/OglqDo44zpQ&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot; style=&quot; position: absolute; top: 0; left: 0; width: 100%; height: 100%; &quot;&gt;&lt;/iframe&gt; &lt;/div&gt;
&lt;p&gt;올해로 3회째를 맞는 LangCon에 발표자로 참석해 “한국어 음성 인식: KoSpeech 개발기부터 OpenSpeech 개발기까지”라는 주제로 발표를 했습니다.&lt;/p&gt;
&lt;p&gt;LangCon은 ‘학생’부터 ‘현장 전문가’까지 자연어처리에 관심 있는 모든 사람들이 모여 연구 경과를 발표하고 얘기를 나누는 축제입니다.&lt;/p&gt;
&lt;p&gt;여느 학회 발표와 달리, ‘경험’의 유무, ‘남녀’, ‘문/이과’와 같은 여러 장벽을 허물고 오픈 소스의 정신을 나누고자 하는 행사인데요, 올해는 3회째를 맞이했습니다.&lt;/p&gt;
&lt;p&gt;올해는 Covid 시대를 맞아 지난 8월 28일 온라인으로 열렸습니다.&lt;/p&gt;
&lt;p&gt;저를 비롯해 저희 튜닙에서는 발표자로 고현웅님과 패널로 대표님인 박규병님이 행사에 참석했습니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[판교 AI Camp 프로그램 발표]]></title><description><![CDATA[판교 AI Camp 프로그램 발표 지난 8월 28일 있었던 판교 AI Camp 프로그램 에서 발표자로 나서 인공지능경진대회 1위 수상의 노하우를 공유했습니다.]]></description><link>https://sooftware.github.io/판교_ai_camp/</link><guid isPermaLink="false">https://sooftware.github.io/판교_ai_camp/</guid><pubDate>Sat, 28 Aug 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;판교 AI Camp 프로그램 발표&lt;/h1&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134294289-a9c8d63c-4aee-456c-9987-fdc8df3aafe0.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;지난 8월 28일 있었던 &lt;a href=&quot;https://m.khan.co.kr/local/Gyeonggi/article/202108201121001&quot;&gt;판교 AI Camp 프로그램&lt;/a&gt; 에서 발표자로 나서 인공지능경진대회 1위 수상의 노하우를 공유했습니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Hugging Face Tokenizers]]></title><description><![CDATA[최근 NLP 토크나이저를 만드는데 가장 많이 사용되는  라이브러와 실제 사용이 가장 많이 되는  라이브러리로의 변환에 대한 코드를 담고 있습니다. 해당 내용은  버젼에서 수행되었습니다. Train 아래 코드는 wordpiece, char-bpe…]]></description><link>https://sooftware.github.io/tokenizers/</link><guid isPermaLink="false">https://sooftware.github.io/tokenizers/</guid><pubDate>Wed, 11 Aug 2021 15:11:55 GMT</pubDate><content:encoded>&lt;p&gt;최근 NLP 토크나이저를 만드는데 가장 많이 사용되는 &lt;code class=&quot;language-text&quot;&gt;tokenizers&lt;/code&gt; 라이브러와 실제 사용이 가장 많이 되는 &lt;code class=&quot;language-text&quot;&gt;transformers&lt;/code&gt; 라이브러리로의 변환에 대한 코드를 담고 있습니다. 해당 내용은 &lt;code class=&quot;language-text&quot;&gt;tokenizers==0.10.3&lt;/code&gt; 버젼에서 수행되었습니다.&lt;/p&gt;
&lt;h3&gt;Train&lt;/h3&gt;
&lt;p&gt;아래 코드는 wordpiece, char-bpe, byte-level bpe 방식을 지원합니다.&lt;br&gt;
센텐스피스의 경우 tokenizers에는 현재 sentencepiece가 불안정하여, 오리지널 sentencepiece 학습 방식으로 학습 후 &lt;code class=&quot;language-text&quot;&gt;tokenizers.SentencePieceUnigramTokenizer.from_spm()&lt;/code&gt; 메서드로 로드하는 방식을 사용하셔야 합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;code&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; argparse
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; tokenizers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    BertWordPieceTokenizer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ByteLevelBPETokenizer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    CharBPETokenizer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    SentencePieceUnigramTokenizer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

parser &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; argparse&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ArgumentParser&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_argument&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;--corpus_file&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; required&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_argument&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;--vocab_size&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; default&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; required&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_argument&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;--limit_alphabet&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; default&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_argument&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;--tokenizer&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; default&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;sentencepiece&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_argument&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;--model_type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; default&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;gpt&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_argument&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;--save_dir&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; default&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;sp&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
args &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parse_args&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model_type &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;bert&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    special_tokens &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;|sos|&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;|eos|&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;|pad|&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;|unk|&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;|mask|&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;|sep|&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;|cls|&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model_type &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;gpt&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    special_tokens &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;|endoftext|&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;|unk|&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; ValueError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;Unsupported model type: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model_type&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lower&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;wordpiece&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    tokenizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; BertWordPieceTokenizer&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        clean_text&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        handle_chinese_chars&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        strip_accents&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        lowercase&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        wordpieces_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;##&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;train&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;files&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;corpus_file&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; limit_alphabet&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;limit_alphabet&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; vocab_size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vocab_size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lower&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;bbpe&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    tokenizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ByteLevelBPETokenizer&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        lowercase&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        add_prefix_space&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        unicode_normalizer&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;nfc&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;train&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        files&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;corpus_file&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        vocab_size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vocab_size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        special_tokens&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;special_tokens&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lower&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;char-bpe&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    tokenizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; CharBPETokenizer&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        lowercase&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        add_prefix_space&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        unicode_normalizer&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;nfc&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;train&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        files&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;corpus_file&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        vocab_size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vocab_size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        special_tokens&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;special_tokens&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; ValueError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Error&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exists&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;save_dir&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mkdir&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;save_dir&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;save&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;tokenizer.json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Convert to transformers tokenizer&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;tokenizers&lt;/code&gt; 라이브러리로 학습한 토크나이저는 아래 코드로 간단하게 &lt;code class=&quot;language-text&quot;&gt;transformers&lt;/code&gt; 토크나이저로 변환이 가능합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python3&quot;&gt;&lt;pre class=&quot;language-python3&quot;&gt;&lt;code class=&quot;language-python3&quot;&gt;from transformers import PreTrainedTokenizerFast

tokenizer = PreTrainedTokenizerFast(tokenizer_file=&amp;#39;tokenizer.json&amp;#39;)
tokenizer.save_pretrained(&amp;#39;SAVE_DIR&amp;#39;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;sentencepiece&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; sentencepiece &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; spm

SENTENCEPIECE_MODEL_PREFIX &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;SP&quot;&lt;/span&gt;
SENTENCEPIECE_MODEL_TYPE &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;unigram&quot;&lt;/span&gt;

spm&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SentencePieceTrainer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Train&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;--input=sentencepiece_input.txt &quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;--model_prefix=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;SENTENCEPIECE_MODEL_PREFIX&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; &quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;--vocab_size=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;vocab_size&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; &quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;--model_type=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;SENTENCEPIECE_MODEL_TYPE&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; &quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;--pad_id=0 &quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;--bos_id=1 &quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;--eos_id=2 &quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;--unk_id=3 &quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;--user_defined_symbols=[SEP],[CLS],[MASK]&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Add post process&lt;/h3&gt;
&lt;p&gt;토크나이저를 만들게 되면 따로 설정해주지 않으면 아래와 같은 형태로 토크나이징이 진행됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;code&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; transformers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; AutoTokenizer

tokenizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AutoTokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SAVE_DIR&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tokenize&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;튜닙은 자연어처리 테크 스타트업이다.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;output&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[&apos;▁&apos;, &apos;튜&apos;, &apos;닙&apos;, &apos;은&apos;, &apos;▁자연&apos;, &apos;어&apos;, &apos;처&apos;, &apos;리&apos;, &apos;▁테&apos;, &apos;크&apos;, &apos;▁&apos;, &apos;스타&apos;, &apos;트&apos;, &apos;업&apos;, &apos;이다.&apos;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;보통 버트나 일렉트라 같은 모델들은 파인튜닝의 편리함을 위해 아래와 같은 포맷으로 문장이 토크나이징 됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[&apos;[CLS]&apos;, &apos;▁&apos;, &apos;튜&apos;, &apos;닙&apos;, &apos;은&apos;, &apos;▁자연&apos;, &apos;어&apos;, &apos;처&apos;, &apos;리&apos;, &apos;▁테&apos;, &apos;크&apos;, &apos;▁&apos;, &apos;스타&apos;, &apos;트&apos;, &apos;업&apos;, &apos;이다.&apos;, &apos;[SEP]&apos;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이러한 포맷으로 자동으로 토크나이징 해주기 위해서는 &lt;code class=&quot;language-text&quot;&gt;post_processor&lt;/code&gt;를 추가해주면 됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;code&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; tokenizers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; SentencePieceUnigramTokenizer
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; tokenizers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;processors &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; TemplateProcessing
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; transformers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; PreTrainedTokenizerFast
        
tokenizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; SentencePieceUnigramTokenizer&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;vocab&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;      

&lt;span class=&quot;token comment&quot;&gt;# &apos;[CLS] SENTENCE [SEP]&apos; format&lt;/span&gt;
tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;post_processor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; TemplateProcessing&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    single&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;[CLS] $A [SEP]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    pair&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;[CLS] $A [SEP] $B:1 [SEP]:1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    special_tokens&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;[CLS]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;token_to_id&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;[CLS]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;[SEP]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;token_to_id&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;[SEP]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

tokenizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; PreTrainedTokenizerFast&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tokenizer_object&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;tokenizer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;save_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SAVE_DIR&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이렇게 저장한 &lt;code class=&quot;language-text&quot;&gt;transformers&lt;/code&gt; 토크나이저를 아까와 똑같이 로드해서 사용해주면 버트 포맷의 인풋으로 토크나이징 됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;code&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; transformers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; AutoTokenizer

tokenizer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AutoTokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SAVE_DIR&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
tokenizer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tokenize&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;튜닙은 자연어처리 테크 스타트업이다.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;output&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[&apos;[CLS]&apos;, &apos;▁&apos;, &apos;튜&apos;, &apos;닙&apos;, &apos;은&apos;, &apos;▁자연&apos;, &apos;어&apos;, &apos;처&apos;, &apos;리&apos;, &apos;▁테&apos;, &apos;크&apos;, &apos;▁&apos;, &apos;스타&apos;, &apos;트&apos;, &apos;업&apos;, &apos;이다.&apos;, &apos;[SEP]&apos;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Efficient Attention Paper Review]]></title><description><![CDATA[Efficient Attention: Attention with Linear Complexities Shen Zhuoran et al. Abstract Dot-product attention은 들어오는 인풋 길이에 따라 memory…]]></description><link>https://sooftware.github.io/efficient-attention/</link><guid isPermaLink="false">https://sooftware.github.io/efficient-attention/</guid><pubDate>Sat, 17 Jul 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Efficient Attention: Attention with Linear Complexities&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Shen Zhuoran et al.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Dot-product attention은 들어오는 인풋 길이에 따라 memory &amp;#x26; computation cost가 quadratically하게 증가함&lt;/li&gt;
&lt;li&gt;어텐션 매커니즘을 조금 수정해서 memory &amp;#x26; computation cost를 상당히 줄이는 방법 제안&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Method&lt;/h2&gt;
&lt;img src=&quot;https://www.pragmatic.ml/content/images/2020/06/image-13.png&quot;&gt;
&lt;ul&gt;
&lt;li&gt;기존 Dot-product로 similarty를 구하는 방식과 다르게, Key와 value를 곱하는 방식 사용&lt;/li&gt;
&lt;li&gt;Dot-product:&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/121996703-0da3ac80-cde4-11eb-9870-e710b6b13c53.png&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Efficient:&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/121996782-2f9d2f00-cde4-11eb-8c73-823f775a42f7.png&quot;&gt;
&lt;h2&gt;Experiment&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/121996832-4774b300-cde4-11eb-8050-b0f7e00f343d.png&quot;&gt;
&lt;ul&gt;
&lt;li&gt;기존 attention과 제안된 attention 비교 =&gt; 상당히 효율적으로 변한것을 확인 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/121997009-90c50280-cde4-11eb-9387-4b4819fcb251.png&quot;&gt;
&lt;ul&gt;
&lt;li&gt;성능 면에서도 더 좋은 결과가 나왔다는 표&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[2021 AI 온라인 경진대회 1위 후기 발표]]></title><description><![CDATA[2021 AI 온라인 경진대회 1위 노하우 발표 이번에 참가한 2021 AI 온라인 경진대회 - 노인 대화 감성 분석 트랙 1위 노하우에 대해 구글밋으로 발표했습니다. 관심 있으신 분들은 위 링크로 접속하셔서 보시면 됩니다 :)]]></description><link>https://sooftware.github.io/2021_ai_online_competition_/</link><guid isPermaLink="false">https://sooftware.github.io/2021_ai_online_competition_/</guid><pubDate>Thu, 15 Jul 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;2021 AI 온라인 경진대회 1위 노하우 발표&lt;/h1&gt;
&lt;div class=&quot;gatsby-resp-iframe-wrapper&quot; style=&quot;padding-bottom: 56.25%; position: relative; height: 0; overflow: hidden; margin-bottom: 1rem&quot; &gt; &lt;iframe src=&quot;https://www.youtube.com/embed/aKKDvdel5O4&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot; style=&quot; position: absolute; top: 0; left: 0; width: 100%; height: 100%; &quot;&gt;&lt;/iframe&gt; &lt;/div&gt;
&lt;p&gt;이번에 참가한 2021 AI 온라인 경진대회 - 노인 대화 감성 분석 트랙 1위 노하우에 대해 구글밋으로 발표했습니다.&lt;/p&gt;
&lt;p&gt;관심 있으신 분들은 위 링크로 접속하셔서 보시면 됩니다 :)&lt;/p&gt;</content:encoded></item><item><title><![CDATA[2021 AI 온라인 경진대회 1위]]></title><description><![CDATA[2021 AI 온라인 경진대회 1위 이번에 열린 2021 인공지능 온라인 경진대회 대화 감성 분류 태스크에 회사 대표로 참가 Public / Private / Final 리더보드에서 모두…]]></description><link>https://sooftware.github.io/2021_ai_online_competition/</link><guid isPermaLink="false">https://sooftware.github.io/2021_ai_online_competition/</guid><pubDate>Mon, 12 Jul 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;2021 AI 온라인 경진대회 1위&lt;/h1&gt;
&lt;img src=&quot;https://aihub.or.kr/sites/default/files/inline-images/2021%20%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5%20%EC%98%A8%EB%9D%BC%EC%9D%B8%20%EA%B2%BD%EC%A7%84%EB%8C%80%ED%9A%8C_%ED%8F%AC%EC%8A%A4%ED%84%B0%5B%EC%B5%9C%EC%A2%85%5D.jpg&quot; width=&quot;400&quot;&gt;
&lt;p&gt;이번에 열린 2021 인공지능 온라인 경진대회 대화 감성 분류 태스크에 회사 대표로 참가 Public / Private / Final 리더보드에서 모두 1위를 기록했습니다.  🎉 🎉&lt;/p&gt;
&lt;img src=&quot;https://scontent-gmp1-1.xx.fbcdn.net/v/t1.6435-9/207960577_2961737444070510_5324504568877735835_n.jpg?_nc_cat=103&amp;amp;ccb=1-5&amp;amp;_nc_sid=8bfeb9&amp;amp;_nc_ohc=928vWdPoSNsAX8QP_is&amp;amp;_nc_ht=scontent-gmp1-1.xx&amp;amp;oh=d4024e0788f8bbce0556445927021c6e&amp;amp;oe=616EF7B0&quot; width=&quot;600&quot;&gt;
&lt;p&gt;회사 대표님인 박규병님과 라이징 스타 고현웅님이 제 디스커션 파트너로 참여해주셨고, 학습 및 대회 진행은 저 혼자 진행했습니다.&lt;/p&gt;
&lt;p&gt;사업화와 관련이 있고 우수기업 선정시 최소 1억에서 최대 3억까지 지원해주는 큰 컴피티션이였기 때문에 약 10일 정도의 대회 기간 동안 대회에 몰입해서 임했습니다.&lt;/p&gt;
&lt;p&gt;해당 대회 종료 후 1위 노하우에 대해 발표했습니다. 해당 내용은 아래 링크에서 확인하실 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=aKKDvdel5O4&amp;#x26;t=1168s&quot;&gt;https://www.youtube.com/watch?v=aKKDvdel5O4&amp;#x26;t=1168s&lt;/a&gt;&lt;/p&gt;
&lt;img src=&quot;https://tunib.notion.site/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F39314fcb-c739-42e5-8479-f39650b2efae%2FiOS_%EC%9D%B4%EB%AF%B8%EC%A7%80.jpg?table=block&amp;amp;id=cdb4f535-efb8-49b7-902b-4bc10097ca72&amp;amp;spaceId=d2222c9a-a58e-4735-80fc-abd873fd9b70&amp;amp;width=3070&amp;amp;userId=&amp;amp;cache=v2&quot; width=&quot;500&quot;&gt;</content:encoded></item><item><title><![CDATA[[REVIEW] 크래프톤웨이 (Krafton Way)]]></title><description><![CDATA[[REVIEW] 크래프톤웨이 (Krafton Way) 배틀그라운드, 테라 등의 게임개발사로 유명한 KRAFTON…]]></description><link>https://sooftware.github.io/krafton/</link><guid isPermaLink="false">https://sooftware.github.io/krafton/</guid><pubDate>Sat, 10 Jul 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;[REVIEW] 크래프톤웨이 (Krafton Way)&lt;/h1&gt;
&lt;p&gt;배틀그라운드, 테라 등의 게임개발사로 유명한 KRAFTON의 창업부터 지금까지의 성공과정이 있기까지의 과정을 글로 담은 책이다.&lt;/p&gt;
&lt;p&gt;지금 나도 공동창업자로 스타트업 씬에 몸담고 있는 상황이여서 그런지 재밌게 읽히면서도 배울 점이 많이 보이고 스스로 반성도 많이 하게 된다.&lt;/p&gt;
&lt;p&gt;한 스타트업이 어떻게 창업이 되고, 성공이 어떻게 다가오는지를 간접적으로 느낄 수 있었다. 내가 몸담고 있는 TUNiB이 크래프톤 같이 성공하는걸 꿈꾸며 설레는 감정이 다가온다.&lt;/p&gt;
&lt;p&gt;크래프톤이 어떻게 성공까지 갈 수 있었는지를 생각해보면.. 잘 모르겠다. 그냥 미친 능력을 가진 리더의 등장(?)이 주요 요인이라고 생각된다.&lt;br&gt;
그리고 기존에 있던 회사 규칙 등은 오히려 이 미친 능력의 리더 발목을 잡는 것 같다는 느낌을 받았다.&lt;br&gt;
역시 실제 세상은 드라마나 영화보다 훨씬 복잡하다.&lt;/p&gt;
&lt;p&gt;IT 스타트업에 몸담고 계시거나 관심이 있으신분, IT 창업을 생각하시는 분들이라면 꼭 읽어보시길 추천드립니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Luna: Linear Unified Nested Attention]]></title><description><![CDATA[Luna: Linear Unified Nested Attention USC + CMU + Facebook AI 2021.06 code Abstract 트랜스포머의 Multi Headed Self Attention…]]></description><link>https://sooftware.github.io/luna/</link><guid isPermaLink="false">https://sooftware.github.io/luna/</guid><pubDate>Sat, 03 Jul 2021 23:46:37 GMT</pubDate><content:encoded>&lt;h1&gt;Luna: Linear Unified Nested Attention&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;USC + CMU + Facebook AI&lt;/li&gt;
&lt;li&gt;2021.06&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/XuezheMax/fairseq-apollo&quot;&gt;code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;트랜스포머의 Multi Headed Self Attention은 시퀀스가 길어질수록 메모리, 시간복잡도가 quadratic함&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이를 linear하게 바꾸기 위한 시도로 Luna (Linear Unified Nested Attention) 을 제안&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;핵심은 인풋을 고정 길이로 변환한다는 점과 attention을 2개로 분리한다는 점.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Positional Embedding을 별도의 고정 길이 query로 뺌.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;속도는 Performer랑 비슷한데 시퀀스가 길어질수록 좀 더 효과적이고 메모리도 적게 쓴다고 함.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;정확도 성능은 경쟁력이 높은 편.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Attention&lt;/h2&gt;
&lt;h3&gt;Traditional attention mechanism:&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/127510622-5af08d8d-771c-4bb9-8e9e-53bb3f4cf85e.png&quot; height=&quot;70&quot;&gt;
&lt;ul&gt;
&lt;li&gt;X: Query sequence, C: Context sequence&lt;/li&gt;
&lt;li&gt;ω: activation function (usually softmax)&lt;/li&gt;
&lt;li&gt;Q = XW&lt;sub&gt;Q&lt;/sub&gt;, K = CW&lt;sub&gt;K&lt;/sub&gt;, V = CW&lt;sub&gt;V&lt;/sub&gt;&lt;/li&gt;
&lt;li&gt;Self attention에서는 X == C&lt;/li&gt;
&lt;li&gt;공간 &amp;#x26; 시간복잡도: O(nm) (n: X의 시퀀스 길이, m: C의 시퀀스 길이)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Linear Unified Nested Attention (LUNA)&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/127514004-0ca02332-8ef5-4563-b9b4-bd9bf6bb72b9.png&quot; height=&quot;400&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Goal: Attention mechanism’s complexity &lt;strong&gt;quadratic =&gt; linear&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Luna (Pack and Unpack Attention)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;이 어텐션의 핵심은 어텐션을 2개로 쪼개는 것.&lt;/li&gt;
&lt;li&gt;O(ln) (l은 P의 길이)&lt;/li&gt;
&lt;li&gt;Pack Attention:
&lt;ul&gt;
&lt;li&gt;Query를 learnable paramter인 P로 대체 (고정 길이, 길이에 대한 실험 있음)&lt;/li&gt;
&lt;li&gt;상대적으로 더 짧은 Query를 놓음으로써 complexity를 줄임&lt;/li&gt;
&lt;li&gt;P-contextual: 첫 레이어의 P는 learnable parameter이며 다음 레이어로 전달&lt;/li&gt;
&lt;li&gt;P-non-contextual: 각 레이어마다 P를 학습하고 다음 레이어로 넘기지 않음&lt;/li&gt;
&lt;li&gt;contextual &amp;#x26; non-contextual에 대한 실험은 뒤에 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/127603299-44234ff8-1735-4dc2-95b0-bc8f66bfbbde.png&quot; height=&quot;60&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Unpack Attention:
&lt;ul&gt;
&lt;li&gt;Pack Attention의 결과인 &lt;code class=&quot;language-text&quot;&gt;packed context&lt;/code&gt;를 Key와 Value로 사용. Query는 기존 query.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/127603352-dfb741df-ec40-4b49-8bdf-b158e55b771e.png&quot; height=&quot;70&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Luna Attention:&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/127603409-554fa551-e89d-46ee-aec4-9a471a5cdc8f.png&quot; height=&quot;70&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Luna Layer&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/127603246-192380b0-fde6-4941-b060-1bf639d3b8e7.png&quot; height=&quot;100&quot;&gt;
&lt;h2&gt;Discussion&lt;/h2&gt;
&lt;h3&gt;Relation to Linformer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Linformer와 비슷한 포지션. 그럼 뭐가 더 나은가?
&lt;ul&gt;
&lt;li&gt;Linformer는 인풋 시퀀스가 모두 고정 길이를 가져야하는데, Luna는 various length가 가능 (projection matrix 때문에 linformer는 길이가 고정이여야함)&lt;/li&gt;
&lt;li&gt;결정적으로 Linformer보다 성능이 좋음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Experiment&lt;/h2&gt;
&lt;h3&gt;Long-Context Sequence Modeling&lt;/h3&gt;
&lt;h4&gt;&lt;strong&gt;Score&lt;/strong&gt;&lt;/h4&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/127603947-40c6b9f0-63d7-475c-8b6d-cefdfbe5ab59.png&quot; height=&quot;500&quot;&gt;
&lt;h4&gt;&lt;strong&gt;Training Speed &amp;#x26; Memory&lt;/strong&gt;&lt;/h4&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/127604072-79facf8c-7f84-4e9d-bd1e-38b3322458d0.png&quot; height=&quot;500&quot;&gt;
&lt;ul&gt;
&lt;li&gt;인풋 길이가 길어지면 Luna가 Linformer보다 더 빠름&lt;/li&gt;
&lt;li&gt;메모리 사용량에서 Luna가 Linformer를 포함한 다른 모델들보다 경쟁력이 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;NLU Task (Masked Language Modeling for Large-Scale Pretraining)&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/127604344-7074edf7-ede2-4140-a6e8-320ed711d5f3.png&quot; height=&quot;300&quot;&gt;
&lt;ul&gt;
&lt;li&gt;BERT 방식으로 pre-training 후 파인튜닝 했을 때 성능 비교&lt;/li&gt;
&lt;li&gt;RoBERTa와도 비견될만큼 좋은 성능을 보임&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Machine Translation&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/127604608-822e1fd6-00a1-472b-801e-24cda16efa5f.png&quot; height=&quot;250&quot;&gt;
&lt;h3&gt;Abbrebiation Study (contextual &amp;#x3C;-&gt; non-contextual)&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/127604743-ae8289cc-d420-41b0-9ff1-5604ef770b4c.png&quot; height=&quot;150&quot;&gt;
&lt;ul&gt;
&lt;li&gt;P를 각 레이어의 파라미터로 둘지, 위층으로 넘김으로써 context 정보를 넘겨줄지에 대한 실험&lt;/li&gt;
&lt;li&gt;결론: 다음 층으로 넘겨주는게 좋더라.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Ray: multi-processing library]]></title><description><![CDATA[Ray: multi-processing library…]]></description><link>https://sooftware.github.io/ray/</link><guid isPermaLink="false">https://sooftware.github.io/ray/</guid><pubDate>Sat, 03 Jul 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Ray: multi-processing library&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;ray&lt;/code&gt;는 파이썬 멀티프로세싱 라이브러리입니다. 파이썬에서 기본적으로 제공되는 &lt;code class=&quot;language-text&quot;&gt;multiprocessing&lt;/code&gt; 라이브러리가 있지만,
그보다 더 간단하고 더 빠른 멀티프로세싱을 제공하기 위해 제작되고 있는 오픈소스 프로젝트입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ray&lt;/code&gt;는 cpu 수가 많은 환경일수록 더 빠르다고 알려져 있음&lt;/li&gt;
&lt;li&gt;로컬 환경, 클라우드의 쿠버네티스(AWS, GCP, Azure) 환경, 온프레미스 쿠버네티스 등 다양한 환경에서 사용할 수 있음&lt;/li&gt;
&lt;li&gt;사용법이 쉬&lt;/li&gt;
&lt;li&gt;프로젝트 링크: &lt;a href=&quot;https://github.com/ray-project/ray&quot;&gt;https://github.com/ray-project/ray&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ pip install ray&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Quick Start&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;ray&lt;/code&gt;는 아래 코드와 같이 간단하게 사용 가능합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; ray
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; psutil

num_workers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; psutil&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cpu_count&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
ray&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;num_cpus&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;num_workers&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@ray&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;remote&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; x

futures &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;remote&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ray&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;futures&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 코드와 같이 기존 함수를 &lt;code class=&quot;language-text&quot;&gt;@ray.remote&lt;/code&gt; 데코레이터로 감싸고 호출시 [FUNC_NAME].remote()로 호출하면 됩니다.&lt;br&gt;
주의할 점은 &lt;code class=&quot;language-text&quot;&gt;remote()&lt;/code&gt; 호출 이후 &lt;code class=&quot;language-text&quot;&gt;get()&lt;/code&gt;을 꼭 호출해야 원하는 결과값을 얻을 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;주의할 점&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;get()&lt;/code&gt; 호출은 최대한 적게하는 것이 좋습니다. for문 안에서 &lt;code class=&quot;language-text&quot;&gt;remote()&lt;/code&gt; 호출 할때마다 &lt;code class=&quot;language-text&quot;&gt;get()&lt;/code&gt;을 호출하게 되면 프로그램 실행속도가 상당히 느려지게 됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;이 외에오 ray 대쉬보드, class에서의 ray 사용 등 다룰 것은 많지만 개인적으로 함수를 데코레이터로 감싸서 쓰는 방식이 가장 간단하면서 쓰임이 좋아서 여기까지만 작성하겠습니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware ML - wandb (Weight & Bias)]]></title><description><![CDATA[wandb (Weight & Bias) image  는 Tensorboard와 같이 log를 보기 쉽게 시각화해주는 툴입니다. Tensorflow, PyTorch, transformers, PyTorch-Lightning…]]></description><link>https://sooftware.github.io/wandb/</link><guid isPermaLink="false">https://sooftware.github.io/wandb/</guid><pubDate>Sun, 13 Jun 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;wandb (Weight &amp;#x26; Bias)&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/122323318-e1ae3580-cf61-11eb-9db2-64e978b459cf.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://wandb.ai/site&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;wandb&lt;/code&gt;&lt;/a&gt; 는 Tensorboard와 같이 log를 보기 쉽게 시각화해주는 툴입니다.&lt;br&gt;
Tensorflow, PyTorch, transformers, PyTorch-Lightning 등 다양한 프레임워크와 함께 사용 가능한 것이 특징입니다.&lt;/p&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Command&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;wandb&lt;/code&gt;는 pip으로 손쉽게 설치 가능합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ pip install wandb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Login&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;wandb&lt;/code&gt;를 사용하기 위해서는 wandb 아이디로 로그인을 해주어야 합니다.&lt;br&gt;
웹사이트 기반으로 로그가 관리되기 때문입니다.&lt;br&gt;
회원가입을 해야한다는 불편함이 있지만 진행한 프로젝트들 로그가 한 아이디에서 관리된다는 장점도 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ wandb login
wandb: You can find your API key in your browser here: https://app.wandb.ai/authorize
wandb: Paste an API key from your profile and hit enter:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위와 같이 &lt;code class=&quot;language-text&quot;&gt;wandb login&lt;/code&gt; 명령어를 실행하면 login을 위한 API Key를 입력하라고 나옵니다.&lt;br&gt;
해당 링크를 타고 들어가면 API Key를 받을 수 있습니다. (ID가 없다면 회원가입을 하고 진행하시면 됩니다.)&lt;/p&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;wandb&lt;/code&gt;는 다음과 같이 쉽게 사용 가능합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PyTorch&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; wandb

&lt;span class=&quot;token comment&quot;&gt;# 1. Start a new run&lt;/span&gt;
wandb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;project&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gpt-3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 2. Save model inputs and hyperparameters&lt;/span&gt;
config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; wandb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;config
config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;learning_rate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.01&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 3. Log gradients and model parameters&lt;/span&gt;
wandb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;watch&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; batch_idx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;train_loader&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; batch_idx &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;log_interval &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# 4. Log metrics to visualize performance&lt;/span&gt;
        wandb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;log&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;loss&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; loss&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Huggingface&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 1. Import wandb and login&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; wandb

wandb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;login&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 2. Define which wandb project to log to and name your run&lt;/span&gt;
wandb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;project&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gpt-3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; run_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;gpt-3-base-high-lr&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 3. Add wandb in your Hugging Face `TrainingArguments`&lt;/span&gt;
args &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; TrainingArguments&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; report_to&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;wandb&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 4. W&amp;amp;B logging will begin automatically when your start training your Trainer&lt;/span&gt;
trainer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Trainer&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; args&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
trainer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;train&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Tensorflow&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; wandb

&lt;span class=&quot;token comment&quot;&gt;# 1. Start a W&amp;amp;B run&lt;/span&gt;
wandb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;init&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;project&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;gpt3&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 2. Save model inputs and hyperparameters&lt;/span&gt;
config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; wandb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;config
config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;learning_rate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.01&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Model training here&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# 3. Log metrics over time to visualize performance&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; tf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Session&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; sess&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
wandb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tensorflow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;log&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;summary&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;merge_all&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;PyTorch Lightning&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; pytorch_lightning&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;loggers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; WandbLogger  &lt;span class=&quot;token comment&quot;&gt;# newline 1&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; pytorch_lightning &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Trainer

wandb_logger &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; WandbLogger&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# newline 2&lt;/span&gt;
trainer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Trainer&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;logger&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;wandb_logger&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - P-Tuning Paper Review]]></title><description><![CDATA[GPT Understands, Too Xiao Liu et al. Tsinghua University etc. arXiv pre-print Abstract GPT를 파인튜닝하는 방법은 Narural Language Understanding (NLU…]]></description><link>https://sooftware.github.io/p_tuning/</link><guid isPermaLink="false">https://sooftware.github.io/p_tuning/</guid><pubDate>Thu, 13 May 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;GPT Understands, Too&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Xiao Liu et al.&lt;/li&gt;
&lt;li&gt;Tsinghua University etc.&lt;/li&gt;
&lt;li&gt;arXiv pre-print&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GPT를 파인튜닝하는 방법은 Narural Language Understanding (NLU) 태스크쪽에서 좋지 않은 결과를 보임&lt;/li&gt;
&lt;li&gt;P-tuning을 이용해서 GPT로 비슷한 사이즈의 BERT와 비슷 or 웃도는 성능을 기록 (Vanilla 대비 20%이상 성능 향상)&lt;/li&gt;
&lt;li&gt;P-tuning은 BERT 성능도 향상시킴&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Language model pre-training은 contextualized text reporesentation 뿐만 아니라 grammar, syntactic, commonsense, world knowledge까지 학습이 된다고 주장하는 연구 결과들이 있음.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Language model pre-training은 다음 3가지 (uni-directional language models (e.g., GPT), bidirectional language models (e.g., BERT), hybrid language models (e.g., XLNet))로 나눌 수 있음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;오래동안 GPT 스타일은 NLU 태스크에 적합하지 않다고 여겨져 왔음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;GPT3는 적절한 프롬프트를 이용해서 NLU 태스크를 풀 수 있지만, 매번 좋은 프롬프트를 바로바로 찾는건 현실적으로 힘들다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;automatic prompt searching (retrieval 등) 같이 discrete prompts를 찾는 방법들이 등장했지만, discrete prompt를 찾는건 차선책일 뿐이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그래서 continuous space에서 prompt를 찾는 P-tuning을 제안&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;P-tuning은 여러 NLU 태스크에서 상당한 성능 향상을 이룸.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Motivation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Big-model은 많은 문제를 해결해줬지만 poor-transferability 문제가 있음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Big-model은 fine-tuning을 제대로 하기가 어려움.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;prompt가 조금만 바뀌어도 큰 성능 차이가 있음&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Method: P-tuning&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;예시 문제: “The capital of Britain is [MASK]”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Prmopt: “The capital of … is …”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Context: “Britain”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Target: “[MASK]”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;기존 Inputs: e(token 0), e(token 1), …, e(token n) (e는 embedding)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;P-tuning Inputs: h(P[0]), …, h(P[i]), e(x), h(P[i+1]), …, h(P[m]), e([MASK]) (h는 lstm hidden state, x는 context)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;P = [0, 1, 2, 3, 4, 5] 이런 식으로 정의&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Anchor tokens: (b)의 “capital” 같이 태스크와 관련된 토큰을 추가로 임베딩 레이어에 넣어줄 수도 있음 (성능 개선을 위해)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;​&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prompt Encoder 구성&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;PromptEncoder&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lstm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; LSTM&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;hidden_size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; hidden_size &lt;span class=&quot;token operator&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; num_layers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bidirectional&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mlp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Sequential&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Linear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;in_features&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;hidden_size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; out_features&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;hidden_size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ReLU&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Linear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;in_features&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;hidden_size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; out_features&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;hidden_size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Bi-directional LSTM + MLP 구조&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;​&lt;/p&gt;
&lt;h2&gt;Experiments&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Knowledge Probing (LAMA Dataset)&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/119778212-3120b900-bf02-11eb-91b0-896d355c901e.png&quot;&gt;
&lt;ul&gt;
&lt;li&gt;SuperGLUE&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/119778331-56152c00-bf02-11eb-92fc-05acf14e8027.png&quot;&gt;
​
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;GPT, BERT에 상대적으로 작은 사이즈의 prompt-encoder를 도입해서 큰 성능 향상을 얻음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;같은 방법으로 GPT3 같은 모델에도 p-tuning을 도입해서 성능 향상을 기대해 볼 수 있음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Megatron-LM 사이즈까지는 실험을 했으나, 그 이상의 사이즈는 실험 X&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - Pushing the Limits of Semi-Supervised Learning for Automatic Speech Recognition Paper Review]]></title><description><![CDATA[Pushing the Limits of Semi-Supervised Learning for Automatic Speech Recognition Yu Zhang et al., 2020 Google Research, Brain Team Reference…]]></description><link>https://sooftware.github.io/Pushing the Limits of Semi-Supervised Learning for Automatic Speech Recognition/</link><guid isPermaLink="false">https://sooftware.github.io/Pushing the Limits of Semi-Supervised Learning for Automatic Speech Recognition/</guid><pubDate>Wed, 17 Mar 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Pushing the Limits of Semi-Supervised Learning for Automatic Speech Recognition&lt;/h1&gt;
&lt;p&gt;Yu Zhang et al., 2020&lt;br&gt;
Google Research, Brain Team&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/kakaobrain/nlp-paper-reading/blob/master/notes/wav2vec%202.0.md&quot;&gt;Wav2vec 2.0 Summary&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/speech-paper-reading/speech-paper-reading/blob/main/notes/conformer.md&quot;&gt;Conformer Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;현재 Papers with Code 기준 ASR 부문 State-Of-The-Art&lt;/li&gt;
&lt;li&gt;Conformer + Wav2vec 2.0 + Noisy Student Training&lt;/li&gt;
&lt;li&gt;1.3%/2.6%/1.4%/2.6% on the dev/dev-other/test/test-other sets&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/111322357-2f3dac80-86ac-11eb-8a05-24be848077de.png&quot; height=&quot;300&quot;&gt;
&lt;hr&gt;
&lt;h3&gt;Wav2vec 2.0 Pre-training&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/92450554-8a22b280-f1f6-11ea-8f66-0616b29d8c94.png&quot;&gt;
&lt;ul&gt;
&lt;li&gt;53,000이라는 대량의 Unlabeled speech data로 학습&lt;/li&gt;
&lt;li&gt;Pre-training 과정
&lt;ul&gt;
&lt;li&gt;Waveform에서 CNN을 이용해서 피쳐를 뽑음&lt;/li&gt;
&lt;li&gt;이를 Vector Quantization을 통해 one-hot-vector로 만들고 Embedding matrix를 내적하여 token화 함&lt;/li&gt;
&lt;li&gt;일정 비율로 Masking하고 다음 Token이 뭔지 알아맞추게하는 Masked Language Modeling (MLM) 학습 방식 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Vector Quantization&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://camo.githubusercontent.com/4e4253817961b5bead8072739c39bd3f3daaced98e8735018c50e8a55d78fb9c/68747470733a2f2f692e696d6775722e636f6d2f7931355175355a2e706e67&quot; height=&quot;300&quot;&gt;
  - Z를 선형변환하여 logit을 만듦
  - 여기에 Gumbel Softmax와 argmax를 취해 one-hot vector를 만듦
  - 이후 Embedding matrix를 내적해 Z^를 만듦
&lt;h3&gt;Conformer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Self-attention 기반한 트랜스포머는 global-context 정보를 잘 표현하지만, local-context에서는 부족하다는 단점이 있음&lt;/li&gt;
&lt;li&gt;반면, CNN 기반 모델은 local-context는 잘 표현하지만 global-context를 반영하기 위해서는 적당한 dilation과 깊은 구조를 가져야 함&lt;/li&gt;
&lt;li&gt;이 두 방법을 결합하여 global-context와 local-context 모두 잘 표현할 수 있도록 하기 위한 transformer + CNN 결합구조인 Conformer 구조 제안&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Method&lt;/h2&gt;
&lt;p&gt;본 논문에서 실험한 모델 구조 및 트레이닝 방법&lt;/p&gt;
&lt;h3&gt;Model Architecture&lt;/h3&gt;
&lt;p&gt;Conformer Encoder + LSTM decoder로 이루어진 Transducer 구조&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/111322627-77f56580-86ac-11eb-957c-d51db823e4e4.png&quot; height=&quot;600&quot;&gt;
&lt;ul&gt;
&lt;li&gt;기존 Conformer 구조에서 Wav2vec 2.0 Pre-training을 도입하기 위해 Masking하는 과정과 Linear Layer (Quantization 대체) 추가&lt;/li&gt;
&lt;li&gt;사이즈별로 L, XL, XXL로 구분&lt;/li&gt;
&lt;li&gt;XXL+는 Conformer XXL에 Conformer block을 stack (XXL보다 50M 파라미터 추가)&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/111324910-8ba1cb80-86ae-11eb-997f-12634e7b6164.png&quot;&gt;
&lt;h3&gt;Wav2vec 2.0 Pre-training&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;60k Libri-Light 데이터셋 사용&lt;/li&gt;
&lt;li&gt;기존 논문과 달리, 인풋으로 log-mel spectrogram 사용&lt;/li&gt;
&lt;li&gt;Masking 된 인풋과 예측한 context vector 간의 contrastive loss로 학습&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Noisy Student Training with SpecAugment&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/111328868-fa345880-86b1-11eb-925c-a76cdbfd7c8c.png&quot; height=&quot;200&quot;&gt;
&lt;h2&gt;Experiiments&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/111329076-2e0f7e00-86b2-11eb-8c87-17d2eca8948b.png&quot; height=&quot;400&quot;&gt;
&lt;ul&gt;
&lt;li&gt;결과적으로 Pre-training + NST가 좋은 성적을 냄&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[카카오브레인 퇴사, 그리고 창업 (feat. 졸업)]]></title><description><![CDATA[카카오브레인 퇴사, 그리고 창업 (feat…]]></description><link>https://sooftware.github.io/new_start/</link><guid isPermaLink="false">https://sooftware.github.io/new_start/</guid><pubDate>Sat, 27 Feb 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;카카오브레인 퇴사, 그리고 창업 (feat. 졸업)&lt;/h1&gt;
&lt;p&gt;최근에 저에게 큰 변화가 있어서 블로그 이웃 분들께 알리고자 글을 씁니다.&lt;/p&gt;
&lt;p&gt;저희 팀장님의 표현을 빌리자면,&lt;br&gt;
더 이상 저를 “카카오브레인에서 근무하는~” 으로  소개를 시작하지 못하게 됐습니다.&lt;/p&gt;
&lt;p&gt;카카오브레인에서의 팀장님과 몇 팀원분들과 함께 창업을 도전하게 됐습니다.&lt;br&gt;
카카오브레인에서의 생활이 마음에 들지 않아서 퇴사하는 건 아닙니다.&lt;/p&gt;
&lt;p&gt;카카오브레인에서의 생활은 100% 이상으로 만족스러웠습니다.&lt;/p&gt;
&lt;p&gt;6~7개월 정도의 짧은 시간이였지만, 실력있는 팀원분들 옆에서 하고 싶었던 음성인식, 합성 연구 및
자연어처리 지식을양껏 쌓을 수 있는 최적의 장소였고, 카카오브레인만의 컬쳐 역시 너무나 좋았습니다.&lt;/p&gt;
&lt;p&gt;단 반년 정도 있었다는 사실이 믿기지 않을 정도로 많은 일이 있었던 것 같고, 그만큼 가파른 실력 상승이 있었던 것 같습니다. 이렇게 가파르게 성장할 수 있는 기회가 다시 있을지 모르겠습니다. 목표로 했던 회사에 예상보다 빨리 온 만큼, 오래오래 있으면서 경험을 쌓으려고 계획했었지만 역시 삶은 계획대로만은 흘러가지 않는 것 같습니다.&lt;/p&gt;
&lt;p&gt;팀장님께 공동 창업 제안을 받고 그리 많은 고민을 하지는 않았습니다. 팀장님과 팀원들에 대한 신뢰가 깊이 있었기 때문에 이 사람들과 함께라면 뭐라도 해낼 수 있을 것 같은 자신감이 들었습니다. 그래서 큰 고민 없이 퇴사를 결심했고 이번 주 월요일 (21.02.22) 부로 카카오브레인에서 퇴사하게 됐습니다.&lt;/p&gt;
&lt;p&gt;아직은 법인 설립도 하지 않은 초기 단계지만, 사명은 TUNiB으로 정해졌습니다.&lt;br&gt;
앞으로 페이스북, 클럽하우스 등에서 자주 홍보할테니 많은 관심 부탁드립니다!&lt;/p&gt;
&lt;p&gt;그리고 제가 드디어 졸업을 해서 학사 학위를 받게 됐습니다 !&lt;br&gt;
정말 많은 일이 있었던 것 같은데 이제 겨우 학생 딱지를 뗀다니까 새삼 새롭네요.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[PORORO Text-To-Speech (TTS)]]></title><description><![CDATA[PORORO Text-To-Speech (TTS) 얼마전에 저희 팀에서 공개한 PORORO: Platform Of neuRal mOdels for natuRal language prOcessing 라이브러리에 제가 공들여만든 TTS…]]></description><link>https://sooftware.github.io/pororo-tts/</link><guid isPermaLink="false">https://sooftware.github.io/pororo-tts/</guid><pubDate>Tue, 16 Feb 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;PORORO Text-To-Speech (TTS)&lt;/h1&gt;
&lt;p&gt;얼마전에 저희 팀에서 공개한 &lt;a href=&quot;https://github.com/kakaobrain/pororo&quot;&gt;PORORO: Platform Of neuRal mOdels for natuRal language prOcessing&lt;/a&gt; 라이브러리에 제가 공들여만든 TTS 태스크가 추가됐습니다.&lt;/p&gt;
&lt;p&gt;11개의 언어를 지원하며 일반적인 TTS 및 Cross-lingual Voice Style Transfer, Code-Switching 기능을 지원합니다.&lt;br&gt;
지원하는 언어는 한국어, 제주어, 영어, 중국어, 일본어, 프랑스어, 독일어, 핀란드어, 러시아어, 스페인어, 네덜란드어입니다.&lt;/p&gt;
&lt;p&gt;하나의 모델로 많은 언어와 여러 기능을 지원하려다보니 부족한 점은 많지만 많이 사용해주세요!&lt;/p&gt;
&lt;p&gt;PORORO TTS - Samples: &lt;a href=&quot;https://pororo-tts.github.io/&quot;&gt;https://pororo-tts.github.io/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;많이 많이 사용해주세요 ㅎㅎ&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Longformer Paper Review]]></title><description><![CDATA[Longformer: The Long-Document Transformer Paper Code Iz Beltagy et al. Introduction 트랜스포머는 긴 시퀀스는 처리하지 못한다는 한계를 가지고 있음 이유는 시퀀스 길이에 O(n^…]]></description><link>https://sooftware.github.io/longformer/</link><guid isPermaLink="false">https://sooftware.github.io/longformer/</guid><pubDate>Sat, 06 Feb 2021 23:46:37 GMT</pubDate><content:encoded>&lt;h1&gt;Longformer: The Long-Document Transformer&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2004.05150&quot;&gt;Paper&lt;/a&gt; &lt;a href=&quot;https://github.com/allenai/longformer&quot;&gt;Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Iz Beltagy et al.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;트랜스포머는 긴 시퀀스는 처리하지 못한다는 한계를 가지고 있음&lt;/li&gt;
&lt;li&gt;이유는 시퀀스 길이에 O(n^2)하게 늘어나는 높은 복잡도 때문&lt;/li&gt;
&lt;li&gt;본 논문은 Attention 이루어지는 복잡도를 낮추는 방법을 제안 (O(n))&lt;/li&gt;
&lt;li&gt;BERT는 512 토큰을 limit으로 가지는데, 본 논문 모델은 4096 토큰까지 가능&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;text8&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;enwik8&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Wiki-Hop&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;TriviaQA&lt;/code&gt;에서 State-Of-The-Art 달성&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Attention Method&lt;/h2&gt;
&lt;img src=&quot;https://haebinshin.github.io/public/img/longformer/figure2.png&quot;&gt;  
&lt;p&gt;본 논문에서는 위 그림과 같은 3가지 어텐션 방식을 제안&lt;/p&gt;
&lt;h3&gt;Sliding window Attention&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;크기가 w인 sliding window 내에서만 attention을 수행하는 방법&lt;/li&gt;
&lt;li&gt;이 방법은 텍스트 길이 n에 대해 O(n x w)의 복잡도를 가짐&lt;/li&gt;
&lt;li&gt;이러한 방식은 레이어가 깊어짐에 따라 receptive field가 넓어지는 CNN과 유사함&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://haebinshin.github.io/public/img/longformer/receptive_field.png&quot;&gt;  
&lt;ul&gt;
&lt;li&gt;예) window size가 2일 때, 레이어가 쌓일수록 w만큼 receptive field가 넓어짐.&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://haebinshin.github.io/public/img/longformer/text_sliding_window_receptive_field.jpg&quot;&gt;
&lt;ul&gt;
&lt;li&gt;l x w의 receptive field size를 가지게 됨.&lt;/li&gt;
&lt;li&gt;각 레이어마다 w의 크기를 다르게 주는 방법이 도움이 될 수도 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Dilated Sliding Window&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sliding window attention보다도 receptive field를 더 넓히기 위해 고안된 방법&lt;/li&gt;
&lt;li&gt;Dilated Convolution에서 착안&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://haebinshin.github.io/public/img/longformer/dilation_convolution.gif&quot;&gt;  
&lt;ul&gt;
&lt;li&gt;dilated 값을 줘서 토큰을 d만큼 건너뛰면서 어텐션하도록 하는 방법&lt;/li&gt;
&lt;li&gt;예) window size가 2이고 dilation size가 2일 때, 아래 그림과 같이 w x d만큼 receptive field가 넓어짐&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://haebinshin.github.io/public/img/longformer/text_dilated_sliding_window_receptive_field.jpg&quot;&gt;
&lt;ul&gt;
&lt;li&gt;l x d x w의 receptive field size를 가지게 됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Global Attention&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;BERT의 [CLS] 토큰 같은 경우는 전체 컨텍스트를 바라봐야하는데, 위의 2가지 방법만으로는 Finetuning하는 태스크에서는 부족한 부분이 있을 수 있음&lt;/li&gt;
&lt;li&gt;따라서 스페셜 토큰 몇 개에 대해서는 global attention을 수행하도록 함.&lt;/li&gt;
&lt;li&gt;전체 토큰 수에 비해서는 스페셜 토큰은 매우 적기 때문에 복잡도는 여전히 O(n)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Linear Projections for Global Attention&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;보통의 트랜스포머의 어텐션은 Q, K, V로 이루어 지는데, sliding window 기반 어텐션과 global 어텐션을 위해 sliding Q, K, V와 global Q, K, V 두 세트로 나눠서 어텐션을 계산하도록 구현&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Experiments&lt;/h2&gt;
&lt;p&gt;2가지 방식으로 평가를 진행.&lt;/p&gt;
&lt;h3&gt;Autoregressive Language Modeling&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;모델 자체의 임베딩 평가를 위함&lt;/li&gt;
&lt;li&gt;character/token 단위의 language modeling을 수행.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;text8&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;enwik8&lt;/code&gt; 데이터셋에서 SOTA를 달성&lt;/li&gt;
&lt;li&gt;본 태스크는 dilated sliding window attention 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://haebinshin.github.io/public/img/longformer/table_2_3.png&quot;&gt;
&lt;h3&gt;Pre-training and Fine-tuning&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;RoBERTa 체크포인트로부터 시작해서 학습&lt;/li&gt;
&lt;li&gt;sliding window attention를 사용&lt;/li&gt;
&lt;li&gt;각 태스크에 따라 스페셜 토큰을 지정하여 global attention을 사용&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;WikiHop&lt;/code&gt;과 &lt;code class=&quot;language-text&quot;&gt;TriviaQA&lt;/code&gt;에서 SOTA 달성&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://haebinshin.github.io/public/img/longformer/table8.png&quot;&gt;</content:encoded></item><item><title><![CDATA[Computer Architecture Review]]></title><description><![CDATA[Computer Architecture Review 오랜만에 컴퓨터 구조에서 배운 내용을 조금 복습해보며 감을 잡기 위함 컴퓨터가 코드를 처리하는 과정 Read Code Assembly 변환 CPU에서 실행 CPU에서 하나의 명령(Ex) Add…]]></description><link>https://sooftware.github.io/computer-ar-review/</link><guid isPermaLink="false">https://sooftware.github.io/computer-ar-review/</guid><pubDate>Fri, 05 Feb 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Computer Architecture Review&lt;/h2&gt;
&lt;p&gt;오랜만에 컴퓨터 구조에서 배운 내용을 조금 복습해보며 감을 잡기 위함&lt;/p&gt;
&lt;h3&gt;컴퓨터가 코드를 처리하는 과정&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Read Code&lt;/li&gt;
&lt;li&gt;Assembly 변환&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CPU에서 실행&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;CPU에서 하나의 명령(Ex) Add)을 실행하는 과정 (5단계)&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;IF: Instruction Fetch (명령어 가져오기)&lt;/li&gt;
&lt;li&gt;ID: Instruction Decode (무슨 명령어인지)&lt;/li&gt;
&lt;li&gt;EX: Execute / Adress calculation (명령 실행 or 접근할 주소 계산)&lt;/li&gt;
&lt;li&gt;MEM: Access Memory (메모리에 접근)&lt;/li&gt;
&lt;li&gt;WB: Write (변수 업데이트)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;위의 5단계가 CPU (Single Cycle Datapath)에서 실행되는 과정&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;한 번의 Cycle에 명령 하나씩 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;layout: post
title: “ComputerArchitecture Review”
date: 2021-01-23 03:15:30 +300
image: x1.png
tags: open-source&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/106787176-baca2380-6692-11eb-9f5f-a6c0a4ae97b3.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;시간 비용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/106787296-e3521d80-6692-11eb-8991-7f25c9d665d4.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;h3&gt;Pipeline&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;나누어진 부분을 경계로 병렬적으로 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/106787546-2f04c700-6693-11eb-8041-f988e7e0ce07.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;시간 비용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/106787829-8440d880-6693-11eb-84f7-6a16f957b7c4.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;h3&gt;Hazard&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Instruction을 실행하기 위한 데이터가 준비되지 않아서 Instruction을 실행할 수 없는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/106788164-f44f5e80-6693-11eb-9117-6c187ced8fbf.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;해결 방법 1: Data Forwarding&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/106788436-4a240680-6694-11eb-8ce1-ca67136cf0f3.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;필요한 데이터가 register나 memory에 write 될 때까지 기다리지 않고, internal buffer로부터 읽어서 Hazard를 해결하는 방법&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;해결 방법 2: Stall (Bubble)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/106788736-af77f780-6694-11eb-9a0f-f92ff79d7ddd.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;Hazard를 피할 수 없는 경우 아무 명령을 처리하지 않는 nop (No-operation) 를 넣음으로써 Data Forwarding을 할 수 있도록 싱크를 맞춰주는 방법&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Pororo: A Deep Learning based Multilingual Natural Language Processing Library]]></title><description><![CDATA[Pororo: A Deep Learning based Multilingual Natural Language Processing Library Link: https://github.com/kakaobrain/pororo…]]></description><link>https://sooftware.github.io/pororo/</link><guid isPermaLink="false">https://sooftware.github.io/pororo/</guid><pubDate>Tue, 02 Feb 2021 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Pororo: A Deep Learning based Multilingual Natural Language Processing Library&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Link: &lt;a href=&quot;https://github.com/kakaobrain/pororo&quot;&gt;https://github.com/kakaobrain/pororo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://github.com/kakaobrain/pororo/raw/master/assets/usage.gif&quot;&gt;  
&lt;p&gt;제가 속해있는 카카오브레인 음성 및 자연어처리 팀에서 오늘 (2021.02.02) Pororo 오픈소스 라이브러리를 공개했습니다!&lt;/p&gt;
&lt;p&gt;Pororo는 영어, 한국어, 중국어, 일본어 등 여러가지 언어로 30가지 이상의 자연어 처리 모델이 구현되어 있는 파이썬 라이브러리 입니다.&lt;/p&gt;
&lt;p&gt;인공지능이나 자연어처리를 전혀 모르더라도 3~4 줄 정도의 코드만 작성하면 음성인식, 개체명 인식, 기계 독해, 기계 번역, 요약, 감정분류 등 다양한 태스크를 손쉽게 수행할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;pip install pororo&lt;/code&gt;로 지금 설치하시면 바로 사용해보실 수 있으며, 언어별 모델, 태스크는 확장해나갈 계획이니 많은 사용과 피드백 부탁드립니다.&lt;/p&gt;
&lt;p&gt;자세한 사항은 &lt;a href=&quot;https://github.com/kakaobrain/pororo&quot;&gt;https://github.com/kakaobrain/pororo&lt;/a&gt; 에서 확인할 수 있습니다. 감사합니다.&lt;/p&gt;
&lt;p&gt;많은 이용 및 스타 부탁드려요! ㅎㅎ&lt;/p&gt;</content:encoded></item><item><title><![CDATA[2020년 회고]]></title><description><![CDATA[2020년 회고 다사다난했던 2020년이 지나고 어느덧 2021년 새해가 밝았습니다. 🤗 🤗 코로나라는 세계적인 재앙 때문에 생활부터 모든게 많이 달라진 한 해 였습니다. 여태까지…]]></description><link>https://sooftware.github.io/2020/</link><guid isPermaLink="false">https://sooftware.github.io/2020/</guid><pubDate>Thu, 31 Dec 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;2020년 회고&lt;/h1&gt;
&lt;p&gt;다사다난했던 2020년이 지나고 어느덧 2021년 새해가 밝았습니다. 🤗 🤗&lt;br&gt;
코로나라는 세계적인 재앙 때문에 생활부터 모든게 많이 달라진 한 해 였습니다.&lt;br&gt;
여태까지 1년 회고는 개인 일기장에만 적어봤지만, 이번에는 많은 일들이 있었던 만큼 제 블로그에 기록해두고 싶어서 글을 남깁니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;KoSpeech (졸업 프로젝트)&lt;/li&gt;
&lt;li&gt;연구실 인턴&lt;/li&gt;
&lt;li&gt;미래에 대한 고민&lt;/li&gt;
&lt;li&gt;갑작스러운 제안&lt;/li&gt;
&lt;li&gt;카카오브레인 인턴&lt;/li&gt;
&lt;li&gt;정직원 전환&lt;/li&gt;
&lt;li&gt;리서치 엔지니어로서의 4달&lt;/li&gt;
&lt;li&gt;Good Bye! Kwangwoon University!&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;KoSpeech (졸업 프로젝트) (1월 ~ 3월)&lt;/h2&gt;
&lt;p&gt;언제부터였는지 모르겠지만, 저는 대학교에서의 졸업작품을 그 어떤 작품들보다 성공적으로 만들고 싶었습니다. 그래서였는지, 학점을 좋게 받는것보다는 프로젝트가 있는 수업에서 그 누구보다 프로젝트를 잘하고 싶었습니다. 시험 전날 다른 과목 시험공부를 하다가도, 프로젝트 아이디어가 떠올라서 노트북을 키고 코딩을 하다보니 어느새 시험 직전이어서 시험 범위도 못 끝낸 적도 있었네요 ㅎㅎ&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/103424527-292d4900-4bf0-11eb-85ea-2cf672fee02e.png&quot; alt=&quot;image&quot;&gt;
&lt;em&gt;c언어로 구현한 갤러그&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;첫 소프트웨어 프로젝트였던 &lt;code class=&quot;language-text&quot;&gt;c언어로 구현한 갤러그&lt;/code&gt;를 시작으로 학부 2-3학년 동안 크고 작은 소프트웨어 프로젝트를 약 20개 가까이 진행했던 것 같습니다. 지금 그 코드를 다시 보면 부끄러울 정도로 미숙하지만, 그런 삽질의 과정들이 있었기 때문에 소프트웨어 구조를 짤 때 어떻게 짜야할지에 대한 인사이트가 조금은 생긴 것 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134026737-b8d2a314-f911-4fef-aef6-a4a589c7f08d.png&quot; alt=&quot;image&quot;&gt;
&lt;em&gt;네이버 AI 해커톤 - Speech&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;졸업작품은 3-2학기 였던 19년 하반기부터 시작했습니다. 한국어 음성 인식을 주제로 프로젝트를 진행했는데, 마침 시기 좋게 열린 &lt;code class=&quot;language-text&quot;&gt;네이버 AI 해커톤 - Speech&lt;/code&gt;에 참가해서 전체 100팀 중 12등을 했었습니다. 당시 상위권 팀이던 1 - 3등 팀들의 소감을 들으면서 많은 자극을 받았습니다. 그래서인지 20년 1월에 한참 음성인식에 대한 열정이 불타올랐던 것 같습니다. 팀원들과 함께 상위권팀들이 썼다는 기술들에 대해 하나하나 키워드별로 조사해가며 스터디를 진행했고, 스터디 → 구현 → 스터디 → 구현을 반복했습니다. 그러다보니 겨울방학기 끝날 때 쯤에는 꽤 그럴 듯한 음성인식 툴킷이 만들어져 있었고, 그 후 계속 수정을 거치며 지금의 &lt;a href=&quot;https://github.com/sooftware/KoSpeech&quot;&gt;KoSpeech&lt;/a&gt;가 만들어졌습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;연구실 인턴 (4월 ~ 8월)&lt;/h2&gt;
&lt;p&gt;당시 제 목표는 구체적이진 않았지만 뛰어난 AI 리서치 엔지니어가 되는 것이였습니다. AI 리서치 엔지니어가 되기 위해서는 적어도 석사 학위는 필수라고 생각했습니다. 학위도 학위지만, 대학원에서의 2년이 결코 무시 못할 경험이라고 생각했습니다. 하지만 막연히 ‘난 대학원에 진학할거야’라는 생각만 가진채, 언제 어떻게 교수님께 컨택을 하고, 어떤 연구실에 진학할지에 대해서는 정하지 않고 있었습니다. 지금 돌이켜보니, 연구실에 컨택했다가 거절당하는 것에 대한 두려움이 어느정도 있어서 계속 결정을 미뤄왔던 것 같습니다. 그러던 중에 대학원에 진학을 염두하는 저를 위해 여자친구가 선물해준 “대학원생 때 알았더라면 좋았을 것들” 책을 읽었습니다.&lt;/p&gt;
&lt;img src=&quot;https://image.yes24.com/Goods/72231788/L&quot;&gt;  
&lt;p&gt;책에 있는 대부분 내용이 유익한 내용이었지만, 그 중 ‘대학원에 진학하기전에 가능하다면 꼭 해당 연구실 인턴을 해봐라. 이미 입학하고 후회하면 늦는다’라는 구절이 제 마음을 움직였습니다. 그 구절을 곱씹으면서 되든 안되든 연구실에 컨택을 해보기로 했습니다. 그렇게 다분히 심심했던 제 생활패턴에서 자기소개서, 교수님께 보낼 메일 작성, 사진 찍기 등 몇일 간 바쁘게 보냈습니다. 준비를 마치고는 관심있었던 연구실의 교수님께 메일을 보냈습니다. 메일을 보내고는 10분마다 메일왔는지를 확인했던 것 같습니다 ㅋㅋㅋ.. 하지만 메일을 보낸지 몇일이 지나도 교수님께 답장은 없었습니다.&lt;/p&gt;
&lt;img src=&quot;https://img1.daumcdn.net/thumb/R800x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F267D2541521A110A2D&quot;&gt;  
&lt;p&gt;메일을 보내고 답장을 기다리는 몇일 동안, 많은 고뇌가 있었습니다. PLAN-B를 생각해본 적이 없었기 때문에 앞으로 어떡해야하나…라는 생각만 들었습니다. 역시 대학원을 가려면 학점이 좀 더 좋아야 했나.. 라는 생각이 들었습니다. 그러던 중, 기다리고 기다리던 교수님으로부터의 답장이 왔습니다!&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;김수환님께
안녕하세요. **대학교 *** 입니다. 보내주신 이메일 잘 받았습니다.

제가 연구하고 있는 음성인식 분야에 대해서 많은 관심을 가지고,
좋은 연구 결과를 내고 있는 것에, 학부연구원 연구 참여/대학원 진학을 떠나
해당 분야를 연구하고 있는 교수로서 감사의 말씀을 드립니다.

우선은 학부 연구원으로 우리 연구실에 참여를 하는 것이 좋을 것 같습니다.
학부 연구원 위촉시, 저희 연구실은 1차로 대학원 학생들의 면접이 있습니다.
현재까지 진행한 연구/개발 위주로 자연스러운 분위기에서 학생들간에 이야기를
나눈다고 생각하시면 되겠습니다. 관련해서 저희 연구실 박사과정 학생이
연락을 드리겠습니다.

- *** 드림 -&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;최근 몇년 간 가장 기뻤던 일 중 하나였습니다. 기다림이 길었던 만큼, 안 좋은 결과를 예상하고 있었는데, 교수님께서 긍정적으로 답변을 주셔서 기뻤고, 제가 여태까지 한 활동이 인정받은 것 같아 기뻤습니다. 연구실 선배들과의 간단한 면접을 마친 후, 다음주부터 연구실로 출근을 했습니다. 학기중이였지만, 코로나로 인해 대부분의 강의가 온라인으로 진행됐기 때문에 연구실로 출근해서 강의를 들을 수 있었습니다. 연구실 세미나도 참석하면서, 연구실에서 진행되고 있는 프로젝트, 연구 주제 등에 대해서 귓동냥을 열심히 했습니다. 👂 👂&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134027002-e3c0fc1b-e35c-4e5b-9938-1b02ac986782.png&quot;&gt;
&lt;p&gt;연구실에 들어간지 3주 정도가 지나고, 교수님께서 제가 했던 음성인식 프로젝트에 대해서 발표를 한번 해달라고 요청해주셨습니다. 전문가분들 앞에서 발표한다는 생각에 많이 떨렸습니다. 그래도 제가 한 모든 것에 대해 발표하고 싶다는 생각에 최대한 열심히 발표했습니다. 다행히도 교수님과 연구실 선배들이 제 발표를 좋게 봐주셨고, 진행중이던 KoSpeech를 더 열심히 해보라며 제가 사용할 수 있는 GPU 서버도 하나 지원해주셨습니다. 👍 👍&lt;/p&gt;
&lt;p&gt;이후에도 지속적으로 세미나에 참석하면서 서당개가 된 기분으로 열심히 들었습니다. 이 외에도 연구실에 있으면서 실제로 석,박사 분들이 어떤 일을 하는지, 어떤 점이 힘든지 등 직접 보고 들으며 제 미래 석사 생활을 머리속으로 그려보곤 했었습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;미래에 대한 고민 (6월 ~ 7월)&lt;/h2&gt;
&lt;p&gt;연구실 생활은 매우 만족스러웠지만, 제 미래에 대한 고민은 계속 커졌던 것 같습니다. 음성인식이란 분야에 내가 어떤 기여를 할 수 있을지, 음성인식이 몇년 뒤에 완전히 정복되어버려서 내가 공부하는 모든게 필요없어지는 날이 와버리는게 아닌지, 지금 있는 연구실이 내 성향과 잘 맞는 곳인지 등 올해 가장 많은 고민을 했던 시기였습니다.&lt;/p&gt;
&lt;p&gt;특히 저는 최근에 연구가 활발한 End-to-End 방식의 음성인식을 해왔고, 앞으로도 이 방법을 연구하고 싶었는데, 소속된 연구실에서는 End-to-End가 나오기 이전 방식인 Kaldi 기반의 음성인식을 주로 연구하고 있었습니다. 그리고 무엇보다도 음성인식 외에도 음성합성, 화자인식, NLP 등 좀 더 넓은 분야를 공부하고 싶은 욕심이 강했습니다. 여기 연구실로 진학하게 되면 전문성은 생기지만 제가 할 수 있는 일의 범위가 너무 협소해지는건 아닐까? 라는 생각에 답이 없는 고민을 하며 지냈습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;갑작스러운 제안 (7월)&lt;/h2&gt;
&lt;p&gt;여느날처럼 연구실 선배들과 저녁을 먹고 연구실로 다시 돌아가던 중에, 지금 팀장님으로부터 페이스북 메시지를 받게 되었습니다. &lt;code class=&quot;language-text&quot;&gt;안녕하세요&lt;/code&gt; 5글자 였지만, 저는 속으로 말도안돼! 라고 생각했었습니다. 깃허브에서 이미 너무나 유명하신 분이셔서 이미 누구신지 잘 알고 있었습니다. 인사를 주고 받은 후에 KoSpeech를 보고 연락을 줬다는 말과 판교로 한 번 놀러오라는 한마디에 사기인가 싶어서 페이스북 프로필에 들어가서 맞는지 확인까지 해봤습니다. 그 뒤로도 메세지 몇개를 주고 받았는데, 인턴 의향이 있냐는 메세지에 얼굴이 빨개지고 심장이 쿵쾅쿵쾅 뛰었던 기억이 생생합니다.&lt;/p&gt;
&lt;p&gt;너무 기뻐서 이게 꿈이 아닌지를 몇번이고 확인해보고, 사기는 아닌지 페이스북 프로필을 몇번이나 확인하고 나서야, 실제상황임을 깨닫고 여자친구와 부모님 친구들께 동네방네 자랑했습니다. ㅋㅋㅋ&lt;/p&gt;
&lt;p&gt;아마 이 날 느낀 감정이 제가 살면서 가장 기뻤던 날로 기억합니다. 항상 제게는 어느 정도 예상 가능한 일들만 일어났었는데, 전혀 예상 못한 일이 일어났다는 그 사실이 믿기지 않았습니다. 특히 제가 석사 졸업하고 가장 가고 싶었던 카카오브레인에서 이런 제안을 해줬다는 사실이 믿기지가 않았습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;카카오브레인 인턴 (9월 ~ 10월)&lt;/h2&gt;
&lt;img src=&quot;https://m.economictimes.com/thumb/msid-69278826,width-1200,height-900,resizemode-4,imgsize-82628/internship2-getty.jpg&quot;&gt;
&lt;p&gt;인턴 제안을 받은지 한 달 정도 후, 몸 담고 있던 연구실 정리와 간단한 인턴 면접 등을 마치고 카카오브레인에서의 인턴 생활을 시작했습니다. 코로나가 한참 심해지던 시기라 첫 날부터 재택근무로 시작을 했습니다. 인턴 프로젝트로 3개월동안 음성 관련 프로젝트를 진행하게 됐습니다. 처음에는 써보지 않은 툴킷에 적응하고, 타겟으로 잡은 논문들을 이해하느라 스트레스도 많이 받았던 것 같습니다. 어떻게든 잘해내고 싶다는 마음에 밤낮, 주말없이 일에 매진했습니다. 처음 한 2주간은 조그만 아웃풋은 커녕, 삽질의 연속이였습니다. 특히 새로운 툴킷에 익숙해지기까지의 과정이 너무나 힘겨웠습니다.&lt;/p&gt;
&lt;img src=&quot;https://post-phinf.pstatic.net/MjAxODA2MDFfMzEg/MDAxNTI3ODQxNjI5MTI4.2cfEooGQ32iBE5yQD0q1ve0PD3BLzV8fnm2fLi48TOQg.pb91iOZ_KPZP-os3R_8G838sddwZUJKy0_wLcFHywX0g.JPEG/%EC%82%BD%EC%A7%88%EC%82%BD%EC%A7%88.jpg?type=w1200&quot;&gt;
&lt;p&gt;하지만 삽질도 2주정도 해보니까, 어떻게 어떻게 툴킷에 적응이 됐고, 막혔던 일들이 기다렸다는 듯이 하나하나 뻥! 뻥! 뚫리기 시작했습니다. 한번 속도가 붙으니 그 뒤로는 한주 한주 다르게 프로젝트가 진행됐던 것 같습니다. 일에 자신감도 붙었고, 팀에도 점차 적응해가며 스트레스보다는 즐거운 마음으로 일을 할 수 있었습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;정직원 전환 (11월)&lt;/h2&gt;
&lt;img src=&quot;https://miro.medium.com/max/6000/1*zPegOUmJJWIWTc-blEekcA.png&quot;&gt;
&lt;p&gt;인턴 기간 3개월 중 2개월이 지나던 무렵, 정직원 전환 면접을 진행하고 정직원으로 전환됐습니다!! 🎉 🎉&lt;br&gt;
인턴으로 들어갈때까지만 해도, 정직원으로의 전환은 말도안된다고 생각했는데, 꿈이 현실로 이루어진 날이였습니다. 사실 면접 보기 전까지는 웬만하면 되지 않을까? 란 생각이 있었는데, 면접을 보고나서 면접을 너무 못 봤다는 생각에 자리로 돌아가 멘탈이 나간채로 자리에 앉아있었습니다. 다시 면접장으로 불러서 팀원들이 정직원 전환 축하한다고 해줬을 때, 얼떨떨해서 좋은 티도 못냈지만 속으로는 기쁨과 안도감이 동시에 들고 긴장감이 확 풀렸었습니다. 정직원 전환됐다는 말에 부모님과 여자친구가 가장 축하해주고 좋아해줬던 것 같습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;리서치 엔지니어로서의 4달 (9월 ~ 12월)&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/103439743-e36d9080-4c82-11eb-9913-6ae40e1d26c8.png&quot; alt=&quot;&quot;&gt;
&lt;em&gt;제 인생 첫 명함입니다 ㅎㅎ&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;9, 10, 11, 12월을 카카오브레인에서 리서치 엔지니어로써 보냈습니다. 4개월 동안 정말 많은 성장이 있었고, 제가 많이 부족하다는 것 또한 뼈져리게 느낀 기간이였습니다. 그리고 이렇게 훌륭한 팀장님, 훌륭한 팀원분들과 같이 일을 할 수 있다는 점에 굉장히 감사합니다. 훌륭한 팀원분들은 항상 제게 동기부여가 되는 것 같습니다. 저도 팀원들에게 동기부여가 되는 사람이 될 수 있도록 부단히 노력해야겠습니다.&lt;/p&gt;
&lt;h2&gt;Good Bye! Kwangwoon University!&lt;/h2&gt;
&lt;img src=&quot;https://www.kw.ac.kr/en/img/m_visual_01.jpg&quot;&gt;
&lt;p&gt;대학교에서의 마지막 학기를 마쳤습니다. 이제 더 이상 제가 다니던 광운대학교에서 수업을 듣는 일은 없게 됐습니다. 그런 점에서 여러모로 아쉬웠던 1년이였습니다. 코로나로 인해 4학년 1년을 대부분 온라인 수업으로 진행하면서, 학교 강의실에서 수업듣는 일, 학교 도서관에서 공부하는 일 등 지극히 당연했던 일상이 급격하게 바뀌었습니다. 편하기도 했지만, 한편으로는 시험기간에 도서관에서 친구들과 밤을 새고, 한번씩 나와서 편의점을 가고 별거 아닌 얘기들로 수다를 떨고, 어디과에 누군지는 모르지만 도서관에서 얼굴을 자주 봐서 어느새 익숙해져 버린 분들도 더 이상 볼 수 없었던 점 등 대학교에서의 마지막 1년의 추억을 많이 쌓지 못한 것 같아 아쉽습니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Fairseq Hydra]]></title><description><![CDATA[Fairseq’s Hydra Fairseq이 0.10.1로 버젼 업그레이드를 하면서 configuration 관리를 Hydra로 하게됨. Fairseq을 실행시키는 command line…]]></description><link>https://sooftware.github.io/fairseq-hydra/</link><guid isPermaLink="false">https://sooftware.github.io/fairseq-hydra/</guid><pubDate>Thu, 31 Dec 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;&lt;a href=&quot;https://github.com/pytorch/fairseq/blob/master/docs/hydra_integration.md&quot;&gt;Fairseq’s Hydra&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Fairseq이 0.10.1로 버젼 업그레이드를 하면서 configuration 관리를 Hydra로 하게됨.&lt;/li&gt;
&lt;li&gt;Fairseq을 실행시키는 command line상에서도, 모델 코드 상에서도 몇 가지 변화가 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;Creating or migrating components&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;기존 모델 코드는 &lt;code class=&quot;language-text&quot;&gt;add_args()&lt;/code&gt;라는 static method로 config를 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@staticmethod&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add_args&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;parser&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Add model-specific arguments to the parser.&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# fmt: off&lt;/span&gt;
    parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_argument&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;--dropout&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metavar&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;D&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;token builtin&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;dropout probability&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_argument&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;--encoder-embed-dim&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metavar&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;N&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;token builtin&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;encoder embedding dimension&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_argument&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;--encoder-embed-path&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metavar&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;STR&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;token builtin&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;path to pre-trained encoder embedding&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;이런 방식은 코드를 읽을 때, 어떤 argument들이 사용되는지 한 번에 보기가 어렵다는 단점이 있음.
→ 내부적으로 사용되는 모듈들을 하나하나 찾아가서 확인해봐야함.
→ 복잡한 모델일수록 더욱 코드 읽기가 어려워짐.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;@dataclass&lt;/code&gt; 데코레이터를 이용하는 class를 이용하는 방법으로 수정 (Tasks &amp;#x26; Models)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@dataclass&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Wav2Vec2Config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;FairseqDataclass&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    extractor_mode&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; EXTRACTOR_MODE_CHOICES &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; field&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        default&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        metadata&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;help&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;mode for feature extractor. default has a single group norm with d &quot;&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;groups in the first conv block, whereas layer_norm has layer norms in &quot;&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;every block (meant to use with normalize=True)&quot;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    encoder_layers&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; field&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        default&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metadata&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;help&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;num encoder layers in the transformer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    encoder_embed_dim&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; field&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        default&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;768&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metadata&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;help&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;encoder embedding dimension&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    encoder_ffn_embed_dim&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; field&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        default&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3072&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metadata&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;help&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;encoder embedding dimension for FFN&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;FairseqDataclass를 상속받는 클래스를 정의해서 사용 → &lt;a href=&quot;https://github.com/pytorch/fairseq/blob/master/fairseq/models/wav2vec/wav2vec2.py&quot;&gt;Example&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Task Example&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@dataclass&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LanguageModelingConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;FairseqDataclass&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Optional&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; field&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        default&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metadata&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;help&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;path to data directory&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@register_task&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;language_modeling&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dataclass&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;LanguageModelingConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LanguageModelingTask&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;LegacyFairseqTask&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
    &lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@classmethod&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setup_task&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cls&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cfg&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; LanguageModelingConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Model Example&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@dataclass&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TransformerLanguageModelConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;FairseqDataclass&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    activation_fn&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ChoiceEnum&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;utils&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_available_activation_fns&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; field&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        default&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;relu&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metadata&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;help&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;activation function to use&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    dropout&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; field&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;default&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; metadata&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;help&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;dropout probability&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@register_model&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;transformer_lm&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dataclass&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;TransformerLanguageModelConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TransformerLanguageModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;FairseqLanguageModel&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
    &lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@classmethod&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;build_model&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cls&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cfg&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; TransformerLanguageModelConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; task&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; FairseqTask&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;기존 방법(&lt;code class=&quot;language-text&quot;&gt;add_args()&lt;/code&gt;)은 여전히 서포트 되지만, 이후 언젠가 deprecated 될 것이라고 함.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;Training with &lt;code class=&quot;language-text&quot;&gt;fairseq-hydra-train&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;configuraion 관리를 hydra로 하기 때문에 기존에 사용했던 &lt;code class=&quot;language-text&quot;&gt;fairseq-train&lt;/code&gt;이 아닌 &lt;code class=&quot;language-text&quot;&gt;fairseq-hydra-train&lt;/code&gt; training&lt;/li&gt;
&lt;li&gt;Override default values through command line:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ fairseq-hydra-train \
    distributed_training.distributed_world_size=1 \
    dataset.batch_size=2 \
    task.data=data-bin \
    model=transformer_lm/transformer_lm_gpt \
    task=language_modeling \
    optimization.max_update=5000&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Replace bundled configs with an external config:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ fairseq-hydra-train \
    --config-dir /path/to/external/configs \
    --config-name wiki103&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;where /path/to/external/configs/wiki103.yaml contains:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# @package _group_&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; transformer_lm
&lt;span class=&quot;token key atrule&quot;&gt;distributed_training&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;distributed_world_size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;dataset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;batch_size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; language_modeling
  &lt;span class=&quot;token key atrule&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /path/to/data
  &lt;span class=&quot;token key atrule&quot;&gt;add_bos_token&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;max_target_positions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;optimization&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;max_update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50000&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;lr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;criterion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cross_entropy
&lt;span class=&quot;token key atrule&quot;&gt;optimizer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; adam
&lt;span class=&quot;token key atrule&quot;&gt;lr_scheduler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cosine&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Sooftware ML - Hydra]]></title><description><![CDATA[Hydra: framework for elegantly configuring complex applications Facebook Research에서 공개한 오픈소스. 복잡한 Configuration…]]></description><link>https://sooftware.github.io/hydra/</link><guid isPermaLink="false">https://sooftware.github.io/hydra/</guid><pubDate>Mon, 28 Dec 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Hydra: framework for elegantly configuring complex applications&lt;/h2&gt;
&lt;p&gt;Facebook Research에서 공개한 오픈소스. 복잡한 Configuration을 간단하고 깔끔하게 정리할 수 있는 장점이 있습니다.&lt;br&gt;
히드라(Hydra)라는 이름은 여러개의 유사한 작업을 수행할 수 있다는 점에서 하나의 몸에 여러 머리를 가진 히드라라는 이름으로 명명됐습니다.&lt;/p&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Install Command&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;pip install hydra-core --upgrade&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2&gt;Tutorials&lt;/h2&gt;
&lt;hr&gt;
&lt;h3&gt;A simple command-line app&lt;/h3&gt;
&lt;p&gt;가장 간단한 버젼의 hydra 사용법입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;my_app.py&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; omegaconf &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; DictConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OmegaConf
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; hydra

&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@hydra&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;my_app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cfg&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; DictConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OmegaConf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to_yaml&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cfg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    my_app&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위의 예제 같이 다른 설정없이 실행한다면, Hydra는 아무것도 담지 않은 &lt;code class=&quot;language-text&quot;&gt;cfg&lt;/code&gt; 객체를 반환합니다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;+&lt;/code&gt; 인자로 기존에 없던 config를 커맨드라인에서 추가해서 사용할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ python my_app.py +db.driver=mysql +db.user=omry +db.password=secret
db:
  driver: mysql
  user: omry
  password: secret&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h3&gt;Specifying a config file&lt;/h3&gt;
&lt;p&gt;위의 방법과 같이 모든 아규먼트를 일일이 타이핑하는 것은 굉장히 지루하고 실수하기 쉬운 방법입니다. 이런 불편함을 해소하기 위해 YAML 포맷으로 config를 관리하는 방법이 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;config.yaml&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 
  &lt;span class=&quot;token key atrule&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; mysql
  &lt;span class=&quot;token key atrule&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; omry
  &lt;span class=&quot;token key atrule&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; secret&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;yaml 포맷을 이용하는 경우 아까 위의 예제에서 &lt;code class=&quot;language-text&quot;&gt;@hydra,main()&lt;/code&gt;에 &lt;code class=&quot;language-text&quot;&gt;config_name&lt;/code&gt; 인자에 경로만 넘겨주면 됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;my_app.py&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;@hydra.main(config_name=&apos;config&apos;)
def my_app(cfg):
    print(OmegaConf.to_yaml(cfg))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이렇게 config 파일 경로만 설정해주면 &lt;code class=&quot;language-text&quot;&gt;config.yaml&lt;/code&gt; 파일이 자동으로 로드되어 프로그램이 실행됩니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ python my_app.py
db:
  driver: mysql
  user: omry
  password: secret&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h3&gt;Using the config object&lt;/h3&gt;
&lt;p&gt;Hydra를 통해 얻은 &lt;code class=&quot;language-text&quot;&gt;cfg&lt;/code&gt;는 omegaconf 모듈의 DictConfig 객체입니다. 아래는 이러한 DictConfig를 다루는 간단한 예제입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;config.yaml&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;                         &lt;span class=&quot;token comment&quot;&gt;# Config is hierarchical&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;loompa&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;                  &lt;span class=&quot;token comment&quot;&gt;# Simple value&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;zippity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;node.loompa&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;     &lt;span class=&quot;token comment&quot;&gt;# Value interpolation&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;oompa ${node.loompa}&quot;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# String interpolation&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;waldo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;?&lt;/span&gt;                  &lt;span class=&quot;token comment&quot;&gt;# Missing value, must be populated prior to access&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;my_app.py&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@hydra&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;config&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;my_app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cfg&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; DictConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; cfg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;loompa &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;          &lt;span class=&quot;token comment&quot;&gt;# attribute style access&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; cfg&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;node&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;loompa&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;# dictionary style access&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; cfg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zippity &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;         &lt;span class=&quot;token comment&quot;&gt;# Value interpolation&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;isinstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cfg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zippity&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# Value interpolation type&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; cfg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;do &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;oompa 10&quot;&lt;/span&gt;      &lt;span class=&quot;token comment&quot;&gt;# string interpolation&lt;/span&gt;

    cfg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;waldo                        &lt;span class=&quot;token comment&quot;&gt;# raises an exception&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Outputs:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ python my_app.py 
Missing mandatory value: waldo
        full_key: waldo
        reference_type=Optional[Dict[Any, Any]]
        object_type=dict&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h3&gt;Puttuing it all together&lt;/h3&gt;
&lt;p&gt;소프트웨어가 복잡할수록 configuraion의 구조도 역시 복잡해집니다. 예를 들면 아래와 같은 구조가 있을 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Directory layout&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;├── conf
│   ├── config.yaml
│   ├── db
│   │   ├── mysql.yaml
│   │   └── postgresql.yaml
│   ├── schema
│   │   ├── school.yaml
│   │   ├── support.yaml
│   │   └── warehouse.yaml
│   └── ui
│       ├── full.yaml
│       └── view.yaml
└── my_app.py&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 구조는 총 12가지의 가능한 조합이 있습니다. composition이 없다면 이런 복잡한 소프트웨어의 configs를 관리하는건 굉장히 복잡하지만, hydra에서는 아래와 같이 간단하게 선택하여 사용할 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;config.yaml&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;defaults:
  - db: mysql
  - ui: full
  - schema: school&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h3&gt;Multi-run&lt;/h3&gt;
&lt;p&gt;어떤 함수나 프로그램을 config 별로 실험을 해야할 때 유용하게 쓸 수 있는 방법입니다. Parameter sweep이라고 하는 이 기능은 &lt;code class=&quot;language-text&quot;&gt;--multirun&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;-m&lt;/code&gt; 플래그로 사용할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ python my_app.py -m schema=warehouse,support,school&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위와 같이 -m 옵션을 주고 &lt;code class=&quot;language-text&quot;&gt;,&lt;/code&gt;로 분리된 리스트를 넘겨주면 해당 파라미터에 대해 sweep을 진행합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt; $ python my_app.py schema=warehouse,support,school db=mysql,postgresql -m
[2019-10-01 14:44:16,254] - Launching 6 jobs locally
[2019-10-01 14:44:16,254] - Sweep output dir : multirun/2019-10-01/14-44-16
[2019-10-01 14:44:16,254] -     #0 : schema=warehouse db=mysql
[2019-10-01 14:44:16,321] -     #1 : schema=warehouse db=postgresql
[2019-10-01 14:44:16,390] -     #2 : schema=support db=mysql
[2019-10-01 14:44:16,458] -     #3 : schema=support db=postgresql
[2019-10-01 14:44:16,527] -     #4 : schema=school db=mysql
[2019-10-01 14:44:16,602] -     #5 : schema=school db=postgresql&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h3&gt;Output / Working directory&lt;/h3&gt;
&lt;p&gt;프로그램을 돌리게되면 프로그램의 결과 혹은 로그를 저장하기 위해 output 경로를 지정해주는게 일반적인데, Hydra는 따로 지정해주지 않아도 매번 &lt;code class=&quot;language-text&quot;&gt;YYYY-MM-DD/H-M-S&lt;/code&gt; 형식으로 output 디렉토리에 저장해줍니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;프로그램의 output 저장&lt;/li&gt;
&lt;li&gt;Hydra output 저장 (Configuration, logs, etc..)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; omegaconf &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; DictConfig

&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@hydra&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;my_app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cfg&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; DictConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Working directory : {}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;getcwd&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

$ python my_app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;py
Working directory &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;home&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;omry&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;dev&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;hydra&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;outputs&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2019&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;09&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;17&lt;/span&gt;

$ python my_app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;py
Working directory &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;home&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;omry&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;dev&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;hydra&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;outputs&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2019&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;09&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;19&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ouput:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ tree outputs/2019-09-25/15-16-17
outputs/2019-09-25/15-16-17
├── .hydra
│   ├── config.yaml
│   ├── hydra.yaml
│   └── overrides.yaml
└── my_app.log&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output / Working directory 기능을 사용하지 않으려면 &lt;code class=&quot;language-text&quot;&gt;hydra.output_subdir&lt;/code&gt;를 &lt;code class=&quot;language-text&quot;&gt;null&lt;/code&gt;로 지정하면 됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Logging&lt;/h3&gt;
&lt;p&gt;많은 사람들이 log 설정하기가 귀찮아서 파이썬에서 로그 기능을 사용하지 않는 경우가 많은데, hydra에서는 이러한 로그의 기본 설정을 이미 해뒀기 때문에 아래와 같이 손쉽게 사용 가능합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; logging
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; omegaconf &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; DictConfig
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; hydra
  
&lt;span class=&quot;token comment&quot;&gt;# A logger for this file&lt;/span&gt;
log &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; logging&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;getLogger&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@hydra&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;my_app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_cfg&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; DictConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;info&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Info level message&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;debug&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Debug level message&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; __name__ &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    my_app&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

$ python my_app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;py
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2019&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;06&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;27&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;52&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;46&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;653&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;__main__&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;INFO&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; Info level message&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - EMNLP Paper Review: Speech]]></title><description><![CDATA[EMNLP Paper Review: Speech Adaptive Feature Selection for End-to-End Speech Translation (Biao Zhang et al) Incremental Text-to-Speech…]]></description><link>https://sooftware.github.io/2020 EMNLP Speech Paper Review/</link><guid isPermaLink="false">https://sooftware.github.io/2020 EMNLP Speech Paper Review/</guid><pubDate>Tue, 08 Dec 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;EMNLP Paper Review: Speech&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2010.08518&quot;&gt;Adaptive Feature Selection for End-to-End Speech Translation (Biao Zhang et al)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1911.02750&quot;&gt;Incremental Text-to-Speech Synthesis with Prefix-to-Prefix Framework (Mingbo Ma et al)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Adaptive Feature Selection for End-to-End Speech Translation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;EMNLP 2020&lt;/li&gt;
&lt;li&gt;Biao Zhang, Ivan Titov, Barry Haddow, Rico Sennrich&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;End-to-End Speech Translation (E2E ST)를 다룬 논문&lt;/li&gt;
&lt;li&gt;Speech Translation
&lt;ul&gt;
&lt;li&gt;Cascade: 음성 (source) → 음성인식 모델 → 텍스트 (source) → 번역 모델 → 텍스트 (target)&lt;/li&gt;
&lt;li&gt;E2E: 음성 (source) → 음성번역 모델 → 텍스트 (target)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Cascade 방식은 음성인식에서의 오류가 기계번역으로 전파가 되는 단점이 있음&lt;/li&gt;
&lt;li&gt;E2E 번역이 최근 많이 연구되고 있으나, Cascade 방식의 성능을 따라잡지 못하고 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/101368190-32294400-38ea-11eb-924b-5b0a2e25d2e6.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;E2E ST가 어려운 주된 이유로, 음성마다 단어 발화 길이가 다르며, 노이즈 혹은 중간중간 끊기는 등 일관적이지 않다는 특징 때문이라고 주장&lt;/li&gt;
&lt;li&gt;그래서 인코딩 된 피쳐를 선택적으로 사용해야 된다고 주장 (Adaptive Feature Selection)&lt;/li&gt;
&lt;li&gt;AFS는 인코더 아웃풋에서 필요없는 프레임은 제거하는 역할을 함 (L&lt;sub&gt;0&lt;/sub&gt;Drop - Zhang et al., 2020)&lt;/li&gt;
&lt;li&gt;결과적으로 본 논문은 아래와 같은 파이프라인을 제안함&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/101366218-073df080-38e8-11eb-8699-dd6ebc2d70dc.png&quot; width=&quot;300&quot;&gt;  
&lt;ul&gt;
&lt;li&gt;Training Pipeline
&lt;ol&gt;
&lt;li&gt;ASR 모델 학습 (Hybrid Cross Entropy + CTC)&lt;/li&gt;
&lt;li&gt;AFS 모델을 추가해서 ASR 모델 파인튜닝&lt;/li&gt;
&lt;li&gt;ASR &amp;#x26; AFS 모델은 Freeze한 채로 ST Encoder, ST Decoder 학습&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Result on MuST-C En-De&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/101370007-4a9a5e00-38ec-11eb-8f41-7f6de1b9d583.png&quot; width=&quot;500&quot;&gt;
&lt;ul&gt;
&lt;li&gt;AFS는 모델을 더 빠르게 하면서도 성능을 높였음&lt;/li&gt;
&lt;li&gt;성능은 Cascade보다는 살짝 낮음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;Incremental Text-to-Speech Synthesis with Prefix-to-Prefix Framework&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;EMNLP 2020&lt;/li&gt;
&lt;li&gt;Mingbo Ma, Baigong Zheng, Kaibo Liu, Renjie Zheng, Hairong Liu, Kainan Peng, Kenneth Church, Liang Huang  (Baidu Research)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://inctts.github.io/&quot;&gt;Demo Page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;동시번역을 위한 빠른 음성합성 기법 제안&lt;/li&gt;
&lt;li&gt;새로 학습할 필요없이 Inference 단에서 수정하여 사용할 수 있는 파이프라인 제안 (Tacotron2 사용)&lt;/li&gt;
&lt;li&gt;기존 TTS 시스템&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/101376816-6bff4800-38f4-11eb-9dca-1592c05c6759.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;Text2Phoneme → Phoneme2Spectrogram → Spectrogram2Wave 단계를 거침&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;위와 같은 Full-sentence TTS는 문장 길이가 길어질수록 latency가 길어지는 고질적인 문제점을 가지고 있음&lt;/li&gt;
&lt;li&gt;이러한 문제점 해결을 위해 아래 파이프라인을 제안&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/101377884-bf25ca80-38f5-11eb-8098-6f0b206d01f6.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Full-sentence TTS가 아닌, Incremental TTS 방식 제안&lt;/li&gt;
&lt;li&gt;먼저 만들어진 오디오를 재생하는 동안 뒷단의 오디오를 만들어나가는 방식&lt;/li&gt;
&lt;li&gt;이와 같은 파이프라인이 가능하려면 특정 단위로 쪼개야함 (E.g. Word)&lt;/li&gt;
&lt;li&gt;하지만 Word 단위로 TTS를 진행한 후, 오디오를 이어붙이게 되면 굉장히 부자연스러운 음성이 합성됨&lt;/li&gt;
&lt;li&gt;이를 극복하기 위해 lookahead-k Policy 제안
&lt;ul&gt;
&lt;li&gt;t번째 target을 만들때 t+k개의 입력 소스를 통해 생성 (첫 k+1 스텝까지는 wait)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;결과적으로 음질이 크게 떨어지지 않으면서도 latency를 줄임 (문장이 길수록 효과가 큼)&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP -  Megatron LM Paper Review]]></title><description><![CDATA[Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism ​ Mohammad Shoeybi et al. 2019. NVIDIA Corp. ​ Summary…]]></description><link>https://sooftware.github.io/Megatron-lm/</link><guid isPermaLink="false">https://sooftware.github.io/Megatron-lm/</guid><pubDate>Thu, 03 Dec 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism&lt;/h1&gt;
&lt;p&gt;​&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mohammad Shoeybi et al. 2019.&lt;/li&gt;
&lt;li&gt;NVIDIA Corp.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;​&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Transformer Language Model Parallelism&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;새로운 컴파일러나 기존 라이브러리 변경 없이 Very Big-Model을 학습시킬 수 있는 Megatron-LM을 제안 (PyTorch 기반)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;8.3 billion 파라미터를 성공적으로 학습시킴 (GPT-3: 175 billion)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;​&lt;/p&gt;
&lt;h2&gt;Backgrounds&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/106808382-a9424500-66ad-11eb-9058-98716b94ae40.png&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;최근 Large-scale의 Transformer를 이용한 Language Model(LM)이 대세&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;하지만 너무 큰 모델은 하드웨어적 메모리 제약으로 인해 학습이 어려움&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이를 해결하기 위해 여러 방법이 나왔지만, 새로운 컴파일러 혹은 기존 라이브러리를 건드려야 한다는 불편함이 있음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;새로운 컴파일러나 기존 라이브러리를 변경하는 일 없이 간단한 방법으로 Model Parallelism 하는 Simple하면서도 Efficient한 방법 제안&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;​&lt;/p&gt;
&lt;h2&gt;Model Parallel Transformers&lt;/h2&gt;
&lt;img src=&quot;https://xiandong79.github.io/downloads/ddl1.png&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Transformer는 self attention block과 multi-layer perceptron (MLP) 로 구성되어 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;​&lt;/p&gt;
&lt;h3&gt;MLP Block&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/106810444-49996900-66b0-11eb-866b-062a4cad3eb6.png&quot;&gt;
&lt;p&gt;MLP Block Model Parallelism&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/106808899-59b04900-66ae-11eb-93a8-58d180bc1a70.png&quot;&gt;
&lt;p&gt;위의 공식을 따르는 MLP 블록을 Model Parallel하게 적용하기 위해서는 2가지 방법이 있을 수 있음.&lt;/p&gt;
&lt;p&gt;방법 1: 입력 X를 column으로, weight matrix A를 row로 split하는 방법.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/106809185-b6136880-66ae-11eb-87d7-693a2d5e56b7.png&quot;&gt;
&lt;p&gt;하지만 이 방법은 GeLU(X1A1 + X2A2) 6= GeLU(X1A1) + GeLU(X2A2)이 성립하지 않기 때문에 GeLU 입력 전에 동기화가 필요하다는 단점이 있음.&lt;/p&gt;
&lt;p&gt;방법 2: weight matrix A를 column으로 split하는 방법이 있음.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/106810580-85ccc980-66b0-11eb-88a5-acfbbb46c111.png&quot;&gt;
&lt;p&gt;이 방법은 위의 그림에서 볼 수 있듯이, GeLU 입력 전후로도 GPU간에 통신이 필요 없다는 장점이 있음.&lt;/p&gt;
&lt;h4&gt;정리&lt;/h4&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/106809827-7ef18700-66af-11eb-903b-ed0db12c2897.png&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Code&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nn &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; nn

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Method1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Module&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__init__&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;a1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Linear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bias&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;a2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Linear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bias&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;chunk&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dim&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        y1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;a1&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        y2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;a2&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; y1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; y2
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; y
    

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Method2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Module&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__init__&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;a1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Linear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bias&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;a2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Linear&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bias&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        y1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;a1&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        y2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;a2&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cat&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dim&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; y

gelu &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GELU&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;FloatTensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;FloatTensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;방법1 Test&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;GeLU(X1A1) + GeLU(X2A2) != GeLU(X1A1 + X2A2)\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gelu&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; end&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;\n\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gelu&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; gelu&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
GeLU&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;X1A1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; GeLU&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;X2A2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; GeLU&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;X1A1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; X2A2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.8413&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;2.9960&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;5.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;7.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;9.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;11.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;13.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
         &lt;span class=&quot;token number&quot;&gt;17.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;19.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.8413&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;2.7958&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;4.9504&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;6.9958&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;8.9999&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;11.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;13.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
         &lt;span class=&quot;token number&quot;&gt;17.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;19.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;방법2 Test&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;GeLU(concat(X1A1, X2A2)) == concat(GeLU(X1A1) + GeLU(X2A2))\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gelu&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cat&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; end&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;\n\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cat&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gelu&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; gelu&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
GeLU&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;concat&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;X1A1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; X2A2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; concat&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;GeLU&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;X1A1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; GeLU&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;X2A2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;0.8413&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;1.9545&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;2.9960&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;3.9999&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;5.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;6.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;7.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token number&quot;&gt;8.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;9.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.8413&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;1.9545&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;2.9960&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;3.9999&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;5.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;6.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;7.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;8.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token number&quot;&gt;9.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

tensor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;0.8413&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;1.9545&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;2.9960&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;3.9999&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;5.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;6.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;7.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token number&quot;&gt;8.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;9.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.8413&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;1.9545&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;2.9960&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;3.9999&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;5.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;6.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;7.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;8.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token number&quot;&gt;9.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10.0000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위의 코드에서 방법2로 계산시, Model Parallel하게 MLP Block을 진행할 수 있음을 알 수 있음.&lt;/p&gt;
&lt;p&gt;​&lt;/p&gt;
&lt;h2&gt;Attention Block&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/106810472-55852b00-66b0-11eb-8f4c-a0c9eca9ef28.png&quot;&gt;
&lt;ul&gt;
&lt;li&gt;MLP Block과 같은 방법으로 Model Parallelism을 적용할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;​&lt;/p&gt;
&lt;h2&gt;Model Parallelism&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/106812317-d6452680-66b2-11eb-88f7-76b1b62fade0.png&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;결과적으로 트랜스포머 블록 하나당 총 4번의 GPU간 통신만 있으면 되는 구조가 됨.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ALL-Reduce란 해당 블록의 결과물을 모든 프로세서가 Return하는 것을 의미함.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;​&lt;/p&gt;
&lt;h2&gt;Experiment&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/106813129-f0cbcf80-66b3-11eb-9597-5a6249bf49e0.png&quot;&gt;
&lt;p&gt;​&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Mac iTerm2 + ZSH 세팅]]></title><description><![CDATA[Mac iTerm2 + ZSH 세팅 개발환경에서 가장 중요한 소프트웨어 중 하나는 쉘입니다. 어떤 OS에서 작업하냐에 따라서 어떤 쉘을 쓰는지 등이 달라질텐데요, Mac OS에서 가장 많이 사용되는 iTerm2와 ZSH…]]></description><link>https://sooftware.github.io/iterm_zsh/</link><guid isPermaLink="false">https://sooftware.github.io/iterm_zsh/</guid><pubDate>Wed, 02 Dec 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Mac iTerm2 + ZSH 세팅&lt;/h1&gt;
&lt;p&gt;개발환경에서 가장 중요한 소프트웨어 중 하나는 쉘입니다. 어떤 OS에서 작업하냐에 따라서 어떤 쉘을 쓰는지 등이 달라질텐데요, Mac OS에서 가장 많이 사용되는 iTerm2와 ZSH를 설치하는 방법에 대해 포스팅해보겠습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;iTerm2 설치&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://iterm2.com/&quot;&gt;링크&lt;/a&gt;로 가게 되면 iTerm2를 설치할 수 있습니다. iTerm는 Mac의 기본 터미널보다 좀 더 확장된 기능을 제공해주는 소프트웨어입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;iTerm2 Color-Scheme 설치&lt;/h2&gt;
&lt;p&gt;개인적으로 개발할 때 IDE 혹은 쉘이 이뻐야 개발할 맛이 나서 저는 상당히 신경을 씁니다 ㅎㅎ..&lt;br&gt;
대표적으로 &lt;a href=&quot;https://github.com/mbadolato/iTerm2-Color-Schemes&quot;&gt;링크&lt;/a&gt;를 가시면 다양한 Color-Scheme을 다운받으실 수 있습니다.&lt;/p&gt;
&lt;p&gt;다운받은 후 iTerm2 &gt; Preference &gt; Profile &gt; colors로 들어가게 되면 아래와 같은 화면을 볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://miro.medium.com/max/1126/1*3eqvqUKzz84yJljncRWOAA.png&quot; alt=&quot;image1&quot;&gt;&lt;/p&gt;
&lt;p&gt;Color Presets를 눌러서 임의의 color-scheme을 import 후 설정해주면 됩니다.&lt;br&gt;
위에 걸어놓은 링크 외에도 iTerm Color Scheme라고만 구글에 쳐도 상당히 많은 수의 테마들이 나오게 됩니다.&lt;br&gt;
저는 dracula라는 테마를 사용중입니다. dracula 테마는 &lt;a href=&quot;https://github.com/dracula/dracula-theme&quot;&gt;링크&lt;/a&gt;에서 다운로드 가능합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;homebrew 설치&lt;/h2&gt;
&lt;p&gt;기존 리눅스에서의 apt-get과 같은 역할이라고 보시면 됩니다. 여러 소프트웨어를 손쉽게 다운받을 수 있게 해주는 프로그램입니다.&lt;br&gt;
iTerm2에서 아래 명령어를 실행해주세요.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/usr/bin/ruby -e &quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install.master/install)&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2&gt;ZSH 설치&lt;/h2&gt;
&lt;p&gt;제트쉘이라고 불리는 ZSH를 설치합니다. ZSH이란 일반적으로 사용한 쉘 보다 높은 수준의 기능들을 제공해주는 쉘입니다. 기본 쉘은 기능이 제한적이기 때문에 Z Shell을 이용한다면 더 강력하게 사용할 수 있습니다. 여기에 Oh My ZSH를 추가적으로 설치한다면 더 많은 추가기능을 사용할 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;zsh 설치&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;brew install zsh&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Oh My ZSH 설치&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;sh -C &quot;$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2&gt;기능 설정&lt;/h2&gt;
&lt;p&gt;여기까지 설치했다면 기본적인 설치는 끝났습니다. 이제 쉘을 더 강력하게 만들기 위해서는 아래 과정을 진행해야 합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;agnoster 테마 설치&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;%7B%7Bsite.baseurl%7D%7D/images/agnoster.png&quot; alt=&quot;agnoster&quot;&gt;&lt;/p&gt;
&lt;p&gt;agnoster 테마는 현재 디렉토리의 Git 상태를 알려줍니다. 현재 마스터브랜치인지 혹은 다른 브랜치인지, 커밋을 했는지 등을 알려줍니다.&lt;/p&gt;
&lt;h3&gt;zshrc 파일 수정&lt;/h3&gt;
&lt;p&gt;아래 명령어로 .zshrc 파일에 진입합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;vi ~/.zshrc&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h3&gt;agnoster 적용&lt;/h3&gt;
&lt;p&gt;위쪽에서 10번째쯤 줄에 ZSH_THEME=“robyrussell”라고 되어 있는 부분을 ZSH_THEME=“agnoster”로 수정해줍니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;MacBok-Pro 지우기&lt;/h3&gt;
&lt;p&gt;아마 따로 설정을 해주지 않으셨다면 위의 이미지와 다르게 쉘에 MacBook-Pro라고 입력란 앞쪽에 떠 있을겁니다. 이 부분이 거슬리는 분들은 zshrc 파일 하단에 아래 내용을 추가해줍니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;prompt_context() {
  if [[ &quot;$USER&quot; != &quot;$DEFAULT_USER&quot; || -n &quot;$SSH_CLIENT&quot; ]]; then
    prompt_segment black default &quot;%(!.%{%F{yellow}%}.)$USER&quot;
  fi
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h3&gt;New Line 적용&lt;/h3&gt;
&lt;p&gt;터미널에서 작업을 하다보면 경로가 복잡한 경우 이미 많은 텍스트 내용 때문에 명령어를 칠 경우 화면에서 벗어나서 보기 이쁘지 않은 경우가 많습니다. 명령어를 다음 줄에서 입력받도록 해주는 New Line을 적용해보겠습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;build_prompt() {
  RETVAL=$?
  prompt_status
  prompt_virtualenv
  prompt_context
  prompt_dir
  prompt_git
  prompt_bzr
  prompt_hg
  prompt_newline //이부분을 추가 꼭 순서 지켜서
  prompt_end
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;zshrc 파일에서 build_prompt를 찾아 prompt_end 위에 prompt_newline을 추가합니다. 다음 아래 코드를 추가합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;prompt_newline() {
  if [[ -n $CURRENT_BG ]]; then
    echo -n &quot;%{%k%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR
%{%k%F{blue}%}$SEGMENT_SEPARATOR&quot;
  else
    echo -n &quot;%{%k%}&quot;
  fi

  echo -n &quot;%{%f%}&quot;
  CURRENT_BG=&apos;&apos;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;저장을 해준 후 iTerm2에서 아래 명령어로 zshrc 파일의 수정사항을 반영해줍니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;source ~/.zshrc&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;여기까지 적용했다면 보통의 경우 위의 사진과 다르게 폰트가 깨지는 모습을 볼 수 있습니다. 깨지지 않는 폰트 사용을 위해 네이버에서 제공하는 D2Coding 폰트를 사용합니다. (&lt;a href=&quot;https://github.com/naver/d2codingfont&quot;&gt;https://github.com/naver/d2codingfont&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;위 링크로 들어가셔서 폰트를 설치하신 후 Preference &gt; Profile &gt; Text로 들어가셔서 폰트를 수정해주시면 됩니다.&lt;br&gt;
d2coding 폰트는 최신 폰트로 사용하셔야 폰트가 깨지지 않습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;마치며&lt;/h2&gt;
&lt;p&gt;이상으로 Mac OS에서 iTerm2 + ZSH 세팅에 대해 간단하게 살펴봤습니다.&lt;br&gt;
개발할 때 이런 툴의 사소한 기능 하나하나가 은근히 큰 차이를 만들어 내는 것 같습니다.&lt;br&gt;
처음 세팅할때 제대로 해놓으면 이후 개발할 때 편하게 사용할 수 있을 겁니다. 😎 😎&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - One Model, Many Languages: Meta-learning for Multilingual Text-to-Speech Paper Review]]></title><description><![CDATA[One Model, Many Languages: Meta-learning for Multilingual Text-to-Speech Tomáš Nekvinda, Ondřej Dušek Charles University INTERSPEECH, 202…]]></description><link>https://sooftware.github.io/one-model-many-langs/</link><guid isPermaLink="false">https://sooftware.github.io/one-model-many-langs/</guid><pubDate>Wed, 14 Oct 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;One Model, Many Languages: Meta-learning for Multilingual Text-to-Speech&lt;/h1&gt;
&lt;p&gt;Tomáš Nekvinda, Ondřej Dušek&lt;br&gt;
Charles University&lt;br&gt;
INTERSPEECH, 2020&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2008.00768&quot;&gt;ArXiv&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Tomiinek/Multilingual_Text_to_Speech&quot;&gt;Source Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tomiinek.github.io/multilingual_speech_samples/&quot;&gt;Demo Webpage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1703.10135&quot;&gt;Tacotron&lt;/a&gt;, &lt;a href=&quot;https://arxiv.org/abs/1712.05884&quot;&gt;Tacotron2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/pdf/1710.08969.pdf&quot;&gt;DC-TTS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Kyubyong/css10&quot;&gt;CSS 10 Dataset&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://commonvoice.mozilla.org/en/datasets&quot;&gt;Common Voice Dataset&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Multilingual Speech Synthesis&lt;/li&gt;
&lt;li&gt;Meta-learning&lt;/li&gt;
&lt;li&gt;Voice Cloning : Speech in multiple languages with the same voice&lt;/li&gt;
&lt;li&gt;Code switching : Speak two (or more) languages with a single utterance.&lt;/li&gt;
&lt;li&gt;Tacotron2 base architecture&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Tacotron&lt;/h2&gt;
&lt;img src=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwnGyQ%2FbtqDblNauXg%2FJsSXkwgQY1yc3lIHtdgIP0%2Fimg.png&quot; width=&quot;700&quot;&gt;
&lt;ul&gt;
&lt;li&gt;딥러닝 기반 음성합성의 대표적인 모델&lt;/li&gt;
&lt;li&gt;Attention + Sequence-to-Sequence의 TTS 버전&lt;/li&gt;
&lt;li&gt;Griffin-Lim Vocoder 사용 (빠르지만 성능은 좋지 못함)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Tacotron2&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/94840259-1cfbe900-0453-11eb-8803-cac2ea30b425.png&quot; width=&quot;470&quot;&gt;  
&lt;ul&gt;
&lt;li&gt;Mel-Prediction Network : Attention based Sequence-to-Sequence Network
&lt;ul&gt;
&lt;li&gt;인코더에서 Bi-directional LSTM 적용&lt;/li&gt;
&lt;li&gt;Location Sensitive Attention 적용 (음성 Alignment에 강한 어텐션)&lt;/li&gt;
&lt;li&gt;인코더, 디코더에 Convolution Layer 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Stop Token 사용&lt;/li&gt;
&lt;li&gt;Vocoder : WaveNet
&lt;ul&gt;
&lt;li&gt;장점 : 상당히 고품질의 음성으로 변환&lt;/li&gt;
&lt;li&gt;단점 : 엄청나게 느림&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Model Architecture&lt;/h2&gt;
&lt;img src=&quot;https://github.com/Tomiinek/Multilingual_Text_to_Speech/raw/master/_img/generated.png&quot; width=&quot;800&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Tacotron2 기반의 모델들로 실험 진행&lt;/li&gt;
&lt;li&gt;WaveRNN Vocoder 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;This Paper`s Model: Generated (GEN)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Parameter Generation Convolutional Encoder&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이 논문에서는 Fully convolutional encoder를 사용 (from DC-TTS)&lt;/li&gt;
&lt;li&gt;Cross-lingual knowledge-sharing을 가능하게 하기 위해 인코더 컨볼루션 레이어의 파라미터를 생성하여 사용&lt;/li&gt;
&lt;li&gt;입력되는 Language ID에 따라 Fully Connected 레이어를 통해 다른 다른 파라미터를 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Speaker Embedding&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Multi-speaker, Cross-lingual voice cloning을 위해 Speaker Embedding을 사용&lt;/li&gt;
&lt;li&gt;인코더 아웃풋에 Concatenate하여 스펙트로그램 생성시에 반영되도록 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Adversarial Speaker Classifier&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이상적으로 Voice cloning을 위해서는 텍스트(언어)로부터 화자의 정보가 반영되면 안됨&lt;/li&gt;
&lt;li&gt;Speaker Classifier와 나머지 모델(인코더, 디코더)은 forward에서는 독립적이지만,  backpropagation을 진행할 때, 두 loss (L2 of predict spectrogram, cross entropy of predicted speaker ID)가 인코더 파라미터 업데이트에 영향을 미침&lt;/li&gt;
&lt;li&gt;Gradient reversal layer를 통해 인코더가 speaker에 대한 정보를 반영 못하도록 학습&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Baselines: Shared, Separate &amp;#x26; Single&lt;/h3&gt;
&lt;p&gt;※ GEN과 다른점만 비교&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Single (SGL)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Monolingual Vanilla Tacotron 2 (Code-switching에 사용 X)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shared (SHA)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;GEN과 다르게 Tacotron 2의 인코더 사용 (Multilingual)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Separate (SEP)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;GEN과 같이 Multiple convolution layer를 사용&lt;/li&gt;
&lt;li&gt;Parameter generation 사용 X&lt;/li&gt;
&lt;li&gt;Adversarial speaker classifier 사용 X&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Dataset&lt;/h2&gt;
&lt;p&gt;10개의 언어로 구성된 CSS10과 Common Voice 데이터셋의 일부를 사용
Code-switching을 학습하기 위해 multi-speaker 데이터가 필요 (언어와 화자 일치를 없애기 위해)&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/95888064-9680c900-0dbb-11eb-9967-a30b21dbfa80.png&quot; width=&quot;600&quot;&gt;  
&lt;h2&gt;Experiment&lt;/h2&gt;
&lt;p&gt;SGL, SHA, SEP, GEN을 비교했을 때 GEN이 거의 모든 결과에서 우수한 성능을 보임&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/95888889-a816a080-0dbc-11eb-81a9-9a2d036f2def.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/95888982-cbd9e680-0dbc-11eb-984f-1524ab3a9f38.png&quot; width=&quot;400&quot;&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;본 논문에서 제안하는 모델은 Multilingual Voice cloning, Code-switching에 우수한 성능을 보임&lt;/li&gt;
&lt;li&gt;추후 연구로 어텐션 모듈을 수정하는 것을 생각중이라고 함&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - RoBERTa Paper Review]]></title><description><![CDATA[RoBERTa paper / code Abstract BERT를 제대로 학습시키는 법을 제안 BERT는 엄청난 모델이지만, Original BERT 논문에서 하이퍼파라미터에 대한 실험이 제대로 진행되지 않음 BERT…]]></description><link>https://sooftware.github.io/roberta/</link><guid isPermaLink="false">https://sooftware.github.io/roberta/</guid><pubDate>Sun, 11 Oct 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;RoBERTa&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1907.11692&quot;&gt;paper&lt;/a&gt; / &lt;a href=&quot;https://github.com/pytorch/fairseq/tree/master/examples/roberta&quot;&gt;code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;BERT를 제대로 학습시키는 법을 제안&lt;/li&gt;
&lt;li&gt;BERT는 엄청난 모델이지만, Original BERT 논문에서 하이퍼파라미터에 대한 실험이 제대로 진행되지 않음&lt;/li&gt;
&lt;li&gt;BERT를 더 좋은 성능을 내게 하기 위한 replication study.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Background (BERT)&lt;/h2&gt;
&lt;img src=&quot;https://baekyeongmin.github.io/images/RoBERTa/bert.png&quot; width=&quot;700&quot;&gt;
&lt;ul&gt;
&lt;li&gt;학습 1단계) 많은 양의 unlabeled corpus를 이용한 pre-train&lt;/li&gt;
&lt;li&gt;학습 2단계) 특정 도메인의 태스크에 집중하여 학습하는 fine-tuning&lt;/li&gt;
&lt;li&gt;“Attention Is All You Need”에서 제안된 transformer의 encoder를 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Main Idea&lt;/h2&gt;
&lt;h3&gt;Dynamic Masking&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;기존의 BERT는 학습 전에 데이터에 무작위로 mask를 씌움.&lt;/li&gt;
&lt;li&gt;매 학습 단계에서 똑같은 mask를 보게 됨. (static masking)&lt;/li&gt;
&lt;li&gt;이를 같은 문장을 10번 복사한 뒤 서로 다른 마스크를 씌움으로써 해결하려고 했지만, 이는 크기가 큰 데이터에 대해서 비효율적임.&lt;/li&gt;
&lt;li&gt;RoBERTa는 매 에폭마다 mask를 새로 씌우는 dynamic masking을 사용&lt;/li&gt;
&lt;li&gt;결과: static masking보다 좋은 성능을 보여줌&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Input Format / Next Sentence Prediction&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;기존 BERT에서는 Next Sentence Prediction(NSP)이라는 과정이 있었음
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;두 개의 문장을 이어 붙인다&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;두 문장이 문맥상으로 연결된 문장인지를 분류하는 binary classification을 수행&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RoBERTa는 NSP에 의문을 제기하고, Masked Language Modeling (MLM)만으로 pre-training을 수행&lt;/li&gt;
&lt;li&gt;NSP를 없앰으로써 두 문장을 이어 붙인 형태의 인풋 형태를 사용할 필요가 없어졌고, RoBERTa는 최대 토큰 수를 넘어가지 않는 선에서 문장을 최대한 이어 붙여서 input을 만들 수 있었음&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[CLS]가나다라마바사아자카타파하[SEP]오늘 날씨가 좋은걸?[SEP]튜닙은 정말 대단한 회사야!.....[SEP]오늘은 빨리 퇴근하고 싶다.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;BERT는 짧은 인풋들을 이어붙이는 경우도 있었지만, RoBERTa는 모든 인풋 토큰 수를 최대길이에 가깝게 사용할 수 있었음 (학습 효율면에서 좋음)&lt;/li&gt;
&lt;li&gt;결과: NSP를 없앤 BERT가 기존의 BERT보다 더 나은 성능을 보임.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Batch Size&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;(batch size X step 수)가 일정하게 유지되는 선에서 배치사이즈에 따른 성능 실험
&lt;ul&gt;
&lt;li&gt;batch size가 256에 step이 1M이라면 batch size가 2K에 step이 125K가 되도록. (둘의 곱이 같도록 유지)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;배치가 클수록 성능이 좋아지는 경향을 보임.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Data&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;데이터가 많을수록 BERT의 성능이 좋아지는 경향을 이전 연구들에서 관찰됐었음.&lt;/li&gt;
&lt;li&gt;기존 BERT는 16GB로 학습했는데, RoBERT는 160GB의 데이터로 학습하였음.&lt;/li&gt;
&lt;li&gt;당연하게도 160GB로 학습한 RoBERTa가 더 좋은 성능을 기록함&lt;/li&gt;
&lt;li&gt;학습 시간을 길게 하면 할수록 더 좋은 성능을 보였다고함.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;160GB의 데이터&lt;/li&gt;
&lt;li&gt;Dynamic Masking&lt;/li&gt;
&lt;li&gt;NSP 밴&lt;/li&gt;
&lt;li&gt;최대한 문장을 구겨넣은 인풋 ([SEP]으로 분리)&lt;/li&gt;
&lt;li&gt;큰 배치사이즈&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Electra Paper Review]]></title><description><![CDATA[Below is just about everything you’ll need to style in the theme. Check the source code to see the many embedded elements within paragraphs…]]></description><link>https://sooftware.github.io/electra/</link><guid isPermaLink="false">https://sooftware.github.io/electra/</guid><pubDate>Wed, 23 Sep 2020 10:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Below is just about everything you’ll need to style in the theme. Check the source code to see the many embedded elements within paragraphs.&lt;/p&gt;
&lt;hr&gt;
&lt;h1&gt;ELECTRA&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://openreview.net/forum?id=r1xMH1BtvB&quot;&gt;paper&lt;/a&gt; / &lt;a href=&quot;https://github.com/google-research/electra&quot;&gt;code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ICLR 2020&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;BERT에서 제안한 Masked Language Modeling(MLM)은 좋은 성능을 보여줬지만, 전체 데이터의 15%만을 마스킹해서 학습 효율 측면에서 좋지 않음.&lt;/li&gt;
&lt;li&gt;ELECTRA는 &lt;strong&gt;모델의 성능&lt;/strong&gt;과 함께 &lt;strong&gt;학습의 효율성&lt;/strong&gt;도 개선할 수 있는 방법을 제안함.&lt;/li&gt;
&lt;li&gt;Replaced Token Detection(RTD)라는 새로운 pre-training 태스크 제안.&lt;/li&gt;
&lt;li&gt;ELECTRA의 장점은 Small 모델에서 두드러짐. 1개의 GPU로 4일만 학습한 모델로 계산량이 30배인 GPT를 능가.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Replaced Token Detection (RTD)&lt;/h2&gt;
&lt;img src=&quot;https://blog.pingpong.us/images/2020.05.08.electra/figure2.png&quot; width=&quot;700&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Generator: BERT의 MLM
&lt;ul&gt;
&lt;li&gt;입력된 인풋 중 15%의 토큰을 [MASK]로 가림&lt;/li&gt;
&lt;li&gt;[MASK]로 가려진 인풋의 원래 토큰을 예측&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Discriminator
&lt;ul&gt;
&lt;li&gt;입력 토큰 시퀀스에 대해서 각 토큰이 original인지 replaced인지 이진 분류로 학습&lt;/li&gt;
&lt;li&gt;학습 과정
&lt;ol&gt;
&lt;li&gt;Generator에서 마스킹 된 입력 토큰들을 예측&lt;/li&gt;
&lt;li&gt;마스킹할 위치의 토큰에 대해 generator가 예측했던 softmax 분포에서 높은 순위의 토큰 중 하나로 치환 (1위: cooked, 2위: ate, 3위: … 이였으면 MLM은 cooked를 선택하지만 해당 과정에서 ate를 가져오는 방식)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Original input : [the, chef, cooked, the, meal]&lt;/li&gt;
&lt;li&gt;Input for generator : [[MASK], chef, [MASK], the, meal]&lt;/li&gt;
&lt;li&gt;Input for discriminator : [the, chef, ate, the, meal]&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;치환된 입력에 대해 discriminator는 원래 입력과 동일한지 치환된 것인지를 이진 분류로 예측&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Training Algorithm&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Jointly 학습
&lt;ul&gt;
&lt;li&gt;Generator와 Discriminator를 동시에 학습시키는 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Two-stage 학습
&lt;ol&gt;
&lt;li&gt;Generator만 MLM으로 N 스텝동안 학습&lt;/li&gt;
&lt;li&gt;뒤이어 해당 모델을 Discriminator로 N 스텝동안 학습시키는 방식 (이때 Generator의 웨이트는 고정)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Adversarial 학습
&lt;ul&gt;
&lt;li&gt;Adversarial training을 모사해서 학습시키는 방식 (jointly보다 좋지 않아서 자세히 안 봤습니다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Result&lt;/h2&gt;
&lt;h3&gt;Performance &amp;#x26; Efficiency&lt;/h3&gt;
&lt;img src=&quot;https://blog.pingpong.us/images/2020.05.08.electra/figure1.png&quot; width=&quot;700&quot;&gt;
&lt;ul&gt;
&lt;li&gt;다른 모델들에 비해 매우 빠르게 성능이 향상되는 것을 볼 수 있음&lt;/li&gt;
&lt;li&gt;그럼에도 불구하고, 기존 BERT보다 더 좋은 성느을 기록함.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Weight Sharing&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Generator와 discriminator는 모두 트랜스포머의 인코더 구조.&lt;/li&gt;
&lt;li&gt;그렇기 때문에 3가지 선택사항이 생김.
&lt;ol&gt;
&lt;li&gt;Generator, Discriminator가 서로 독립적으로 학습 (83.5)&lt;/li&gt;
&lt;li&gt;임베딩 레이어의 웨이트만 공유 (84.3)&lt;/li&gt;
&lt;li&gt;모든 레이어의 웨이트를 공유 (84.4)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;결과적으로 모든 웨이트를 공유하는 것이 가장 좋은 성능을 보임.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Training Algorithm&lt;/h3&gt;
&lt;img src=&quot;https://blog.pingpong.us/images/2020.05.08.electra/figure3.png&quot; width=&quot;700&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Jointly 방식이 가장 성능이 좋았음 (왼쪽은 discriminator와 generator의 사이즈에 따른 실험)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;더 효율적이고 효과도 좋은 Replaced Token Detection (RTD) 제안&lt;/li&gt;
&lt;li&gt;메인 아이디어는 Generator가 만들어 낸 질 좋은 negative sample로 학습함으로써 더 적은 리소스로 모델을 더욱 견고하게 만드는 것.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - Wav2vec 2.0 : A Framework for Self-Supervised Learning of Speech Representations]]></title><description><![CDATA[wav2vec 2.0 : A Framework for Self-Supervised Learning of Speech Representations Alexei Baevski, Henry Zhou, Abdelrahman Mohamed, Michael…]]></description><link>https://sooftware.github.io/wav2vec2/</link><guid isPermaLink="false">https://sooftware.github.io/wav2vec2/</guid><pubDate>Sat, 12 Sep 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;wav2vec 2.0 : A Framework for Self-Supervised Learning of Speech Representations&lt;/h1&gt;
&lt;p&gt;Alexei Baevski, Henry Zhou, Abdelrahman Mohamed, Michael Auli&lt;br&gt;
Facebook AI Research (FAIR)&lt;br&gt;
arXiv (2020.06)&lt;/p&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2006.11477&quot;&gt;arXiv&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pytorch/fairseq/tree/master/examples/wav2vec&quot;&gt;source code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1810.04805&quot;&gt;BERT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/pdf/1904.05862.pdf&quot;&gt;Wav2vec&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/pdf/1910.05453.pdf&quot;&gt;VQ-Wav2vec&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ratsgo.github.io/speechbook/docs/neuralfe/wav2vec&quot;&gt;speech book&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;BERT in Speech Recognition&lt;/li&gt;
&lt;li&gt;Representation learning with 53,000 hours of unlabeled speech data.&lt;/li&gt;
&lt;li&gt;Excellent speech recognition performance with only 40 sentences (10 minutes) of labeled data&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;음성 데이터 자체만으로 학습한 후 Fine-tuning하는 간단한 방법으로 semi-supervised 방법보다 좋은 성능을 냄&lt;/li&gt;
&lt;li&gt;TIMIT, LibriSpeech 100h 데이터셋에서 State-Of-The-Art (SOTA) 를 달성&lt;/li&gt;
&lt;li&gt;LibriSpeech 100h은 단 1시간의 데이터만으로 기존 SOTA보다 높은 성능을 보임&lt;/li&gt;
&lt;li&gt;단 10분의 데이터 (40문장) 으로 LibriSpeech clean 5.7 / noisy 10.1 Word Error Rate (WER) 를 기록&lt;/li&gt;
&lt;li&gt;LibriSpeech의 전체 학습셋을 사용했을 때 (960h) clean 1.9 / noisy 3.5 WER을 기록 (현재 &lt;a href=&quot;https://github.com/syhw/wer_are_we&quot;&gt;wer-are-we&lt;/a&gt; SOTA보다 높은 기록)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Wav2vec&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;현재 어느 정도 수준 이상의 음성인식기를 만들기 위해서는 대량의 데이터가 필요함 (수천 시간)&lt;/li&gt;
&lt;li&gt;세상에는 7,000개 이상의 언어가 존재하는데 모든 언어에 대해 이 정도 수준의 데이터를 구축하기는 어려움&lt;/li&gt;
&lt;li&gt;영아 (infant) 들은 단순히듣는 것만으로 음성에 대해 학습함&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Wav2vec 1.0 (previous work)&lt;/h3&gt;
&lt;img src=&quot;https://i.imgur.com/H9X1HiX.png&quot; width=&quot;500&quot;&gt;    
&lt;ul&gt;
&lt;li&gt;wav2vec은 크게 &lt;em&gt;encoder&lt;/em&gt; network &lt;em&gt;f&lt;/em&gt;와 &lt;em&gt;context&lt;/em&gt; network &lt;em&gt;g&lt;/em&gt; 두개의 파트로 구성 (둘 모두 convolution neural network)&lt;/li&gt;
&lt;li&gt;wav2vec은 해당 입력이 Positive인지 Negative인지 이진 분류(Binary Classification)하는 과정에서 학습&lt;/li&gt;
&lt;li&gt;Positive : (C&lt;sub&gt;i&lt;/sub&gt;, Z&lt;sub&gt;i+1&lt;/sub&gt;), Negative : otherwise&lt;/li&gt;
&lt;li&gt;Negative 쌍은 입력 음성의 i번째 context representation C&lt;sub&gt;i&lt;/sub&gt;와 다른 음성의 hidden representation들 중 랜덤 추출&lt;/li&gt;
&lt;li&gt;즉, 2개의 네트워크는 입력 음성의 다음 시퀀스가 무엇일지에 관한 정보를 음성 피처에 녹여내도록 학습&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;VQ-Wav2vec (previous work)&lt;/h3&gt;
&lt;img src=&quot;https://i.imgur.com/ivviYL1.png&quot; width=&quot;500&quot;&gt;  
&lt;ul&gt;
&lt;li&gt;Wav2vec 아키텍처 중간에 &lt;strong&gt;Vector Quantization&lt;/strong&gt; 모듈을 추가한 구조&lt;/li&gt;
&lt;li&gt;VQ 모듈 : continuous representation Z를 discrete representation Z&lt;sup&gt;^&lt;/sup&gt;로 변환&lt;/li&gt;
&lt;li&gt;Discretization(이산화)는 discrete한 input을 필요로하는 NLP 알고리즘들을 바로 적용할 수 있다는 장점이 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Vector Quantization&lt;/h4&gt;
&lt;img src=&quot;https://i.imgur.com/y15Qu5Z.png&quot; width=&quot;300&quot;&gt;  
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Z를 선형변환하여 logit을 만듦&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;여기에 Gumbel Softmax와 argmax를 취해 one-hot vector를 만듦&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이후 Embedding matrix를 내적해 Z&lt;sup&gt;^&lt;/sup&gt;를 만듦&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Wav2vec 2.0&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/92450554-8a22b280-f1f6-11ea-8f66-0616b29d8c94.png&quot; width=&quot;500&quot;&gt;  
&lt;ul&gt;
&lt;li&gt;VQ-wav2vec의 모델을 Transformer로 대체&lt;/li&gt;
&lt;li&gt;Pre-training 이후 labeled data로 fine-tuning (Connectionist Temporal Classification (CTC) loss 사용)&lt;/li&gt;
&lt;li&gt;이전 연구들과의 차이점으로 Filter-Bank와 같은 피쳐추출 과정이 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Model&lt;/h2&gt;
&lt;p&gt;VQ-Wav2vec와 비교하여 Transformer를 사용했다는 특징이 있음&lt;/p&gt;
&lt;h3&gt;Feature Encoder&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;N x [Conv1d, Dropout, GroupNorm, GELU]&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Transformer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Positional Encoding을 conv1d로 대체&lt;/li&gt;
&lt;li&gt;Convoulation Layer 뒷단에 layer normalization 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Quantization module&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Vector Quantization 부분 참고&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Training&lt;/h2&gt;
&lt;p&gt;BERT의 masked language modeling (MLM)과 유사하게 latent speech의 일부분을 masking하며, 모델은 quantized latent audio representation을 맞추는 방식으로 트레이닝이 진행됨. 이렇게 학습한 후 labeled 된 데이터로 fine-tuning 진행.&lt;/p&gt;
&lt;h3&gt;Masking&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Maksing 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;1. 전체 오디오 구간 중 6.5%를 랜덤하게 선택  
  
2. 선택된 구간부터 10 time-step만큼 masking (masking은 중복될 수 있음)   &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;전체 오디오 구간 중 약 49% 정도가 masking (평균 14.7 timestep (299ms))&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Objective&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/93301173-0474b780-f833-11ea-8206-5ab40cf418a5.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;L&lt;sub&gt;m&lt;/sub&gt; : Contrastive Loss, L&lt;sub&gt;d&lt;/sub&gt; : Diversity Loss, L&lt;sub&gt;f&lt;/sub&gt; : L2 penalty, {alpha, beta} : hyperparameter&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Contrastive Loss&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/92514957-c5040500-f24d-11ea-95c3-1183fa1145b2.png&quot; alt=&quot;contrastive-loss&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Diversity Loss&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/92514997-df3de300-f24d-11ea-835c-f1367aef5ebe.png&quot; alt=&quot;diversity-loss&quot;&gt;&lt;/p&gt;
&lt;h3&gt;Fine-tuning&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;이렇게 Pre-train 된 모델을 ASR 태스크로 Fine-tuning (+ projection layer)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;29 character token&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CTC Loss&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SpecAugment&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Experiment&lt;/h2&gt;
&lt;h3&gt;Datasets&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Unlabeled data 1 : LibriVox-60k (전처리하여 53.2k 사용) [&lt;a href=&quot;https://arxiv.org/abs/1912.07875&quot;&gt;Reference&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;Unlabeled data 2 : LibriSpeech 960h&lt;/li&gt;
&lt;li&gt;train-10min, train-1h, train-10h, train-100h, train-960h 설정 (LibriSpeech)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Result&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;WER on the Librispeech dev/test sets when training on the Libri-light low-resource labeled&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;data setups of 10 min, 1 hour, 10 hours and the clean 100h subset of Librispeech&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/92516234-de0db580-f24f-11ea-88f3-485ee579bfda.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WER on Librispeech when using all labeled data of 960 hours&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/92516409-262cd800-f250-11ea-8e77-42fdc8761d2c.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;적은 비용으로도 좋은 성능의 음성인식기를 만들 수 있는 연구 방향을 제시함&lt;/li&gt;
&lt;li&gt;Seq2seq 구조 혹은 word-piece 단위로의 변경을 통해 성능 향상 기대&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - Conformer Paper Review]]></title><description><![CDATA[Conformer: Convolution-augmented Transformer for Speech Recognition Anmol Gulati et al. Google Inc. INTERSPEECH, 2020 Reference Conformer…]]></description><link>https://sooftware.github.io/conformer/</link><guid isPermaLink="false">https://sooftware.github.io/conformer/</guid><pubDate>Sun, 30 Aug 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Conformer: Convolution-augmented Transformer for Speech Recognition&lt;/h1&gt;
&lt;p&gt;Anmol Gulati et al.&lt;br&gt;
Google Inc.&lt;br&gt;
INTERSPEECH, 2020&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/pdf/2005.08100.pdf&quot;&gt;Conformer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1706.03762&quot;&gt;Attention Is All You Need&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hichoe95.tistory.com/48&quot;&gt;Convolution&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Transformer 기반 모델이 음성인식 분야에서 좋은 성능을 보이고 있음&lt;/li&gt;
&lt;li&gt;Self-attention 기반한 트랜스포머는 global-context 정보를 잘 표현하지만, local-context에서는 부족하다는 단점이 있음&lt;/li&gt;
&lt;li&gt;반면, CNN 기반 모델은 local-context는 잘 표현하지만 global-context를 반영하기 위해서는 적당한 dilation과 깊은 구조를 가져야 함&lt;/li&gt;
&lt;li&gt;이 두 방법을 결합하여 global-context와 local-context 모두 잘 표현할 수 있도록 하기 위한 transformer + CNN 결합구조인 Conformer 구조 제안&lt;/li&gt;
&lt;li&gt;Conformer Encoder + Transducer 구조&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;Conformer Encoder&lt;/h2&gt;
&lt;p&gt;기존 트랜스포머 블록과 다르게 2개의 Feed Forward Network (FFN)에 쌓인 Sandwich 방식으로 구성&lt;/p&gt;
&lt;h3&gt;Conformer encoder model architecture&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/105320076-16af9980-5c09-11eb-86ec-b5146ac65812.png&quot; width=&quot;500&quot;&gt;   
&lt;p&gt;기존 트랜스포머 인코더 블록은 &lt;code class=&quot;language-text&quot;&gt;Multi Head Self Attention (MHSA) → LayerNorm → Feed Forward Network (FFN) → LayerNorm&lt;/code&gt; 구조에서 &lt;code class=&quot;language-text&quot;&gt;FFN Module → MHSA Module → Conv Module → FFN Module → LayerNorm&lt;/code&gt; 구조로 변경&lt;/p&gt;
&lt;h3&gt;Multi-Headed Self-Attention Module&lt;/h3&gt;
&lt;img src=&quot;https://images.deepai.org/converted-papers/2005.08100/x3.png&quot;&gt;  
&lt;ul&gt;
&lt;li&gt;Relative positional encoding&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;절대적인 position 정보를 더하는 방식이 아닌, 상대적인 position 정보를 주는 방식
절대적인 position 정보가 a=1, b=2와 같이 값을 지정하고 그 값의 차이를 계산하는 방식이라면, 상대적인 position 정보는 a=1, b=2이든 a=5, b=6이든 상관없이 두 수(위치)의 차이가 1이라는 것만 알려주면 되는 방식&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;이런 방식은 가변적인 시퀀스 길이 인풋에 대해 인코더를 robust하게 만들어 줌&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Pre-norm&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;기존 트랜스포머는 Post-norm인데 반해, pre-norm 적용&lt;br&gt;
이전 연구들에서 pre-norm은 깊은 모델 학습이 원활하게 되도록 도와주는 효과가 있다고 알려짐&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Convolution Module&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/105454437-30aeb200-5cc5-11eb-8624-1ea49b71c8cd.png&quot; width=&quot;500&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Pointwise Conv&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8hxuL%2Fbtqw5f6QxMM%2Fk4gn4DUTEqPkqbJXusPAKk%2Fimg.png&quot; width=&quot;400&quot;&gt;  
&lt;blockquote&gt;
&lt;p&gt;kernel size가 1x1로 고정된 convolution
dimension을 맞출 때 자주 쓰임&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;GLU Activation&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://miro.medium.com/max/1400/1*EwUvi3ATcVoa9Lm-2FwNUA.png&quot; width=&quot;500&quot;&gt;  
&lt;img src=&quot;https://miro.medium.com/max/1400/1*4UZTVLQZSDV7gCsw2cn16Q.png&quot; width=&quot;500&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Depthwise Conv&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbw6Am5%2Fbtqw4n45UWN%2FqNYnywQjSGkzkOtl5Pkzc1%2Fimg.png&quot;&gt;  
&lt;blockquote&gt;
&lt;p&gt;그룹이 채널수와 같은 Group-Convolution. 각 channel마다의 spatial feature를 추출하기 위해 고안된 방법&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Conv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;in_channels&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; out_channels&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; group&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Swish activation&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://blog.kakaocdn.net/dn/QbxpI/btqEHxducIg/hrmYfDLHDT4N1oqCtt74CK/img.png&quot; width=&quot;400&quot;&gt;
&lt;h3&gt;Feed Forward Module&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/1694368/103190710-1b847480-490d-11eb-8ea5-280749a32a24.png&quot; width=&quot;500&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;Pre-norm 적용&lt;br&gt;
Swish activation : regularizing에 도움&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;Conformer Block&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/pdf/1906.02762.pdf&quot;&gt;Macaron-Net&lt;/a&gt;에 영감을 받아서 2개의 FFN에 쌓인 Sandwich 구조로 구성.&lt;br&gt;
FFN 모듈에 half-step residual connection 적용&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/105326425-13b8a700-5c11-11eb-804c-bd8efef6060b.png&quot; width=&quot;400&quot;&gt;  
&lt;blockquote&gt;
&lt;p&gt;뒤의 Ablation study에서 Macaron-net FFN과 half-step residual connection이 성능 향상에 많은 기여를 했다고 함&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;Experiment&lt;/h2&gt;
&lt;h3&gt;Data&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;LibriSpeech&lt;/li&gt;
&lt;li&gt;80 channel filterbank, 25ms window, 10ms stride&lt;/li&gt;
&lt;li&gt;SpecAugment (F=27), ten time masks (maximum ratio 0.05)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Conformer Transducer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Three models: 10M, 30M, and 118M params&lt;/li&gt;
&lt;li&gt;Decoder: single LSTM-layer (Transducer)&lt;/li&gt;
&lt;li&gt;Dropout ratio: 0.1&lt;/li&gt;
&lt;li&gt;Adam optimizer, β1=0.9, β2=0.98 and έ=10^-9&lt;/li&gt;
&lt;li&gt;Learning rate scheduler: transformer lr scheduler, 10k warm-up steps&lt;/li&gt;
&lt;li&gt;3-layer LSTM language model (LM) with 4096 hidden dimension (shallow fusion)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Results on LibriSpeech&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/105327556-5cbd2b00-5c12-11eb-8714-2c0ce2c7a1b0.png&quot; width=&quot;500&quot;&gt;  
&lt;hr&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/105327620-752d4580-5c12-11eb-9091-433ce8700141.png&quot; width=&quot;500&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Conformer Block vs Transformer Block (without external LM)&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/105327876-c9d0c080-5c12-11eb-8b02-948f87c5f47d.png&quot; width=&quot;500&quot;&gt;
&lt;hr&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/105328157-1916f100-5c13-11eb-9473-69ac0c658e15.png&quot; width=&quot;500&quot;&gt;  
&lt;hr&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/105328196-2338ef80-5c13-11eb-9e8a-50ff45bad7b5.png&quot; width=&quot;500&quot;&gt;
&lt;hr&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/105328376-54b1bb00-5c13-11eb-9059-38bc7361ba6d.png&quot; width=&quot;500&quot;&gt;
&lt;hr&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/105328408-5aa79c00-5c13-11eb-94b2-8ee455c8daca.png&quot; width=&quot;500&quot;&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Transformer + CNN 구조인 Conformer를 제안했고, 이를 잘 결합하기 위한 다양한 실험을 해서 결과를 냄.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - AI & Speech Processing: Application-2]]></title><description><![CDATA[AI & Speech Processing: Application-2 본 글은 광운대학교 전자공학과 박호종 교수님의 강의를 듣고 작성되었음을 밝힙니다. Speaker Verification and Identification Verification…]]></description><link>https://sooftware.github.io/audio_app2/</link><guid isPermaLink="false">https://sooftware.github.io/audio_app2/</guid><pubDate>Fri, 17 Apr 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;AI &amp;#x26; Speech Processing: Application-2&lt;/h1&gt;
&lt;p&gt;본 글은 광운대학교 전자공학과 박호종 교수님의 강의를 듣고 작성되었음을 밝힙니다.&lt;/p&gt;
&lt;h2&gt;Speaker Verification and Identification&lt;/h2&gt;
&lt;h3&gt;Verification (인증)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78555116-50184380-7847-11ea-8ff3-c6c393d6402c.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;음성신호에서 개인별 고유 정보를 추출하여 &lt;strong&gt;본인 검증&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;Identification (인식)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78551433-afbf2080-7840-11ea-96f9-176458bae5dd.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;여러 음성 신호에서 &lt;strong&gt;특정인 검색&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ex) Smartphone 지문 인식 문제&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78553517-59ec7780-7844-11ea-8a81-300778187510.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Why Bio 인증?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;기존 비밀번호보다 편리?&lt;/p&gt;
&lt;p&gt;기존 비밀번호보다 안전?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78553891-0890b800-7845-11ea-94f4-7acd4be09065.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;Voice를 이용한 보안의 문제점은 테러범의 핸드폰 같은 경우, 지문 혹은 얼굴 인식과 달리 본인이 마음 먹지 않으면 절대 풀 수가 없음.&lt;/p&gt;
&lt;h2&gt;Sound Recognition / Detection&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;인간과 동일한 sound 정보 인식&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Robot

아기 울음소리 / 동물소리 인식

자율주행 
:: 자율주행에서도 소리로 특징을 포착하는 기술이 필요 (구글은 사이렌 소리를 인식)

청각장애&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;인간 능력 이상의 sound 정보 인식&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;불법 벌목 감청 (구글이 도입)

멸종위기 고래 탐지&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Music Information Analysis&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78554986-1c3d1e00-7847-11ea-94c0-020f85549942.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;음악 검색, Hit 가능성 여부 예측, 인공 작곡 + 감정&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Content 기반으로 Music 검색 / Retrieval&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;노래 일부분의 음만을 가지고 찾고싶은 노래 검색  

표절 확인

자동 노래 선곡 시스템&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Speech and Audio Coding&lt;/h2&gt;
&lt;p&gt;전송 또는 저장을 위한 디지털 데이터양을 감소시키는 기술&lt;/p&gt;
&lt;p&gt;=&gt; 거의 완벽하게 산업화에 성공&lt;/p&gt;
&lt;p&gt;디지털 이동 통신, portable music의 핵심&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78555377-d9c81100-7847-11ea-9987-cdcf3d884ad5.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;현재의 연구 동향&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;모든 종류의 sound를 통합적으로 처리&lt;br&gt;
(기존에는 speech codec, audio codec으로 구분)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;국제 기관 (ITU, ISO 등)에서 표준 codec 선정&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3D Audio / 입체 음향&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78555735-9d48e500-7848-11ea-852b-56129ba59960.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Audio for Virtual Reality&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78555846-d3866480-7848-11ea-9abf-fa4b18b994c6.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;h2&gt;디지털 오디오 방송&lt;/h2&gt;
&lt;h3&gt;객체(Object) 기반 디지털 오디오 방송&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78557966-beabd000-784c-11ea-9d56-ca474c336ae5.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;오디오 객체별로 신호 전송&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;사용자가 sound를 임의로 선택하여 청취&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sports 중계 방송, 음악 방송, 드라마&lt;/li&gt;
&lt;li&gt;언어 선택 (외국어로 방송 청취)&lt;/li&gt;
&lt;li&gt;입체 음향 청취&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;사용자는 원하는 오디오를 선택하여 청취&lt;/p&gt;
&lt;h2&gt;잡음 제거&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78558545-bb651400-784d-11ea-842a-9565d373a9ea.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;잡음을 제거하는 간단한 방법으로 마이크를 여러개 설치한다.&lt;/p&gt;
&lt;p&gt;Active Noise Cancellation (ANC)&lt;br&gt;
=&gt; Airpod Pro에 탑재된 기술 (주변 소음 제거)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78558732-1860ca00-784e-11ea-9656-f8eab0578c1d.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;들어오는 소리의 파형과 반대되는 파형을 더해줌으로써 0으로 만들어줌&lt;/p&gt;
&lt;h2&gt;기타&lt;/h2&gt;
&lt;h3&gt;신호 복원 : 왜곡되고 변형된 신호를 원 신호로 복원&lt;/h3&gt;
&lt;h3&gt;Sound type 분리&lt;/h3&gt;
&lt;h3&gt;Multimedia DB에서 Audio 특성으로 원하는 장면 검색&lt;/h3&gt;
&lt;h3&gt;의료 신호처리&lt;/h3&gt;
&lt;h3&gt;음악 치료&lt;/h3&gt;
&lt;h3&gt;음향 장비&lt;/h3&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - AI & Speech Processing: Application-1]]></title><description><![CDATA[AI & Speech Processing: Application-1 본 글은 광운대학교 전자공학과 박호종 교수님의 강의를 듣고 작성되었음을 밝힙니다. 음성/오디오/sound…]]></description><link>https://sooftware.github.io/audio_app/</link><guid isPermaLink="false">https://sooftware.github.io/audio_app/</guid><pubDate>Wed, 15 Apr 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;AI &amp;#x26; Speech Processing: Application-1&lt;/h1&gt;
&lt;p&gt;본 글은 광운대학교 전자공학과 박호종 교수님의 강의를 듣고 작성되었음을 밝힙니다.&lt;/p&gt;
&lt;h2&gt;음성/오디오/sound 특성&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;방송 / 통신 / 엔터테인먼트의 핵심 기술&lt;/li&gt;
&lt;li&gt;학계/산업계의 전문 엔지니어 부족&lt;/li&gt;
&lt;li&gt;Art, 취미 활동과 관련된 기술&lt;/li&gt;
&lt;li&gt;음성에서 언어의 종속성&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;음성 이해, 음성 신호의 품질 및 명료도 평가에서 중요한 요인&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;음성은 대표적인 생체신호&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;음성 기반 헬스케어, 장애인을 위한 복지 기술&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Data 양 : V &gt;&gt; A (4차원 : 2차원)&lt;/li&gt;
&lt;li&gt;심리적 민감도 : V &amp;#x3C; A&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;특정 sound에 대한 거부감 존재&lt;br&gt;
심리 변화에 큰 영향 : 공포 영화에서 분위기 조정&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;요구 품질 : V &amp;#x3C; A&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;일반적으로 낮은 화질은 허용되지만 낮은 음질은 허용되지 않음&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;멀티미디어에서의 독립성 : V &amp;#x3C; A&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Applications - Speech Synthesis&lt;/h2&gt;
&lt;p&gt;기계를 이용하여 언어 정보를 가지는 음성 신호를 생성 : Text-To-Speech (TTS)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78545239-6f5aa500-7836-11ea-8851-b87875dd586f.png&quot; alt=&quot;tts&quot;&gt;&lt;/p&gt;
&lt;p&gt;음정을 맞추기는 쉽지만, 발음을 정확히 맞추기가 어렵다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Before 2010 : digital waveform 연결, boundary smoothing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78545482-cfe9e200-7836-11ea-93e1-dc07293a672c.png&quot; alt=&quot;tts-before-2010&quot;&gt;&lt;/p&gt;
&lt;p&gt;음절 단위로 미리 녹음해놓고 파형을 저장해놓는다.&lt;br&gt;
Text를 보고 미리 녹음해놓은 파형을 적절하게 이어붙인다.&lt;/p&gt;
&lt;p&gt;=&gt; 부자연스러움&lt;/p&gt;
&lt;p&gt;이러한 부자연스러움을 해결하기 위해 단어 단위로 녹음하는 것이 더 자연스러웠음&lt;/p&gt;
&lt;p&gt;하지만 자연스럽게 하는 과정이 굉장히 어렵다.&lt;/p&gt;
&lt;p&gt;Example)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;고기

소고기
돼지고기

불고기

물고기
=&gt; 물꼬기라고 발음이 됨 ※ 문제가 됨 ※&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;After 2010 : AI-based waveform generation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;현재 AI를 이용하여 상용화가 가능할 정도의 음질이 나오게 됨&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;부모가 들려주는 동화책&lt;/li&gt;
&lt;li&gt;죽은 사람의 목소리 재현 : 신체 구조로부터 음색 추정&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Applications - Music Synthesis&lt;/h2&gt;
&lt;p&gt;전자장치를 이용하여 music signal 합성
(쉽게 말하면 전자 키보드)&lt;/p&gt;
&lt;h2&gt;Applications - Sound for Game and Animation&lt;/h2&gt;
&lt;p&gt;게임이나 애니메이션 사운드를 직접 만드는 기술&lt;br&gt;
(물건이 떨어지는 소리, 발자국 소리 등..)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;기존에는 미리 녹음된 waveform을 상황에 맞추어 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;=&gt; 단순한 sound 반복에 의한 피로감&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sound 합성 엔진 이용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;물체 특성과 움직임에 따라 수학적으로 sound를 합성&lt;/p&gt;
&lt;h2&gt;Applications - Speech Recognition&lt;/h2&gt;
&lt;p&gt;기계가 음성 신호에 포함되어 있는 언어정보를 인식&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78549178-ebf08200-783c-11ea-9dfa-3922f0d77404.png&quot; alt=&quot;stt&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Human-machine interface의 핵심 기술&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;휴대전화에서 mic 입력으로 문자 및 명령 입력&lt;br&gt;
장애인, 특수 환경에서의 기기 동작&lt;br&gt;
지능형 로봇&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;언어에 대한 지식 필요&lt;/li&gt;
&lt;li&gt;감정 인식에 대한 연구 진행&lt;/li&gt;
&lt;li&gt;문제점&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;기술적 한계 : 사용자는 매우 높은 인식률 요구&lt;br&gt;
사용에 대한 거부감 (의외로 불편)&lt;br&gt;
더 편리한 다른 방법이 있으면 사용하지 않음&lt;br&gt;
=&gt; 말보다 키보드 or 마우스 입력이 편하다&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;자연어 (Natural Language) 인식&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;휴대폰에서 많이 사용하는 이유는, 조그마한 휴대폰에 타이핑하기가 힘들기 때문이다.&lt;br&gt;
음성인식은 항상 첫번째 옵션이 아닌, 두번째 세번째 옵션인 것을 이해해야 한다.&lt;/p&gt;
&lt;h2&gt;AI Assistant&lt;/h2&gt;
&lt;p&gt;아마존의 에코, SK의 누구, KT의 기가지니 등 최근 많이 볼 수 있는 제품&lt;/p&gt;
&lt;p&gt;생각보다 불편한 탓에 아직 활용가치가 높지 않다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;문제점 1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;아마존 인형의집 주문 사건&lt;/p&gt;
&lt;p&gt;TV에서 나온 소리를 인식해서, 미국 전역에 장난감을 주문한 사건&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;문제점 2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;화자 인식&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78549804-e8112f80-783d-11ea-83fd-3f6bb63870c4.png&quot; alt=&quot;assistant-problem&quot;&gt;&lt;/p&gt;
&lt;p&gt;=&gt; 여기서 “내”가 누군지 모른다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Privacy Issue&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;항상 Sound를 수집하고 있다?  
  
수집은 하지만 폐기한다?  
  
일상 대화  
  
인간 인식&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Camera (CCTV)에 비하여 위험성은 인지 못함&lt;/p&gt;
&lt;h2&gt;자동차에서의 음성 인식&lt;/h2&gt;
&lt;p&gt;자동차 내에서는 “복잡한 입력보다는 음성으로 입력을 하자”라는 논리가 성립이 됨&lt;/p&gt;
&lt;p&gt;But! 자동차라는 이유로 생기는 문제점이 있음&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;다양한 잡음 (자동차 잡음, 라디오 소리, 대화 소리 등 …)&lt;/li&gt;
&lt;li&gt;원거리 마이크&lt;/li&gt;
&lt;li&gt;버튼보다 불편함&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Very Efficient Speech Communication&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;파형 전송 없이 텍스트만 전송하므로 정보량이 매우 적음&lt;/li&gt;
&lt;li&gt;자연스러운 통신을 위하여 감정과 Speaker 특성 전송&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78550813-b8fbbd80-783f-11ea-9ad4-c97440914b0c.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;여기에 기계 번역까지 더해진다면, 어느 언어와도 편리한 통신이 가능함&lt;/p&gt;
&lt;p&gt;아직은 Ideal한 얘기지만, 이렇게 될 것이다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - AI & Speech Processing: DSP for Audio]]></title><description><![CDATA[AI & Speech Signal Processing Lecture : DSP for Audio 본 글은 광운대학교 전자공학과 박호종 교수님의 강의를 듣고 작성되었음을 밝힙니다. 이제는 오디오에 특화된 DSP로 넘어가보자. Short-Time…]]></description><link>https://sooftware.github.io/dsp_for_audio/</link><guid isPermaLink="false">https://sooftware.github.io/dsp_for_audio/</guid><pubDate>Sat, 11 Apr 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;AI &amp;#x26; Speech Signal Processing Lecture : DSP for Audio&lt;/h1&gt;
&lt;p&gt;본 글은 광운대학교 전자공학과 박호종 교수님의 강의를 듣고 작성되었음을 밝힙니다.&lt;/p&gt;
&lt;p&gt;이제는 오디오에 특화된 DSP로 넘어가보자.&lt;/p&gt;
&lt;h2&gt;Short-Time Fourier Transform&lt;/h2&gt;
&lt;p&gt;질문으로 시작하자.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Quesion&lt;/strong&gt; : 아래 두 신호의 spectrum은 어떤 차이를 가지는가?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79644550-a476d800-81e4-11ea-8dae-c00593ebb35c.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;위의 두 신호는 분명히 서로 다른 신호이다. 이 신호를 주파수 축에서 바라본다면 어떤 차이가 있을까??&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79644591-e869dd00-81e4-11ea-9676-0c39b9b2e5c1.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;차이를 찾을 수가 없음을 볼 수 있다. 주파수 성분이 서로 같으므로 당연한 결과이다.&lt;/p&gt;
&lt;p&gt;여기서 문제점이 제기된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fourier Transform은 무한대 시간 영역 적분이다.
&lt;ul&gt;
&lt;li&gt;Spectral Magnitude는 &lt;strong&gt;전체 시간 영역의 평균적인 주파수 특성&lt;/strong&gt;을 보여준다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Phase&lt;/strong&gt;가 시간적 특성 변화 정보를 제공한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;여기서 Phase는 그냥 넘어가도록 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;음성/오디오 신호는 시간 진행에 따른 &lt;strong&gt;주파수 성분 변화가 핵심 정보&lt;/strong&gt;이다.
&lt;ul&gt;
&lt;li&gt;시간 진행에 따른 spectrum 정보 변화의 분석이 필요하다.&lt;/li&gt;
&lt;li&gt;짧은 시간 영역에 한정된 FT를 실시한다.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Short-Time Fourier Transform (STFT)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;해당 구간만의 FT를 실시하면 &lt;strong&gt;boundary effect&lt;/strong&gt;가 발생한다.
&lt;ul&gt;
&lt;li&gt;Boundary에서의 급격한 신호 변화가 spectrum에 포함됨&lt;/li&gt;
&lt;li&gt;Window function을 사용하여 Smoothing을 해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79644736-d6d50500-81e5-11ea-8491-dd3342a1e1c4.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;실제 신호에 대해서 어떻게 &lt;strong&gt;STFT&lt;/strong&gt;가 적용되는지를 살펴보자. 앞에서 말했듯이 전체 시간 영역에 대해서 적분을 하게 되면 전체 시간 영역의 평균적인 주파수 특성만을 보여준다.&lt;/p&gt;
&lt;p&gt;이에 대한 해결책은, 짧은 시간에 대해서 Fourier Transform을 적용하면 된다.&lt;br&gt;
오른쪽 그림과 같이 원하는 구간을 제외한 부분을 0으로 없애버리고 Fourier Transform을 적용한다.&lt;/p&gt;
&lt;p&gt;여기서 중요한 점은 일부 구간에 대해서만 FT를 적용하는 것이 아니라, 나머지를 0으로 만들고 전체 영역에 대하여 FT를 적용해야한다는 점이다.&lt;/p&gt;
&lt;p&gt;하지만 이 과정에서 새로운 문제점이 제기된다.&lt;/p&gt;
&lt;p&gt;위에서 언급했듯이, 음성/오디오 신호에서는 주파수 성분 변화가 핵심 정보이다.&lt;br&gt;
근데 위와 같이 원하는 부분만 뚝- 잘라버리면 경계 부분의 순간 변화율이 매우 크게 된다. 이러한 문제를 &lt;strong&gt;Boundary Effect&lt;/strong&gt;라고 한다.&lt;/p&gt;
&lt;p&gt;이는 &lt;strong&gt;기존 신호에서는 없던 정보&lt;/strong&gt;라는게 핵심이다.&lt;br&gt;
그렇기 때문에, 이러한 쓸데없는 정보를 최대한 줄여줘야 하는 과제가 생긴다.&lt;br&gt;
이때 나오는 방법이 &lt;strong&gt;Windowing&lt;/strong&gt;이다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79645063-f1a87900-81e7-11ea-98b9-c13e41e0c831.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;왼쪽 그림과 같은 윈도우를 자른 구간에 곱해서 순간 변화율을 Smoothing 해줌으로써 기존에 없던 정보를 최대한 줄여준다.&lt;/p&gt;
&lt;p&gt;하지만 이 방법의 단점으로는, 자른 신호의 가운데 부분이 조금 더 강조된다는 단점이 있다. (하나의 장점이 있으면, 하나의 단점이 있다)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79645325-97a8b300-81e9-11ea-9c64-021c5de016f2.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;많이 쓰는 윈도우 함수로는 위의 5가지가 있다. 논문 등에 많이 나온다고 하니, 정확한 식은 기억 못하더라도, 이름 정도는 알고 있는게 좋다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Window Shape&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79645357-c888e800-81e9-11ea-8029-c5e57c6354d7.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - AI & Speech Processing: DSP-2]]></title><description><![CDATA[AI & Speech Processing: DSP-2 본 글은 광운대학교 전자공학과 박호종 교수님의 강의를 듣고 작성되었음을 밝힙니다. DFT (Discrete Fourier Transform) Digital 처리를 위하여 time와 frequency…]]></description><link>https://sooftware.github.io/dsp2/</link><guid isPermaLink="false">https://sooftware.github.io/dsp2/</guid><pubDate>Thu, 09 Apr 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;AI &amp;#x26; Speech Processing: DSP-2&lt;/h1&gt;
&lt;p&gt;본 글은 광운대학교 전자공학과 박호종 교수님의 강의를 듣고 작성되었음을 밝힙니다.&lt;/p&gt;
&lt;h2&gt;DFT (Discrete Fourier Transform)&lt;/h2&gt;
&lt;p&gt;Digital 처리를 위하여 time와 frequency domain에서 모두 &lt;strong&gt;sampling&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78664225-88cf2000-790e-11ea-97f9-b045bfaa45d7.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;f축에서 1 / N 간격으로 샘플링을 하게 되면 샘플한 결과는 주기마다 N개가 된다.&lt;br&gt;
이때 샘플링을 했으므로 축은 f -&gt; k로 변하게 된다.&lt;/p&gt;
&lt;p&gt;이전 CTFT와 같이, 1 / N마다 샘플링을 하게 되면 반대 도메인에서 N마다 반복하게 된다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78664562-3c381480-790f-11ea-845a-08b0022d3aee.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;t축에서 샘플링을 했기 때문에 f축에서 반복이 일어난다. 또한 t축은 n축으로 변하게 된다.&lt;/li&gt;
&lt;li&gt;f축에서 샘플링을 했기 때문에 n축에서 반복이 일어난다. 또한 f축은 k축으로 변하게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78664917-efa10900-790f-11ea-88d5-232526cb7e1d.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;사실 x[n]과 X(k)는 서로 연관이 있지 않다. x[n]은 X(f)와, x_hat[n]은 X(k)와 연관이 있을 뿐이다.&lt;br&gt;
하지만 x[n]에서 X(k)로의 변환이 필요하니 조금 억지로나마 수학적으로 관계를 정의했다.&lt;br&gt;
=&gt; 이것을 &lt;strong&gt;DFT (Discrete Fourier Transform)&lt;/strong&gt; 이라고 한다.&lt;/p&gt;
&lt;p&gt;여기서 이렇게 변환이 가능하게한 트릭이 뭔지 살펴보자.&lt;br&gt;
x[n]과 X(k)는 서로 관계가 없다. 하지만 어차피 일정 부분의 반복일 뿐이다.&lt;br&gt;
그러므로, 반복되는 부분은 새로운 정보가 있지 않다. =&gt; 반복이 되는 내용만 알면 된다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78665186-61795280-7910-11ea-86dc-36622103938e.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;-N/2 ~ N/2 범위로 잡기보다는 보통 [0, N-1]을 범위로 잡는다고 한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79641837-dbdd8880-81d4-11ea-8ba1-882096d7f5c1.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;그럼 &lt;strong&gt;Discrete Fourier Tansform&lt;/strong&gt; 식을 한번 살펴보자.&lt;br&gt;
x[n]식을 보게 되면, 1/N을 제외하고 보게 되면 아래와 같이 반복되는 모양이다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79641889-4262a680-81d5-11ea-8603-e57920de4d29.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;여기서 1/N을 해주는 이유는 수학적 이론 때문이라고 한다.&lt;br&gt;
(이는 그렇게 중요한 내용은 아니라고 넘어가셨다.)&lt;/p&gt;
&lt;p&gt;여기서 중요한 부분은 &lt;strong&gt;0 ≤ n &amp;#x3C; N&lt;/strong&gt; 부분이다.&lt;br&gt;
위의 &lt;strong&gt;x_hat&lt;/strong&gt;에 대해서 &lt;strong&gt;0 ≤ n &amp;#x3C; N&lt;/strong&gt;으로 범위를 한정해주기 때문에 x[n]으로 변환될 수 있는것이다.&lt;/p&gt;
&lt;p&gt;이렇게 조금은 억지로 x[n]과 X(k)의 관계를 정의할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79642034-214e8580-81d6-11ea-8ebd-d7a31101714a.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;h3&gt;※ 샘플링이 다른 도메인에서 반복이 되는 이유 ※&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79642307-b9993a00-81d7-11ea-98ac-2ba51258285d.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;(a)와 같은 원 신호에 대해 샘플링을 한다는 것은 (b)와 같은 임펄스 신호와 곱셈을 한다고도 볼 수 있다.&lt;br&gt;
그리고 &lt;strong&gt;시간 축에서의 곱셈은 주파수 축에서의 컨볼루션 연산과 같다.&lt;/strong&gt;&lt;br&gt;
( 반대로 주파수 축에서의 곱셈은 시간 축에서의 컨볼루션이다 )&lt;/p&gt;
&lt;p&gt;그런데 (b)와 같은 임펄스 신호는 주기함수이기 때문에 주파수 대역에서 반복된다.&lt;br&gt;
(주기함수는 cos(2nf + a)꼴이기 때문)&lt;/p&gt;
&lt;p&gt;즉 임펄스 신호가 주파수 대역에서 주기적으로 반복되는 신호이기 때문에 이에 컨볼루션 연산을 취하게 되면, 주기적으로 반복하는 신호가 된다.&lt;/p&gt;
&lt;h3&gt;N-point DFT&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79642567-252fd700-81d9-11ea-8f2e-347a489a8d5d.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;이제 DFT에서 &lt;strong&gt;N&lt;/strong&gt;에 주목해보자.&lt;br&gt;
&lt;strong&gt;N&lt;/strong&gt;은 주파수축에서는 1/N 마다 샘플링을 하고, 시간 축에서는 N을 주기로 반복하게 하는 중요한 파라미터다.&lt;/p&gt;
&lt;p&gt;그럼 이러한 N은 어떤 점을 결정하게 될까?&lt;br&gt;
아래 그림을 살펴보자.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79642660-e77f7e00-81d9-11ea-8834-9ec678cdcb44.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;만약 위와 같이 샘플링을 하게 되면 신호의 특성을 충분히 반영하지 못할 것이다.&lt;br&gt;
즉, 신호에 담겨있는 많은 &lt;strong&gt;정보&lt;/strong&gt;를 잃어버리게 된다.&lt;/p&gt;
&lt;p&gt;이처럼 N은 &lt;strong&gt;주파수의 resolution&lt;/strong&gt;을 결정한다. (음질)&lt;/p&gt;
&lt;p&gt;촘촘하게 샘플링을 할 수록 더 좋은 음질 혹은 해상도를 가질 수 있게 한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79642796-8ad09300-81da-11ea-9713-026b3c7be5dd.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;위의 예제는 8kHz의 주파수 범위를 가지는 신호에 대해 100-Point 샘플링을 한 예이다.&lt;br&gt;
이 때의 Spectral Resolution은 샘플링의 간격인 8k / 100 = 80Hz가 된다.&lt;/p&gt;
&lt;p&gt;그리고 만약, 해당 신호에 대하여 200Hz의 low-pass filter를 통과시켰다고 해보자.&lt;br&gt;
그럼 200Hz 이상의 신호를 지워버리면 된다.&lt;/p&gt;
&lt;p&gt;근데 왜 98, 99신호가 남아있지? 라고 생각할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79642992-a25c4b80-81db-11ea-8373-1a6ce5a51037.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;위의 그림을 봐보자. 우리는 [-N/2, N/2]를 범위로 하기보다는, 편의를 위해 [0, N-1]을 범위로 잡았다. 이때, 우리가 편의상 범위를 그렇게 잡았을 뿐이지, 원래 최고 주파수는 0.5 (가운데 )라는 사실을 기억해야한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79642918-1ea25f00-81db-11ea-8967-7b73702538c4.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;0.5까지는 주파수가 증가하다가 0.5 이후로는 주파수가 감소한다는 사실을 꼭 기억해야한다.&lt;/p&gt;
&lt;p&gt;즉, 가운데 (0.5) 를 기준으로 서로 대칭인 관계라는 사실을 꼭 기억해야한다.&lt;/p&gt;
&lt;h2&gt;LTI (Linear Time-Invariant) System&lt;/h2&gt;
&lt;p&gt;시스템에서 우리가 관심있는 것은 대표적으로 2가지이다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;시스템 동작을 어떻게 &lt;strong&gt;구현&lt;/strong&gt;할 것인가&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;시스템의 &lt;strong&gt;성질&lt;/strong&gt;이 무엇인가&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;충격응답 h[n]&lt;/h3&gt;
&lt;p&gt;충격응답을 넣었을 때 어떤 신호가 resonse로 나오는지가 관심이 있는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79643460-03851e80-81de-11ea-92ef-675de741b2b5.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;위와 같이 조금은 복잡한 식이지만, 프로그래밍으로 &lt;strong&gt;구현&lt;/strong&gt;한다면 충분히 구현이 가능하다.&lt;/p&gt;
&lt;p&gt;하지만, h[n]만으로 이 시스템이 어떤 동작을 시키는 시스템이냐? 라는 질문에는 답하기 어렵다.&lt;/p&gt;
&lt;p&gt;h[n]은 단지 수식으로 시스템의 동작만을 알려줄 뿐이다.&lt;/p&gt;
&lt;p&gt;하지만 이러한 한계를 H(f) (주파수 응답) 을 이용하여 극복한다.&lt;/p&gt;
&lt;p&gt;Y(f) = X(f)H(f)가 된다.&lt;br&gt;
=&gt; 시간 축에서의 컨볼루션은 주파수 축에서의 곱 !!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79643546-6bd40000-81de-11ea-9068-95aa74824355.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;위와 같이 X라는 입력이 H라는 시스템에 들어갔을 때 어떤 식으로 변화가 이루어지는지를 쉽게 파악할 수 있다.&lt;/p&gt;
&lt;p&gt;이러한 변화는 &lt;strong&gt;Spectral envelop의 변화&lt;/strong&gt;라고 한다.&lt;br&gt;
(평탄했던 Spectral의 높낮이가 변함)&lt;/p&gt;
&lt;p&gt;실제로 X와 Y의 소리를 듣게 되면 상당한 변화가 느껴진다고 한다.&lt;br&gt;
교수님의 말씀으로는 이러한 Spectral envelop의 변화가 사람 음성에서는 &lt;strong&gt;발음&lt;/strong&gt;을 결정하는 요소가 된다고 한다.&lt;/p&gt;
&lt;h2&gt;Z-Transform&lt;/h2&gt;
&lt;p&gt;h[n] 또는 H(f)는 &lt;strong&gt;시스템의 동작 구조&lt;/strong&gt;를 효율적으로 보여주지는 못한다.&lt;br&gt;
H(f)는 시스템을 쉽게 파악할 수 있게하지만, 여러번의 transform을 요구한다.&lt;/p&gt;
&lt;p&gt;그래서 z-transform을 이용하여 &lt;strong&gt;시스템의 동작 구조&lt;/strong&gt;를 쉽게 파악할 수 있게 한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79643803-a7bb9500-81df-11ea-9dad-2a26a905d37c.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;위의 식에서 볼 수 있듯이, Z-Transform을 사용하면 쉽고 빠르게 어떤 동작이 이루어지는지를 파악할 수 있다.&lt;/p&gt;
&lt;p&gt;H(z) = X(z) / Y(z) 라는 식에 초점을 맞춰보면, &lt;strong&gt;분자는 인풋&lt;/strong&gt;에 어떤 시스템이 적용되는지를 파악할 수 있고, &lt;strong&gt;분모는 피드백&lt;/strong&gt;이 어떤 식으로 들어가는지를 파악할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/79643861-008b2d80-81e0-11ea-80de-10e8213948bb.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;위는 Z-Transform을 이용하여 시스템의 동작 구조를 블록 다이어그램으로 표현한 그림이다.&lt;br&gt;
이처럼 Z-Transform은 h[n]이나 H(f)보다 쉽게 시스템의 동작 구조를 이해하도록 해준다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - AI & Speech Processing: DSP-1]]></title><description><![CDATA[AI & Speech Processing: DSP-1 본 글은 광운대학교 전자공학과 박호종 교수님의 강의를 듣고 작성되었음을 밝힙니다. DSP Review Time-to-Frequency transform Continuous-Time Fourier…]]></description><link>https://sooftware.github.io/dsp1/</link><guid isPermaLink="false">https://sooftware.github.io/dsp1/</guid><pubDate>Wed, 08 Apr 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;AI &amp;#x26; Speech Processing: DSP-1&lt;/h1&gt;
&lt;p&gt;본 글은 광운대학교 전자공학과 박호종 교수님의 강의를 듣고 작성되었음을 밝힙니다.&lt;/p&gt;
&lt;h2&gt;DSP Review&lt;/h2&gt;
&lt;h3&gt;Time-to-Frequency transform&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Continuous-Time Fourier Transform, &lt;strong&gt;CTFT&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Discrete-Time Fourier Transform, &lt;strong&gt;DTFT&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Discrete Fourier Transform, &lt;strong&gt;DFT&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;System Equation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Frequency Response&lt;/li&gt;
&lt;li&gt;z-transform&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;CTFT and DTFT&lt;/h2&gt;
&lt;h3&gt;Continuous-Time Fourier Transform (CTFT)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78560266-d08f7200-7850-11ea-930a-c4dc16410ccf.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ω = 2πf&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;X(f) : Spectrum&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;x(t) : Signal&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;X(f)식 해석&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;basis signal&lt;/strong&gt;  : 주파수를 정의하는 가장 기본적인 식 (f0는 주파수)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;correlation&lt;/strong&gt; : 2개의 시그널을 곱하고 전체 적분을 취하면 그것이 곧 두 신호의 비슷한 정도를 나타낸다.&lt;/p&gt;
&lt;p&gt;x(t)에 f0가 얼마나 들어있는지를 correlation으로 측정한다.&lt;br&gt;
(Conjucate를 취해줘서 -j2πft로 바뀜)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;x(t)식 해석&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;역변환의 관계를 이용한 식&lt;/p&gt;
&lt;h3&gt;Conversion from x(t) to x[n]&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78560292-ddac6100-7850-11ea-8c23-e7da693d1bfd.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Analog Signal을 주기 T마다 Sampling을 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;축을 t에서 n으로 변환시킨다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;주의할 점은 n축일때에 1이 1초일때가 아니라는 점.&lt;br&gt;
=&gt; 우리는 샘플 주기를 모른다면, 몇초인지를 알 수 있다.&lt;/p&gt;
&lt;h3&gt;Discrete-Time Fourier Transform (DTFT)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78560748-86f35700-7851-11ea-865e-7946c84988a6.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;중요 포인트 1&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;시간 축에서 T마다 샘플링을 하게 되면, 기존 스펙트럼이 1 / T 를 주기로 반복되고 크기는 1 / T로 줄어든다.&lt;/p&gt;
&lt;p&gt;1 / T는 주파수를 의미하기도 한다.&lt;br&gt;
=&gt; 1초에 샘플을 몇개 얻어오느냐&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;중요 포인트 2&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;주기 T가 1로 1 / T배 줄어들게되면, 스펙트럼은 반대로 T배만큼 늘어나게 된다.&lt;/p&gt;
&lt;p&gt;3번째 그림의 f는 주파수가 아닌 cucle per sample이라는 새로운 f임 주의 !!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;중요 포인트 3&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;중간과정을 생략한채 보게 되면, 기존 스펙트럼이 T배 벌어지고, 1마다 반복되게 된다.&lt;/p&gt;
&lt;p&gt;(a가 Ta가 되고, 1마다 반복된다)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;문제 1&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3번째 그림의 1을 가르키면서 몇 Hz냐고 묻는다면, Sampling 주파수에 해당한다 !!&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;결국 CTFT와 DTFT는 같은 것이지만, Continuous하냐, Discrete하냐에 따라서 Sigma를 해주느냐, Summation을 해주느냐만이 다른 것이다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/78562135-d9ce0e00-7853-11ea-8fa4-64d5969a5a3d.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - ClovaCall Paper Review]]></title><description><![CDATA[ClovaCall: Korean Goal-Oriented Dialog Speech Corpus for Automatic Speech Recognition of Contact Centers image 논문링크 2020-04-2…]]></description><link>https://sooftware.github.io/clovacall/</link><guid isPermaLink="false">https://sooftware.github.io/clovacall/</guid><pubDate>Fri, 13 Mar 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;ClovaCall: Korean Goal-Oriented Dialog Speech Corpus for Automatic Speech Recognition of Contact Centers&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/80241423-8a367180-869e-11ea-8438-6b651ab65fb6.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2004.09367&quot;&gt;논문링크&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2020-04-20에 클로바에서 공개한 따끈따끈한 논문입니다. 한국어 음성 데이터셋 공개와 더불어 베이스라인 코드와 AI Hub, 공개한 데이터셋에 대한 학습 결과까지 포함하고 있습니다. 현재 제가 진행하는 프로젝트와 완전히 동일한 주제이면서도 같은 데이터셋 (AI Hub) 을 이용한 학습까지 했다고하니 굉장히 기대하면서 읽었습니다. 게다가 논문을 낸 기관이 네이버 Clova여서 더 기대가 됐네요.&lt;/p&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;p&gt;ASR은 여러 어플리케이션에서 필수적입니다만, License-free한 데이터는 찾기 힘들고, 유명한 Switchboard와 같은 데이터는 조금 구식입니다. 또한 가장 큰 문제점은 이러한 오픈 데이터는 대부분 영어로 이루어져 있다는 점입니다. 그래서 본 논문에서는 대용량의 한국어 음성 데이터셋을 공개한다고 밝힙니다. 11,000명의 화자에게서 얻은 60,000 쌍의 음성 데이터셋입니다. (1,000시간의 AI Hub 데이터셋이 2,000명의 화자로 이루어진 점과 비교하여 다양한 화자들로 구성된 데이터셋임을 알 수 있습니다.) 또한 해당 데이터셋을 검증하기 위한 베이스라인 코드를 같이 공개했습니다. 해당 데이터셋 및 코드는 &lt;a href=&quot;https://github.com/ClovaAI/ClovaCall&quot;&gt;이곳&lt;/a&gt;에 공개되어 있습니다.&lt;/p&gt;
&lt;h2&gt;1. Introduction&lt;/h2&gt;
&lt;p&gt;음성인식 서비스는 다양한 분야에 적용가능한 핵심 기술입니다. 하지만 이러한 음성인식 서비스 개발을 위한 오픈 데이터들은 (Wall Street Journal (WSJ), TIMIT, Switchboard, CallHome, Librispeech) 공개된 지 오래된 구식의 데이터들이며, 모두 영어로 이루어져 있습니다. 물론 &lt;a href=&quot;http://www.aihub.or.kr/aidata/105&quot;&gt;AI Hub&lt;/a&gt;와 &lt;a href=&quot;https://github.com/goodatlas/zeroth&quot;&gt;zeroth&lt;/a&gt;와 같이 오픈된 한국어 음성 데이터셋도 있지만, 이 데이터셋은 일상대화와 같은 주제들을 다룬 데이터셋입니다. 이러한 데이터셋들을 사용하게 되면 특정 도메인을 타겟으로 한 태스크에서는 성능이 좋지 않습니다. 그래서 본 논문에서는 음식점을 도메인으로한 데이터셋을 공개했다고 밝힙니다. 대부분의 문장은 10초 이내의 짧은 발화로 구성되어 있으며, End-point detection이나 alignment가 이슈가 되지 않는다고 합니다.&lt;/p&gt;
&lt;p&gt;또한 본 논문에서는 이러한 데이터셋이 어느 정도의 성능을 낼 수 있는지를 보이기 위해 Deep Speech 2 (DS2)와 Listen, Attend and Spell (LAS)의 2개의 모델로 실험을 진행했다고 밝힙니다. 이때 &lt;strong&gt;Pretraining-finetuning&lt;/strong&gt;, &lt;strong&gt;from-scratch training&lt;/strong&gt;, &lt;strong&gt;scratch training with data augmentation&lt;/strong&gt; 의 3가지 방법을 통해 비교했다고 합니다. 이에 더하여, 비교를 위해 이미 공개되어 있는 2개의 한국어 음성 데이터셋에 대해서도 같이 실험을 진행했습니다. 2개의 데이터셋은 QA Dataset (task-specific)과 AI Hub Dataset (dialog)를 의미합니다.&lt;/p&gt;
&lt;h2&gt;2. Related Work&lt;/h2&gt;
&lt;p&gt;본 장에서는 기존의 여러 데이터셋들에 대해 소개하고 있습니다. WSJ, TIMIT, Switchboard, CallHome, LibriSpeech 등의 데이터셋을 소개하고 있으며, 해당 데이터셋들은 여러 ASR 모델들의 성능을 비교하는 벤치마크로 사용되고 있습니다. 하지만 다시 강조하듯이, 이러한 데이터셋들은 일상 대화라는 주제를 가진 데이터셋이며, 특정 도메인을 주제로한 데이터셋들은 거의 오픈되지 않습니다. 또한 이렇게 오픈된 일상 대화 데이터셋들은 특정 도메인을 타겟으로 한 모델의 Pretraining 데이터셋이 될 수 있지만, 일상 대화라는 도메인과 특정 도메인을 타겟으로하는 데이터셋은 서로 꽤나 상이하여 Pretraining 하더라도 좋은 결과를 내지 못하고 있다고 합니다.&lt;/p&gt;
&lt;h2&gt;3. Korean Clova Call Speech Corpus&lt;/h2&gt;
&lt;h3&gt;3.1 Naver Clova AI for Contact Center&lt;/h3&gt;
&lt;p&gt;ClovaCall 데이터셋 구축은 &lt;em&gt;NAVER Clova AI for Contact Center (AICC)&lt;/em&gt; 프로젝트의 메인 주제였습니다. ClovaCall 데이터셋은 자연어 이해, 음성인식, 음성합성 등에 활용될 수 있으며, ‘음식점 예약’이라는 시나리오를 주제를 목적으로한 대용량 데이터셋임을 다시 한번 강조합니다.&lt;/p&gt;
&lt;h3&gt;3.2 Data Cconstruction from Humans&lt;/h3&gt;
&lt;p&gt;데이터 구축 과정에 대해 설명합니다. 데이터 구축은 다음 과정을 거쳤다고 합니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;making a Sentence Pool (어떤 문장들로 데이터셋을 구성할지)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;call-based recording (전화상으로 들어온 소리를 녹음)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;refining the recorded speech data (데이터 정제)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;자세한 내용은 논문을 참고해주시면 되겠습니다. (데이터 구축 과정이 제 관심분야는 아닌지라 ㅎㅎ;;)&lt;/p&gt;
&lt;h3&gt;3.3 Statistical Analysis&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/80275445-3a968b00-871c-11ea-86f4-296e88ba1269.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;본 논문에서는 ClovaCall 데이터셋과 AI Hub 데이터셋을 분석한 결과를 보이고 있습니다. &lt;strong&gt;단어, 문자, 음소, 발화 길이&lt;/strong&gt;를 분석하여 막대그래프로 표현했습니다.&lt;/p&gt;
&lt;h2&gt;4. Speech Recognition Result&lt;/h2&gt;
&lt;p&gt;이제 드디어 제가 관심있는 파트가 등장했습니다.&lt;/p&gt;
&lt;h3&gt;4.1 Experimental Setup&lt;/h3&gt;
&lt;h4&gt;Dataset &amp;#x26; Training Schemes&lt;/h4&gt;
&lt;p&gt;앞서 언급했듯이, &lt;strong&gt;Pretraining-finetuning&lt;/strong&gt;, &lt;strong&gt;from-scratch training&lt;/strong&gt;, &lt;strong&gt;scratch training with data augmentation&lt;/strong&gt;와 같은 3가지 방식으로의 학습방식 결과를 비교했습니다.&lt;/p&gt;
&lt;p&gt;데이터셋은 총 3가지를 사용했습니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;AI Hub&lt;/strong&gt; for Pretraining&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;QA Call&lt;/strong&gt; for Finetuning&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Clova Call&lt;/strong&gt; for Finetuning&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;AI Hub 데이터셋은 Pretraining을 위해 사용되었고, QA Call 데이터셋은 Clova Call 데이터셋과의 성능 비교를 위해 사용되었습니다. 또한 Noise-Augmentation &amp;#x26; Spec-Augmentation 2가지 기법을 각자 사용하여 결과를 비교했습니다.&lt;/p&gt;
&lt;h4&gt;Data preprocessing&lt;/h4&gt;
&lt;p&gt;먼저 AI Hub 데이터셋과 CLova Call 데이터셋의 샘플링 레이트가 서로 다릅니다. AI HUb는 16k의 샘플링 레이트를 가지는데 반해, Clova Call 데이터는 통화로부터 수집하다보니, 8k의 샘플링 레이트를 가집니다. 그래서 Clova Call 데이터를 Upsampling을 통해 8k =&gt; 16k의 샘플링 레이트를 가지도록 수정했습니다. 그리고 모든 모델은 &lt;strong&gt;log-spectrogram&lt;/strong&gt;을 인풋으로 가지며, 20ms의 &lt;em&gt;window_size&lt;/em&gt;와 10ms의 &lt;em&gt;stride&lt;/em&gt;를 가집니다. (librosa 라이브러리를 사용했습니다.) 또한 모든 스펙트로그램은 &lt;em&gt;instance-wise standardazation&lt;/em&gt; 방식으로 정규화를 진행했습니다.&lt;/p&gt;
&lt;p&gt;개인적으로 왜 Mel-Spectrogram이 아닌, 그냥 Spectrogram을 사용했는지에 대해 궁금증이 남아서, 공동 제 1저자 분 중 한분께 메일로 문의를 드렸습니다. 혹시 답변 해주신다면 답변 내용도 남기겠습니다.&lt;/p&gt;
&lt;h4&gt;ASR Models&lt;/h4&gt;
&lt;p&gt;ASR 모델로는 DeepSpeech2, Listen, Attend and Spell 2개의 아키텍처로 비교했습니다.&lt;/p&gt;
&lt;p&gt;DeepSpeech2 아키텍처는 &lt;em&gt;2D-Convolutional layer with 32 channel&lt;/em&gt;를 포함하고 있으며, 5개의 Bidirectional LSTM layer로 구성되어 있습니다. (각 방향당 800개의 unit을 사용했습니다.) 또한 트레이닝은 CTC loss를 이용하여 학습했다고 합니다.&lt;/p&gt;
&lt;p&gt;LAS 아키텍쳐는 DeepSpeech2와 같은 &lt;em&gt;Convolution layer&lt;/em&gt;를 포함시키고, 각 방향당 512개의 unit을 가진 3층의 &lt;em&gt;Bidirectional LSTM layer&lt;/em&gt;로 인코더를 구성하며, 512개의 unit을 가진 2층의 &lt;em&gt;Unidirectional LSTM layer&lt;/em&gt;로 디코더를 구성했다고 합니다. 또한 어텐션 매커니즘으로는 「Attention based Models for Speech Recognition」- &lt;a href=&quot;https://github.com/sooftware/Paper-Review/blob/master/Review/Attention-Based%20Models%20for%20Speech%20Recognition.md&quot;&gt;Review Link&lt;/a&gt;에서 제안한 Location Aware 어텐션 매커니즘을 사용했습니다.&lt;/p&gt;
&lt;p&gt;모델 평가 지표로는 Character Error Rate (CER)을 사용했으며 다음과 같은 Metric을 따릅니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/80277350-42a8f780-8729-11ea-9609-665ea1944f7b.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;h3&gt;4.2 Comparison Results on Datasets&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/80277359-60765c80-8729-11ea-928f-1f9941c7f36a.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;이제 결과를 비교하는 시간입니다. 결과만 놓고보자면, AI Hub 데이터셋으로 Pretraining 한 후, ClovaCall 데이터셋으로 Finetuning한 LAS 모델이 가장 좋은 성능 (Error Rate 7%) 을 냈습니다.&lt;/p&gt;
&lt;p&gt;또한 주목할만한 점은, AI Hub 데이터셋만으로 학습시킨 모델의 경우, Specific-domain의 데이터로 테스트 했을 때, 성능이 매우 저조했다는 점입니다. 가장 좋은 성능을 낸 LAS 모델로 비교를 하자면 Error Rate 69.2%를 기록했네요.&lt;/p&gt;
&lt;p&gt;또한 본 실험에서는 Data Augmentation이 의미있는 결과를 내지 못했습니다. 본 논문에서는 이를 이미 노이즈가 낀 상황에서 데이터를 만들었다는 점과, 파라미터 수가 작은 LAS 모델에서 Spec Augmentation을 적용했다는 점이 의미있는 효과를 내지 못한 점으로 꼽았습니다.&lt;/p&gt;
&lt;h2&gt;5. Concluding Remarks&lt;/h2&gt;
&lt;p&gt;결국 이 논문의 핵심을 특정 도메인을 대상으로 한 ASR 시스템을 구축하기 위해서는 해당 도메인의 데이터셋이 필요한데, 저희가 그런 ‘음식점 예약’ 도메인에서의 큰 데이터셋을 공개했고, 이 데이터셋을 사용했더니 결과가 좋았습니다 ! 를 강조한 논문이였습니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Beam Search (빔서치)]]></title><description><![CDATA[Sooftware NLP - Beam Search (빔서치) 본 포스팅은 “빔서치”에 대한 본질적인 개념보다는 Encoder-Decoder 모델 (Seq2seq…]]></description><link>https://sooftware.github.io/beamsearch/</link><guid isPermaLink="false">https://sooftware.github.io/beamsearch/</guid><pubDate>Fri, 14 Feb 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Sooftware NLP - Beam Search (빔서치)&lt;/h1&gt;
&lt;p&gt;본 포스팅은 “빔서치”에 대한 본질적인 개념보다는 Encoder-Decoder 모델 (Seq2seq) 을 기반으로 한 모델에서 빔서치가 어떻게 적용되는지에 중점을 두었습니다.&lt;/p&gt;
&lt;p&gt;본 포스팅을 이해하기 위해서는 다음 글에 대한 이해가 선행되는 것이 좋습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;sooftware.io/seq2seq&quot;&gt;Seq2seq&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Greedy Search&lt;/h2&gt;
&lt;p&gt;기본적인 Sequence to sequence (이하 Seq2seq) 모델에서의 디코딩 과정은 보통 Greedy Decoding 방식을 따른다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134004910-af0480cb-5256-4ede-a594-83b505e728c8.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;Greedy Decoding이란 단순하게 해당 시점에서 가장 확률이 높은 후보를 선택하는 것이다. 시간복잡도 면에서는 훌륭한 방법이지만, 최종 정확도 관점에서는 좋지 못한 방법이다.&lt;/p&gt;
&lt;p&gt;특정 시점 t에서의 확률 분포 상에서 상위 1등과 2등의 확률 차이가 작든 크든, Greedy Decoding 방식은 무조건 가장 큰 놈에게만 관심이 있을 뿐이다.&lt;br&gt;
(1등과 2등의 차이가 정말 미묘하다면,  2등이 정답일 경우도 고려해주어야 할 것이다)&lt;/p&gt;
&lt;p&gt;이러한 예측에서 한 번이라도 틀린 예측이 나오게 된다면, 이전 예측이 중요한 디코딩 방식에서는 치명적인 문제가 된다.&lt;/p&gt;
&lt;h2&gt;Beam Search&lt;/h2&gt;
&lt;p&gt;Greedy Decoding의 이러한 단점을 “어느 정도” 극복하기 위해 나온 방법이다.&lt;/p&gt;
&lt;p&gt;가장 좋은 방법은 나올 수 있는 모든 경우의 수를 고려한 뒤 누적 확률이 가장 높은 한 경우를 선택하는 것이겠지만, 이는 시간복잡도 면에서 사실상 불가능한 방법이다.&lt;/p&gt;
&lt;p&gt;빔서치는 이러한 Greedy Decoding과 모든 경우의 수를 고려하는 방법의 타협점이다. 해당 시점에서 유망한 빔의 개수만큼 (이하 K) 골라서 진행하는 방식이다. 그럼 이제 어떤 방식으로 진행이 되는지를 살펴보자. ( K = 3 )&lt;/p&gt;
&lt;h3&gt;Start&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134004999-c897db1b-f66b-46a9-b667-2e621bde023d.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;START 토큰이 입력된다.&lt;/p&gt;
&lt;h3&gt;Step 1&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134005032-03a5c5c2-d2bd-499d-ae50-50a0b7ba9947.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;START 입력을 바탕으로 나온 예측 값의 확률 분포 중 가장 높은 확률 K개를 고른다.&lt;/p&gt;
&lt;p&gt;(이제부터 이 K개의 갈래는 각각 하나의 빔이 됩니다)&lt;/p&gt;
&lt;h3&gt;Step 2&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134005069-25f9cc15-e757-46c0-8867-426967a6fa35.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;K개의 빔에서 각각 다음 예측 값의 확률 분포 중 가장 높은 K개를 고른다.&lt;/p&gt;
&lt;p&gt;( 이를 자식 노드라고 하겠습니다 )&lt;/p&gt;
&lt;h3&gt;Step 3&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134005106-414f10f8-8649-41dd-a533-80c48b8edc4d.png&quot; width=&quot;400&quot;&gt;  
&lt;p&gt;총 K&lt;sup&gt;2&lt;/sup&gt;개의 자식 노드 중 누적 확률 순으로 상위 K개를 뽑는다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;※ 주의 사항 ※&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;빔서치에서 고려하는 모든 확률은 누적 확률입니다. 어떠한 자식 노드들이 서로 같은 확률을 가지더라도, 어떤 빔에서 뻗어나왔냐에 따라 누적 확률은 달라지게 됩니다.&lt;/p&gt;
&lt;h3&gt;Step 4&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134005149-da8386b8-c05f-4a8e-ba40-25d8f5a8ce3f.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;뽑힌 상위 K개의 자식노드를 새로운 빔으로, 다시 상위 K개의 자식 노드를 만든다.&lt;/p&gt;
&lt;h3&gt;Step 5&lt;/h3&gt;
&lt;p&gt;EOS를 만난 빔이 K개가 될 때까지 Step3 - Step4를 반복한다.&lt;/p&gt;
&lt;p&gt;이상이 빔서치의 전반적인 과정이다.&lt;/p&gt;
&lt;h2&gt;EOS(End Of Sentence) Token&lt;/h2&gt;
&lt;p&gt;위에서 살펴본 빔서치에서 각각의 빔은 EOS를 만날 때까지 Step1 ~ Step5의 과정을 진행한다.&lt;br&gt;
그럼 어떠한 빔이 EOS를 만났을 때는 어떤 과정이 일어나는지를 살펴보자.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134005201-59df1183-5124-41e9-a4e9-f43fb4f28340.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;위의 그림처럼 어떤 빔이 EOS (or END) 를 만나게 되면 해당 빔은 최종 선택 후보에 오르게 된다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134005249-5bf2e1e5-5ffe-4c56-a819-c5620f9ecf5d.png&quot; width=&quot;300&quot;&gt;
&lt;p&gt;그리고, 끝난 빔의 자리를 대신하여, 해당 시점에서 상위 K개에 밀려서 K+1위를 차지했던 빔이 활성화 되어서 이후 K개의 빔을 유지한다.&lt;/p&gt;
&lt;p&gt;( 어떤 시점에서 x개의 빔이 EOS를 만나서 종료된다면, 상위 K+1위 ~ K+x위의 빔이 활성화된다 )&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134005264-b0d3c34e-db63-4509-b241-df2a7b272be1.png&quot; width=&quot;300&quot;&gt;
&lt;p&gt;그렇게 EOS를 만난 빔이 K개가 될 때까지 진행하고, EOS를 만난 빔이 K개가 된다면, 총 K개의 후보 중에서 가장 높은 누적 확률을 가진 빔을 최종적으로 선택한다.&lt;/p&gt;
&lt;h2&gt;Length Penalty&lt;/h2&gt;
&lt;p&gt;마지막으로 누적 확률 계산시에 필요한 Length Penalty를 살펴보자. 확률의 범위는 0.0 ~ 1.0이다. 이는 누적하여 곱할수록, 크기가 점점 작아진다는 것을 의미한다.&lt;/p&gt;
&lt;p&gt;그렇다면, 당연히 빔의 길이가 길어질수록 누적 확률의 값이 작아지는 것은 당연할 것이다. 이러한 길이에 따른 불공평을 해소하기 위해 Length Penalty라는 개념이 나오게 된다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134005336-6f1e2ae0-8174-48b8-b846-88f18ae0eb2f.png&quot; width=&quot;300&quot;&gt;
&lt;p&gt;간단한 공식으로 길이가 길어짐으로 인해 발생하는 불공평성을 해결해주는 것이다. 보통 알파는 1.2 정도의 값을 사용한다고 한다. 위의 공식에서는 바로 5로 들어가 있지만, minimum length로 이것 역시 설정 가능한 파라미터이다.&lt;/p&gt;
&lt;p&gt;파이썬 코드로는 다음과 같이 간단하게 구현할 수 있다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134005384-f0bd82c7-155f-480b-bcbd-aee3dce45296.png&quot; width=&quot;300&quot;&gt;
&lt;p&gt;위의 코드로 나온 결과값으로 현재 빔의 누적 확률을 나눠주면 된다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;new_prob = prob ÷ length_penalty &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Beam Search의 성능&lt;/h2&gt;
&lt;p&gt;Beam Search와 Greedy Decoding의 차이점은 단지 Greedy Decoding은 K=1인 Beam Search라는 것이다.&lt;/p&gt;
&lt;p&gt;그러므로 당연히 더 많은 경우의 수를 고려해주므로, 예측 결과 역시 좋아지는 경우가 많다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134005420-622d9a66-4a1c-4630-aba0-78e5d2468a17.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;위는 빔 크기가 커짐에 따라 표현이 더욱 풍부해진 것을 확인할 수 있는 표이다. 실제로 빔서치를 적용하면 기계 번역에서 BLEU 성능이 2 가량 올라간다고 한다.&lt;/p&gt;
&lt;p&gt;기계번역 뿐만 아니라, 본인이 음성 인식 대회에 참여했을 당시에 상위권 팀들 모두 입 모아서 빔서치를 적용했을 때 성능이 가장 많이 올랐다고 할 정도로 빔서치의 적용 여부는 NLP 모델의 성능에 크게 기여한다고 볼 수 있다.&lt;/p&gt;
&lt;p&gt;다만 빔서치의 단점이라면, 기존 Greedy Decoding에 비해 코드로 구현하여 적용하기가 어렵다는 점이다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - STATE-OF-THE-ART SPEECH RECOGNITION WITH SEQUENCE-TO-SEQUENCE MODEL Paper Review]]></title><description><![CDATA[「STATE-OF-THE-ART SPEECH RECOGNITION WITH SEQUENCE-TO-SEQUENCE MODEL」 Review title https://arxiv.org/abs/1712.0176…]]></description><link>https://sooftware.github.io/sota_sr_speech/</link><guid isPermaLink="false">https://sooftware.github.io/sota_sr_speech/</guid><pubDate>Mon, 03 Feb 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;「STATE-OF-THE-ART SPEECH RECOGNITION WITH SEQUENCE-TO-SEQUENCE MODEL」 Review&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134009230-def853f7-3fd9-4cc5-b8dc-babda6779b99.png&quot; alt=&quot;title&quot;&gt;&lt;br&gt;
&lt;a href=&quot;https://arxiv.org/abs/1712.01769&quot;&gt;https://arxiv.org/abs/1712.01769&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;본 논문은 제가 진행하는 &lt;a href=&quot;https://github.com/sooftware/kospeech&quot;&gt;프로젝트&lt;/a&gt;의 Contributor 분께서 추천해주신 논문으로, 본 논문에서 적용한 Multi-Head Attention을 적용하여 인식률이 향상되었습니다. 또한 본 논문에서는 Word-Piece를 사용하지만, 한국어에서는 Word-Piece 적용시 성능이 저하된다고 합니다. &lt;a href=&quot;https://github.com/sh951011/Korean-Speech-Recognition/pull/9&quot;&gt;Show Issue&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;p&gt;논문 이름에서부터 밝히듯이, 500h Voice Search 분야에서 &lt;strong&gt;State-Of-The-Art (SOTA)&lt;/strong&gt; 를 달성한 논문입니다.&lt;br&gt;
어텐션 기반의 Seq2seq구조인 Listen, Attend and Spell (LAS) 아키텍쳐를 사용했습니다. LAS 구조는 이전에 음향 모델, 발음 모델, 언어 모델로 구성된 방식에서 하나의 Neural Network로 End-to-End 학습이 가능한 구조입니다.&lt;/p&gt;
&lt;p&gt;본 논문에서는 grapheme (문자 단위) 모델이 아닌 word-piece (단어 단위) 모델을 사용했으며, Multi-Head Attention을 도입했다고 합니다. 그 외에도 최적화를 위해 Synchronous training, scheduled sampling, label smoothing 등을 사용했다고 밝힙니다.&lt;/p&gt;
&lt;p&gt;특이한 점으로 빠른 인식 및 학습을 위해 인코더 부분에 Bidirectional-LSTM이 아닌 Unidirectional-LSTM을 사용했다고 합니다.&lt;/p&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Sequence-to-Sequence 모델은 Autonomic Speech Recognition (ASR) Task에서 탁월한 성능을 보여주었습니다.&lt;br&gt;
2015년에 「Listen, Attend and Spell」 논문에서 Seq2seq 아키텍처를 도입한 이후로 이 글을 쓰는 지금 2020년까지도 관련 논문들이 많이 나오고 있고 SOTA 모델에서도  Sequence-to-Sequence 모델이 많이 점유하고 있습니다.&lt;/p&gt;
&lt;p&gt;Neural Machine Translation 분야에서 엄청난 성능을 자랑하는 Transformer가 Speech 분야에서는 Transformer 모델이 다소 부진한 듯 합니다. (NMT에서의 압도적인 성능에 비해서입니다 ㅎㅎ..)&lt;/p&gt;
&lt;p&gt;제가 네이버 AI 해커톤 참여 당시, 멘토분께서 Transformer는 데이터가 적을 때 성능이 그렇게 좋지 않다고 하셨습니다. 아마 데이터가 적은 음성 분야라 더 두드러지는 특징이 아닐까 싶습니다. 실제로 네이버 대회 당시 100시간이라는 한정된 데이터로 진행을 하다보니, Transformer를 사용한 팀들이 어텐션 기반의 Seq2seq 모델을 사용한 팀들에게 밀리는 현상이 있었습니다. 본 논문도 Transformer보다 뒤에 나온 논문이지만, Transformer가 아닌 Seq2seq 기반으로 모델을 구성한 것을 볼 수 있습니다. 단, Transformer를 제안한 「Attention Is All You Need」 논문에서 제안된 &lt;strong&gt;Multi-Head Attention&lt;/strong&gt;을 사용했습니다. 또한 뒤에서 다룰 &lt;strong&gt;Word-Piece Model (WPM)&lt;/strong&gt;, &lt;strong&gt;Scheduled Sampling (SS)&lt;/strong&gt;, &lt;strong&gt;label smoothing&lt;/strong&gt;, &lt;strong&gt;Asynchronous SGD&lt;/strong&gt;, &lt;strong&gt;language model&lt;/strong&gt; 등을 사용했습니다. 자세한 내용은 뒤에서 다루겠습니다.&lt;/p&gt;
&lt;h2&gt;System Overview&lt;/h2&gt;
&lt;h3&gt;Basic LAS Model&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134009251-4afed2eb-d4a2-4995-aa56-947c366e3463.png&quot; alt=&quot;las-model&quot;&gt;&lt;/p&gt;
&lt;p&gt;LAS 모델을 간략하게 설명해줍니다. Encoder(Listener)는 입력으로 들어온 특징 벡터를 &lt;em&gt;&lt;strong&gt;h&lt;/strong&gt;&lt;/em&gt;라는 higher-level feature로 변환해줍니다. 이러한 &lt;em&gt;&lt;strong&gt;h&lt;/strong&gt;&lt;/em&gt;를 가지고 Decoder(Speller)는 어텐션 매커니즘과 함께 출력을 만들어 냅니다. 이에 대한 자세한 설명은 &lt;a href=&quot;https://github.com/sh951011/Paper-Review/blob/master/Review/Listen%2C%20Attend%20and%20Spell.md&quot;&gt;「Listen, Attend and Spell」 Paper Review&lt;/a&gt;을 참고하시면 좋을 것 같습니다.&lt;/p&gt;
&lt;h3&gt;Word-Piece Models&lt;/h3&gt;
&lt;p&gt;LAS 모델은 아웃풋의 단위가 보통 grapheme (character)이였습니다.&lt;/p&gt;
&lt;p&gt;하지만 이러한 구조는 OOV (Out-Of-Vocabulary) 문제가 발생시킬 수 있습니다. 이를 위한 대안으로, grapheme 단위가 아닌 phoneme (음소) 단위가 있습니다만, phoneme 단위의 단점은 추가적인 발음 모델과 언어 모델이 필요하다는 점입니다. 또한 본 논문에서 실험한 바로는, phoneme 단위는 grapheme 단위 모델보다 성능이 좋지 못했다고 합니다.&lt;/p&gt;
&lt;p&gt;그래서 본 논문은 Word-Piece Model (WPM)을 사용했다고 합니다. WPM은 OOV 문제를 해결할 수 있습니다. 또한, 일반적으로 word-level의 언어 모델은 graphme-level의 언어 모델보다 Perplexity가 낮다고 합니다. (Perplexity가 낮을수록 우수한 모델입니다.) 그래서 본 논문에서는 이러한 경향을 봤을 때, WPM을 사용하게 되면 디코딩 과정에서 더 우수한 성능이 나오지 않을까라고 예상했다고 합니다.&lt;/p&gt;
&lt;p&gt;또한 이러한 WPM으로 진행하게 되면, 기존 문자 단위에 비해 더 적은 디코딩 스텝으로 계산되기 때문에 학습 및 추론 속도가 향상되는 장점도 가지게 됩니다. 그리고 결과적으로, WPM을 사용한 모델이 다른 모델보다 더 좋은 성능을 보였다고 합니다.&lt;/p&gt;
&lt;p&gt;주의할 점으로 Word-Piece 같은 경우, 한국어에서는 오히려 성능이 저하된다고 합니다.&lt;/p&gt;
&lt;h3&gt;Multi-Head Attention&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134009258-1d50ed68-02d1-4f24-8140-331e65560944.png&quot; alt=&quot;MHA&quot;&gt;&lt;/p&gt;
&lt;p&gt;Multi-Head Attention (MHA)은 유명한 「Attention Is All You Need」 논문에서 기계번역 분야를 위해 제안되었습니다. 본 논문은 이러한 MHA를 Speech 분야로 확장해보았다고 합니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134009289-e4801493-8376-4829-84b0-2540e02b4de0.png&quot; alt=&quot;attn-distribution&quot;&gt;&lt;/p&gt;
&lt;p&gt;MHA는 기존의 어텐션을 multiple head로 확장한 구조입니다. 기존 어텐션이 1개의 어텐션 분포를 만들었다면, MHA의 각 head는 서로 다른 어텐션 분포를 만들어 내게 됩니다. 이러한 구조는 각 head가 encoder output의 서로 다른 곳을 Attend하게 해주는 효과가 있습니다.&lt;/p&gt;
&lt;p&gt;본 논문에서는 MHA를 적용 전, 후를 따로 비교하지는 않을 것 같습니다만, 제가 진행하는 음성 인식 프로젝트에서 비교해본 결과 MHA를 적용했던 모델이 압도적으로 좋은 성능을 보였습니다.&lt;/p&gt;
&lt;h3&gt;Scheduled Sampling&lt;/h3&gt;
&lt;p&gt;본 논문에서 적용한 Scheduled Sampling이라는 개념에 대해 서술합니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134009305-d7a653f0-4821-430f-bb89-84ae74e0be29.png&quot; alt=&quot;teacher_forcing&quot;&gt;&lt;/p&gt;
&lt;p&gt;Seq2seq 구조에서는 학습을 빠르게 시키기 위해 &lt;a href=&quot;https://blog.naver.com/sooftware/221790750668&quot;&gt;티쳐포싱&lt;/a&gt;이라는 기법을 사용합니다. Seq2seq구조는 원래 이전 타임스텝의 추론 char / word를 다음 타임스텝의 입력으로 넣어야 합니다만, 학습 초기에는 대부분 잘못된 추론 결과가 나오게 됩니다. 이러한 부분을 개선해주기 위하여 이전 타임스텝 추론 결과가 아닌, Ground Truth를 넣어줌으로써 빠른 학습을 가능하게끔 해주는 기법입니다.&lt;/p&gt;
&lt;h4&gt;Exposure Bias Problem&lt;/h4&gt;
&lt;p&gt;하지만 이러한 티쳐포싱 기법에는 단점이 있습니다. 학습 중에는 Ground Truth를 가지고 있지만, 실제 추론 과정에서는 Ground Truth가 없습니다. 그렇기 때문에 학습 과정과 추론 과정에서 차이(discrepancy)가 발생하게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134009321-7bf9039f-b367-4171-a38d-bc6e7d071736.png&quot; alt=&quot;ss&quot;&gt;&lt;/p&gt;
&lt;p&gt;본 논문은 이러한 Exposure Bias Problem의 차이를 줄이기 위해서 스케쥴링을 해줍니다.&lt;br&gt;
학습 초기에는 티쳐포싱 100%로 진행이 되지만, 학습이 진행될수록 비율을 점점 낮춰서 최종적으로는 티쳐포싱 60%까지 줄여서 학습을 진행했다고 합니다.&lt;br&gt;
이렇게 스케쥴링 해줌으로써 실제 추론과 학습 단계에서의 차이를 줄였다고 합니다.&lt;/p&gt;
&lt;h3&gt;Label-Smoothing&lt;/h3&gt;
&lt;p&gt;또한 본 논문은 Label-Smoothing을 적용했다고 밝힙니다. Label-Smoothing은 데이터에 대한 Over-Confidence를 조금 덜어주는 역할을 합니다. 아마 Overfitting은 많이 봤겠지만, Over-Confidence는 생소한 분들이 많으실 겁니다. Over-Confidence란 데이터를 너무 믿는다는 겁니다. 아무래도 레이블링이라는 작업이 결국은 사람이 하는 것이다 보니, 어느 정도의 오류가 있습니다. 이러한 오류가 있는 데이터를 학습하다보면 아무래도 정확한 학습하기가 힘듭니다. 그래서 이러한 Over-Confidence를 줄여주기 위하여 Label-Smoothing이라는 개념이 있습니다.&lt;/p&gt;
&lt;p&gt;정확히 말하자면 Label-Smoothing loss입니다. loss를 계산할 때 적용이 됩니다. loss 계산시에, 원-핫 인코딩 되어 있는 레이블링에 의해 정답에 대해서만 loss가 계산되지만, 이때 정답 레이블은 1, 나머지 레이블은 0으로 되어 있는 것이 아니라, 정답 레이블은 confidence, 나머지 레이블은 uncertainty로 바꾸어 loss 계산을 합니다.&lt;/p&gt;
&lt;p&gt;confidence + uncertainty = 1.0이 되도록 설정을 합니다.&lt;/p&gt;
&lt;p&gt;아래는 이를 PyTorch로 이를 구현한 코드입니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LabelSmoothingLoss&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Module&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; vocab_size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ignore_index&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; smoothing&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dim&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;LabelSmoothingLoss&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__init__&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;confidence &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; smoothing
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;smoothing &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; smoothing
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vocab_size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vocab_size
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dim &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dim
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ignore_index &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ignore_index

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; logit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;no_grad&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            label_smoothed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros_like&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;logit&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            label_smoothed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fill_&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;smoothing &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vocab_size &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            label_smoothed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scatter_&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;unsqueeze&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;confidence&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            label_smoothed&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;target &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ignore_index&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;label_smoothed &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; logit&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; criterion &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; LabelSmoothingLoss&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;vocab_size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ignore_index&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; smoothing&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dim&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Second-Pass Rescoring&lt;/h3&gt;
&lt;p&gt;물론 Seq2seq의 Decoder가 어느 정도의 language model의 성격을 갖습니다만, 훈련 데이터의 텍스트만이 반영되기 때문에 language model로서의 한계점은 분명합니다. 그래서 다른 논문에서도 그러하듯이, 방대한 텍스트 데이터로 학습한 external language model과 결합을 합니다. 다만 이러한 결합은 훈련 과정이 아닌, 추론 과정에서만 결합을 합니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134009340-a23d7cfb-b9f9-4f9a-8c63-c0cc27ee2979.png&quot; alt=&quot;equation&quot;&gt;&lt;/p&gt;
&lt;p&gt;위의 식과 같이, Acoustic Model에서 나온 확률과 Language Model에서 나온 확률, 단어의 개수를 고려하여 Rescoring을 해줍니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Attention Mechanism (어텐션 메커니즘)]]></title><description><![CDATA[Sooftware NLP - Attention Mechanism (어텐션 메커니즘) 본 포스팅을 이해하기 위해서는 다음 글에 대한 이해가 선행되는 것이 좋습니다. RNN (Recurrent Neural Network) LSTM & GRU (Long…]]></description><link>https://sooftware.github.io/attention/</link><guid isPermaLink="false">https://sooftware.github.io/attention/</guid><pubDate>Sun, 26 Jan 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Sooftware NLP - Attention Mechanism (어텐션 메커니즘)&lt;/h1&gt;
&lt;p&gt;본 포스팅을 이해하기 위해서는 다음 글에 대한 이해가 선행되는 것이 좋습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://sooftware.github.io/rnn/&quot;&gt;RNN (Recurrent Neural Network)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sooftware.github.io/lstm_gru/&quot;&gt;LSTM &amp;#x26; GRU (Long Short Term Memory &amp;#x26; Gated Recurrent Unit)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sooftware.github.io/seq2seq/&quot;&gt;Seq2seq (sequence to sequence)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;Seq2seq의 한계&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147275988-a5eca2d8-18d0-4a23-b7f0-79ccf4c4a416.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;기본적인 Seq2seq 모델은 간단한 구조라는 장점이 있었지만, 크게 2가지의 문제점이 존재한다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;하나의 고정된 크기의 벡터에 모든 정보를 압축하다보니 정보 손실이 발생한다.&lt;/li&gt;
&lt;li&gt;RNN의 고질적인 문제인 &lt;strong&gt;Vanishing Gradient Problem&lt;/strong&gt;이 존재한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이러한 문제점들은 입력 데이터가 길어지면 성능이 크게 저하되는 현상으로 이어지게 된다. 이를 위한 기법으로 입력 데이터가 길어지더라도, 정확도가 떨어지는 것을 보정해주기 위해 등장한 방법이 &lt;strong&gt;어텐션(Attention)&lt;/strong&gt; 기법이다.&lt;/p&gt;
&lt;h2&gt;Seq2seq의 문제점&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147275994-360a8692-5525-41f3-b110-d3a0b2572271.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;그렇다면 Seq2seq 구조에서 어떤 부분이 문제였는지를 살펴보자. Seq2seq의 구조를 살펴보면, Encoder에서 계산한 여러 Hidden State 중 마지막 Hidden State만을 Decoder에서 사용하게 된다.&lt;/p&gt;
&lt;p&gt;즉, 마지막 Encoder의 RNN 셀의 마지막 Hidden State를 제외하고는 사용되지 않는다.&lt;/p&gt;
&lt;p&gt;어텐션 매커니즘은 바로 이 사용되지 않은 Hidden State를 이용한 아이디어이다.&lt;/p&gt;
&lt;p&gt;어텐션의 기본 아이디어는 Decoder에서 출력 결과를 예측하는 매 시점(time step)마다, Encoder의 Hidden State를 다시 한 번 참고한다는 아이디어다.&lt;/p&gt;
&lt;p&gt;그리고 이 참고하는 비율을, 해당 시점에서 예측해야하는 결과와 연관이 있는 부분을 판단하여 좀 더 집중 (Attention) 하여 본다고 하여 Attention Mechanism이라고 부른다.&lt;/p&gt;
&lt;h2&gt;Attention의 직관적인 설명&lt;/h2&gt;
&lt;p&gt;그렇다면 이 Attention Mechanism이 왜 효과가 있을지를 먼저 생각해보자.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147276029-26d22b53-0045-4794-ae20-fd8d907e81dc.png&quot; width=&quot;300&quot;&gt;
&lt;p&gt;위와 같은 영어 문제가 있다고 해보자. 우리는 위의 영어 문제를 해석할 때, 처음부터 끝까지 혹은, 처음부터 한 문장이 끝날 때까지 모두 읽고 해석한다면 해석하기 쉽지 않을 것이다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147276036-a69e28bd-c039-4c0f-a9e6-1abf10dd0e9e.png&quot; width=&quot;400&quot;&gt;  
&lt;p&gt;이 보다는 위의 □ 부분과 같이 부분부분 끊어서 해석하는 편이 더 나은 결과를 도출할 것이다.&lt;/p&gt;
&lt;h3&gt;Encoder of Seq2seq&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147276041-b9831d3b-2971-4bd8-89b6-343372b566b6.png&quot; width=&quot;400&quot;&gt;  
&lt;p&gt;그럼 다시 Seq2seq의 Encoder에 주목해보자. 시각별 RNN 셀의 Hidden State에는 당연히 직전에 입력된 단어에 대한 정보가 많이 포함되어 있을 것이다.&lt;/p&gt;
&lt;p&gt;예를 들면 “Sooft”라는 단어가 들어간 RNN 셀의 Hidden State는 “Sooft”의 성분이 많이들어간 벡터라고 생각할 수 있다.&lt;/p&gt;
&lt;p&gt;어텐션의 아이디어는 여기서 시작된다.&lt;/p&gt;
&lt;h2&gt;Attention Mechanism&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147276107-8d3b8047-82be-42be-aebd-a6f1690cf050.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;위 그림은 디코더의 세 번째 RNN 셀에서 출력 단어를 예측할 때, 어텐션 매커니즘을 사용하는 모습이다. 그럼 어텐션 매커니즘이 어떻게 적용되는지를 살펴보자.&lt;/p&gt;
&lt;h3&gt;Attention Score&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147276113-12444d0c-c63f-486d-a1de-c1bbea208a5b.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;어텐션 매커니즘은 디코더에서 출력 결과를 예측할 때, 인코더의 Hidden State들을 다시 한 번 참고해주는 방법이라고 했다.&lt;/p&gt;
&lt;p&gt;이 때 어느 인코더의 Hidden State를 얼마나 참고할지를 결정해야 한다.&lt;/p&gt;
&lt;p&gt;이 때, 현재 예측에 필요한 정도라고 판단되는 점수를 어텐션 스코어 (Attention Score)라고 한다.&lt;/p&gt;
&lt;p&gt;이러한 어텐션 스코어를 구하기 위해, 현 시점의 디코더의 Hidden State (s&lt;sub&gt;t&lt;/sub&gt;)와 인코더의 모든 Hidden State들과 각각 내적을 수행한다.&lt;/p&gt;
&lt;p&gt;※ 벡터의 내적의 결과는 스칼라가 나온다 ※&lt;/p&gt;
&lt;h3&gt;Attention Distribution&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147276123-ad9bf1a0-60fa-4fab-a32e-dedd08e132a2.png&quot; width=&quot;400&quot;&gt;  
&lt;p&gt;앞에서 각 인코더와 디코더의 현재 Hidden State를 내적한 값은 스칼라로 나오기 때문에 이를 소프트맥스 함수를 적용해서 어텐션 분포를 구한다.&lt;/p&gt;
&lt;p&gt;※ 소프트맥스 함수는 입력받는 값을 모두 0 ~ 1 사이의 값으로 정규화하며 총합은 항상 1이 된다 ※&lt;/p&gt;
&lt;p&gt;이렇게 구한 어텐션 분포(Attention Distribution)는 각 인코더 Hidden State의 중요도라고 볼 수 있다.&lt;/p&gt;
&lt;h3&gt;Attention Distribution X Encoder Hidden State&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147276182-aa176c23-bd20-4c99-81b0-88c65f244752.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;소프트맥스를 통해 얻은 어텐션 분포를 각 인코더 Hidden State와 곱해준다.(Broadcasing)&lt;/p&gt;
&lt;h3&gt;Weight Sum&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147276190-edfc16a9-4f0d-4a2e-927d-4aac3175c025.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;각 어텐션 분포와의 곱을 통해 얻어진 Hidden State들을 전부 더해준다. (element-wise)&lt;/p&gt;
&lt;p&gt;이렇게 얻은 벡터를 인코더의 문맥을 포함하고 있다하여 컨텍스트 벡터(Context Vector)라고도 부른다.&lt;br&gt;
기본적인 Seq2seq에서 Encoder의 마지막 Hidden State를 컨텍스트 벡터라고 부른 것과 대조된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;※ 이해를 돕기 위한 예시 ※&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147276201-1a35def6-66a3-4911-8e7e-45aa9da2121e.png&quot; width=&quot;500&quot;&gt;
&lt;h3&gt;Concatenating to s&lt;sub&gt;t&lt;/sub&gt;&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147276294-abdbad76-1890-440e-b605-b815225e508a.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;그렇게 구한 컨텍스트 벡터와 현 시점의 디코더 셀의 Hidden State와 연결해준다. (여기서는 concatenate라는 방법을 사용했지만 평균을 내서 사용하는 방법도 있다)&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147276300-463fb022-c9ab-4903-8217-3b4c1218b47b.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;그리고 이렇게 구한 벡터를 이용해서 최종 예측 값을 구하게 된다.&lt;/p&gt;
&lt;p&gt;이상이 가장 기본적인 어텐션인 &lt;strong&gt;Dot-Product Attention&lt;/strong&gt;의 설명이다.&lt;/p&gt;
&lt;p&gt;어텐션 스코어를 구할 때 Dot-Product를 한다고 해서 Dot-Product Attention이라고 한다.&lt;/p&gt;
&lt;h2&gt;다양한 종류의 어텐션&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/147276306-65d644fc-f2a2-4a43-a10c-e79679738f6b.png&quot; width=&quot;450&quot;&gt;  
&lt;p&gt;어텐션은 그 효과가 검증된 만큼, 많은 종류의 기법이 존재한다. 하지만 다른 어텐션들과의 차이는 어텐션 스코어를 구하는 중간 수식의 차이일 뿐이지, 크게 개념을 벗어나지 않는다.&lt;/p&gt;
&lt;p&gt;위의 표처럼 다양한 어텐션의 종류가 있으며, 어떤 어텐션을 적용하느냐도 모델의 성능을 좌우할 것이다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Seq2seq (Sequence to sequence)]]></title><description><![CDATA[Sooftware NLP - Seq2seq (Sequence to sequence) 본 포스팅을 이해하기 위해서는 다음 글에 대한 이해가 선행되는 것이 좋습니다. RNN (Recurrent Neural Network) LSTM & GRU (Long…]]></description><link>https://sooftware.github.io/seq2seq/</link><guid isPermaLink="false">https://sooftware.github.io/seq2seq/</guid><pubDate>Sat, 25 Jan 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Sooftware NLP - Seq2seq (Sequence to sequence)&lt;/h1&gt;
&lt;p&gt;본 포스팅을 이해하기 위해서는 다음 글에 대한 이해가 선행되는 것이 좋습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://sooftware.github.io/rnn/&quot;&gt;RNN (Recurrent Neural Network)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sooftware.github.io/lstm_gru/&quot;&gt;LSTM &amp;#x26; GRU (Long Short Term Memory &amp;#x26; Gated Recurrent Unit)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;Seq2seq (Sequence-to-Sequence)&lt;/h2&gt;
&lt;p&gt;세상에는 많은 시계열 데이터 (Sequence Data) 가 존재한다.&lt;br&gt;
텍스트, 음성, 영상 등 많은 종류의 시계열 데이터가 존재하고,&lt;br&gt;
이러한 시계열 데이터들을 다른 시계열 데이터로 변환하는 문제들도 숱하게 생각할 수 있다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134771361-dc0b6d38-12b1-4bc6-a750-d6c5eaa1666a.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;예컨대 기계 번역이나 음성 인식을 예로 들 수 있다.&lt;br&gt;
(Neural Machine Translation or Speech Recognition)&lt;/p&gt;
&lt;p&gt;이러한 문제를 위한 모델로 2개의 RNN을 이용하는 Seq2seq&lt;sup&gt;sequence to sequence&lt;/sup&gt;라는 모델을 살펴보자 !!&lt;/p&gt;
&lt;h2&gt;Seq2seq의 원리&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134771395-4ecc674d-ddc6-4225-8737-bbbe7b8ce3c7.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;Seq2seq를 Encoder-Decoder 모델이라고도 많이들 부른다.&lt;br&gt;
이름이 말해주듯이 2개의 모듈, Encoder와 Decoder가 등장한다.&lt;/p&gt;
&lt;p&gt;Encoder는 어떤 시계열 데이터를 압축해서 표현해주고,&lt;br&gt;
Decoder는 압축된 데이터를 다른 시계열 데이터로 변환해준다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134771419-8f2db6a1-57ee-4fa2-a1b9-506316975c78.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;인코더는 데이터를 입력받아서 하나의 벡터로 정보를 압축한다.&lt;br&gt;
이 때의 벡터를 &lt;b&gt;컨텍스트 벡터 (Context Vector)&lt;/b&gt; 라고 하며,&lt;br&gt;
디코더는 이 컨텍스트 벡터를 이용해서 위의 그림과 같은 번역을 수행하는 것이다.&lt;/p&gt;
&lt;h2&gt;Encoder&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134771435-8cdf6c13-93ee-4e20-963a-710d35bd3ace.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;그럼 한번 Encoder부터 살펴보자.&lt;br&gt;
Encoder의 계층은 위의 그림처럼 구성된다.&lt;/p&gt;
&lt;p&gt;위의 그림처럼 Encoder는 RNN (or LSTM, GRU) 을 이용하여 데이터를&lt;br&gt;
h라는 Hidden State Vector로 변환한다.&lt;/p&gt;
&lt;p&gt;Encoder가 출력하는 벡터 h는 마지막 RNN 셀의 Hidden State이다.&lt;br&gt;
즉, Encoder는 그냥 RNN을 이어놓은 것에 불과하다.&lt;/p&gt;
&lt;p&gt;여기서 주목할 점은 Encoder가 내놓는 Context Vector는 결국 마지막 RNN 셀의&lt;br&gt;
Hidden State므로, 고정 길이 벡터라는 사실이다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134771463-ad53f595-0b1b-4927-86d6-6b07559d6f82.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;그래서 인코딩 한다라는 말은 결국 임의 길의의 시계열 데이터를 고정 길이 벡터로 변환하는 작업이 된다.&lt;/p&gt;
&lt;h2&gt;Decoder&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134771491-201c18ba-5ded-4a64-97a4-b1fade60f963.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;다음으로 Decoder를 살펴보자.&lt;br&gt;
Decoder는 기본적으로 RNNLM (RNN Language Model)이다.&lt;/p&gt;
&lt;p&gt;Decoder는 Encoder로부터 Context Vector (h)를 넘겨받는다.&lt;br&gt;
그리고 첫 입력으로 문장의 시작을 의미하는 심볼인 [s]가 들어간다.&lt;br&gt;
([s]는 [sos], [bos], [Go] 등 많은 이름으로 불린다)&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134771524-eb819bce-12f8-460e-899c-b3e9d7a0f1c1.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;Decoder의 첫번째 RNN 셀은 Context Vector와 [s], 이 2개의 입력을 바탕으로&lt;br&gt;
새로운 Hidden State를 계산하고 이를 Affine 계층과 Softmax 계층을 거쳐서&lt;br&gt;
다음에 등장할 확률이 높은 “안녕하세요”를 예측한다.&lt;/p&gt;
&lt;p&gt;※ Affine 계층은 Hidden State를 입력으로 받아 분류 개수로 출력해주는 피드포워드 네트워크이다  ※&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134771557-ad262610-582b-46cb-92de-6de78c8e0be5.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;그리고 계산한 새로운 Hidden State와 예측한 “안녕하세요”를 입력으로 해서 2번째 예측을 수행한다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134771585-7c026d60-3349-4838-925f-c7bc56df6dc8.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;위의 과정을 문장의 끝을 의미하는 심볼인 [/s]가 다음 단어로 예측될 때까지 반복한다.&lt;br&gt;
([/s]는 [eos], [end] 등 많은 이름으로 불린다)&lt;/p&gt;
&lt;h3&gt;Decoder와 RNNLM&lt;/h3&gt;
&lt;p&gt;여기서 디코더와 RNNLM (RNN Language Model).&lt;br&gt;
즉, RNN을 이용해서 문장을 생성하는 모델과의 유일한 차이점은&lt;br&gt;
인코더에서 만든 Context Vector를 입력받는다는 점만이 다르다.&lt;/p&gt;
&lt;p&gt;컨텍스트 벡터를 초기 입력으로 받는다는 사소한 차이점이 평범한 언어 모델도&lt;br&gt;
기계 번역, 음성 인식과 같은 복잡한 문제도 풀 수 있는 Decoder로 탈바꿈 시킬 수 있다.&lt;/p&gt;
&lt;h2&gt;Seqseq의 전체 모습&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134771633-8fbf84f2-1b31-4b3c-ad1e-242558ceb450.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;위는 Encoder와 Decoder를 연결한 Seq2seq의 전체 그림이다.&lt;br&gt;
위의 그림에서 볼 수 있듯이, Encoder의 마지막 Hidden State가&lt;br&gt;
Encoder와 Decoder의 순전파와 역전파를 이어주는 다리가 된다.&lt;/p&gt;
&lt;h2&gt;Seq2seq 개선&lt;/h2&gt;
&lt;p&gt;이번에는 앞에서 본 기본적인 Seq2seq 구조를 조금 개선해보자.&lt;br&gt;
효과적인 기법이 몇 가지 존재하는데 그 중 2가지를 살펴보자.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134771651-1d17c46e-f9b9-487a-9f82-71c108569f09.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;첫 번째 개선안은 아주 손 쉬운 방법이다.&lt;br&gt;
위 그림에서 보듯이 입력 데이터의 순서를 반전시키는 것이다.&lt;/p&gt;
&lt;p&gt;위의 트릭은 「“Sequence to sequence learning with neural networks.” Advances in neural information processing system. 2014.」 논문에서 제안했다.&lt;/p&gt;
&lt;p&gt;이 트릭을 사용하면 많은 경우 학습이 빨라져서, 최종 정확도도 좋아진다고 한다.&lt;/p&gt;
&lt;p&gt;그렇다면 왜 입력 데이터를 반전시키는 것만으로 학습이 빨라지고 정확도가 향상되는 걸까?&lt;br&gt;
직관적으로는 Gradient의 전파가 원활해지기 때문이라고 볼 수 있다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134771684-c6d18e9e-c1d3-4521-a56b-58c6e25e77dc.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;예를 들어 “나는 고양이로소이다”를 “I am a cat”으로 번역하는 문제에서,&lt;br&gt;
“나”라는 단어가 “I”까지 가는 것보다 데이터를 반전시켰을 때 Gradient 전파가 잘 될 것이다.&lt;/p&gt;
&lt;p&gt;물론 평균적인 거리는 그대로이지만,&lt;br&gt;
시계열 데이터는 관련 문제에서는 앞쪽 데이터에 대한 정확한 예측이 선행되면&lt;br&gt;
뒤의 예측에서도 좋은 결과로 이어지는 경우가 많기 때문에 더 좋은 결과가 나오지 않을까 싶다.&lt;/p&gt;
&lt;p&gt;필자가 진행중인 음성 인식 (Speech Recognition) 프로젝트에서도&lt;br&gt;
입력 데이터를 반전시켰을 때 학습 속도가 상당히 개선되는 것을 확인했고,&lt;br&gt;
정확도 역시 더욱 좋아졌다.&lt;/p&gt;
&lt;p&gt;매우 간단한 트릭이기 때문에 한 번 시도해보는 것을 추천한다.&lt;/p&gt;
&lt;h3&gt;Peaky Seq2seq&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134771714-4ffc097f-a72a-4e45-ae5f-d381f35064bd.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;이어서 Seq2seq 두 번째 개선안이다.&lt;br&gt;
앞서 배운 Seq2seq의 동작을 다시 한 번 살펴보게 되면,&lt;br&gt;
Encoder는 입력 데이터를 고정 길이의 컨텍스트 벡터로 변환한다.&lt;/p&gt;
&lt;p&gt;Decoder 입장에서는 이 컨텍스트 벡터만이 예측을 하는데에 제공되는 유일한 정보인 셈이다.&lt;br&gt;
그러나 이 중요한 정보를 기본 Seq2seq에서는 최초 RNN 셀에만 전달이 된다.&lt;/p&gt;
&lt;p&gt;이러한 점을 수정해서 중요한 정보가 담긴 컨텍스트 벡터를 디코더의&lt;br&gt;
다른 계층들에게도 전달해주는 것이다.&lt;/p&gt;
&lt;p&gt;이러한 아이디어는 「”learning phrase representation using RNN encoder-decoder for statistical machine translation” Cho, Kyunhyun 2014.」 논문에서 제안되었다.&lt;/p&gt;
&lt;p&gt;Peeky Seq2seq는 기본 Seq2seq에 비해 꽤나 더 좋은 성능을 보인다고 알려져있다.&lt;br&gt;
하지만 Peeky Seq2seq는 기본 Seq2seq에 비해 파라미터가 더 늘어나기 때문에&lt;br&gt;
계산량 역시 늘어나게 된다.&lt;/p&gt;
&lt;p&gt;그리고 Seq2seq의 정확도는 하이퍼파라미터에 영향을 크게 받으므로,&lt;br&gt;
실제 문제에서는 어떤 성능을 낼지 미지수이다.&lt;/p&gt;
&lt;h2&gt;Seq2seq의 한계&lt;/h2&gt;
&lt;p&gt;하지만 이러한 기본적인 Seq2seq에는 한계점이 존재한다.&lt;br&gt;
입력 데이터가 길어지게 되면 성능이 확연하게 떨어진다는 것이다.&lt;/p&gt;
&lt;p&gt;이러한 Seq2seq의 한계를 극복하기 위해 제안된 Attention Mechanism이 있다.&lt;br&gt;
실제로 엄청난 성능 향상을 일으킨 이 어텐션 기법에 대해서는 다음 글에서 알아보자.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - Teacher Forcing (티쳐포싱)]]></title><description><![CDATA[Sooftware NLP - Teacher Forcing (티쳐포싱) 본 포스팅을 이해하기 위해서는 다음 글에 대한 이해가 선행되는 것이 좋습니다. RNN (Recurrent Neural Network) LSTM & GRU (Long Short…]]></description><link>https://sooftware.github.io/teacher_forcing/</link><guid isPermaLink="false">https://sooftware.github.io/teacher_forcing/</guid><pubDate>Sat, 25 Jan 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Sooftware NLP - Teacher Forcing (티쳐포싱)&lt;/h1&gt;
&lt;p&gt;본 포스팅을 이해하기 위해서는 다음 글에 대한 이해가 선행되는 것이 좋습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://sooftware.github.io/rnn/&quot;&gt;RNN (Recurrent Neural Network)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sooftware.github.io/lstm_gru/&quot;&gt;LSTM &amp;#x26; GRU (Long Short Term Memory &amp;#x26; Gated Recurrent Unit)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sooftware.github.io/seq2seq/&quot;&gt;Seq2seq (Sequence to sequence)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;Teacher Forcing의 개요&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Teacher Forcing is the technique where the target word is passed as the next input to the decoder&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;티쳐 포싱은 Seq2seq (Encoder-Decoder) 을 기반으로 한 모델들에서 많이 사용되는 기법이다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/149659739-9dc7e4be-3702-438f-85b9-f1a7604e9d43.png&quot; width=&quot;400&quot;&gt;  
&lt;p&gt;티쳐 포싱은 target word(Ground Truth)를 디코더의 다음 입력으로 넣어주는 기법이다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/149659792-cbe4ba4e-7862-476a-8e47-b85a6bfff9b7.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;티쳐 포싱이 적용되지 않은 Seq2seq 모델의 디코더를 생각해보자.  t-1 번째의 디코더 셀이 예측한 값 (y_hat) 을 t번째 디코더의 입력으로 넣어준다.&lt;/p&gt;
&lt;p&gt;t-1번째에서 정확한 예측이 이루어졌다면 상관없지만, 잘못된 예측이 이루어졌다면 t번째 디코더의 추론 역시 잘못된 예측으로 이어질 것이다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/149659836-550c5dea-1d1e-4587-9acb-6cd2d14ec8a2.png&quot; width=&quot;400&quot;&gt;  
&lt;p&gt;이전 예측을 고려해주는 디코더의 장점이 잘못된 예측 앞에서는 엄청난 단점이 되어버린다.&lt;/p&gt;
&lt;p&gt;특히 이러한 단점은 학습 초기에 학습 속도 저하의 요인이 된다. 이러한 단점을 해결하기 위해 나온 기법이 티쳐포싱(Teacher Forcing) 기법이다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/149659856-b7ef82fb-b260-453a-9242-7f7a3a00fcfd.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;위와 같이 입력을 Ground Truth로 넣어주게 되면, 학습시 더 정확한 예측이 가능하게 되기 때문에 초기 학습 속도를 빠르게 올릴 수 있다.&lt;/p&gt;
&lt;h2&gt;Teacher Forcing의 쉬운 비유&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/149659876-d032ef83-6165-4bf3-8cf4-008f1036e324.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;위와 같이 문제 A의 답이 문제 B의 계산에 필요하고, 문제 B의 답이 문제 C의 풀이에 이용되는 문제들을 생각해보자.&lt;/p&gt;
&lt;h3&gt;Teacher Forcing 미사용&lt;/h3&gt;
&lt;p&gt;학생은 문제 A, B, C를 순서대로 풀이하고 답 a, b, c를 한꺼번에 작성하여 제출&lt;br&gt;
교사는 이 답안지를 보고 a, b, c를 한꺼번에 채점하여 점수를 알려줌.&lt;/p&gt;
&lt;h3&gt;Teacher Forcing 사용&lt;/h3&gt;
&lt;p&gt;학생은 문제 A를 풀이하고 답 a를 제출
교사는 답안지를 가져가고, 정답 a를 알려줌&lt;br&gt;
학생은 문제 A의 답 a를 가지로 문제 B를 풀이하고 답 b를 제출&lt;/p&gt;
&lt;h2&gt;Teacher Forcing 기법의 장단점&lt;/h2&gt;
&lt;h3&gt;학습이 빠르다&lt;/h3&gt;
&lt;p&gt;학습 초기 단계에서는 모델의 예측 성능이 나쁘다. 때문에 Teacher Forcing을 이용하지 않으면 잘못된 예측 값을 토대로 Hidden State 값이 업데이트되고, 이 때문에 모델의 학습 속도는 더뎌지게 된다.&lt;/p&gt;
&lt;h3&gt;노출 편향 문제 (Exposure Bias Problem)&lt;/h3&gt;
&lt;p&gt;추론 (Inference) 과정에서는 Ground Truth를 제공할 수 없다. 때문에 모델은 전 단계의 자기 자신의 출력값을 기반으로 예측을 이어가야한다. 이러한 학습과 추론 단계에서의 차이 (discrepancy) 가 존재하여 모델의 성능과 안정성을 떨어뜨릴 수 있다.&lt;/p&gt;
&lt;p&gt;다만 노출 편향 문제가 생각만큼 큰 영향을 미치지 않는다는 2019년 연구 결과가 나와 있다고 한다.&lt;br&gt;
(T. He, J. Zhang, Z. Zhou, and J. Glass. Quantifying Exposure Bias for Neural Language Generation (2019), arXiv.)&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - LSTM & GRU]]></title><description><![CDATA[Sooftware NLP - LSTM & GRU 본 포스팅을 이해가기 위해서는 아래 글에 대한 이해가 선행되는 것이 좋습니다. RNN (Recurrent Neural Network) LSTM 등장 배경 RNN…]]></description><link>https://sooftware.github.io/lstm_gru/</link><guid isPermaLink="false">https://sooftware.github.io/lstm_gru/</guid><pubDate>Fri, 24 Jan 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Sooftware NLP - LSTM &amp;#x26; GRU&lt;/h2&gt;
&lt;p&gt;본 포스팅을 이해가기 위해서는 아래 글에 대한 이해가 선행되는 것이 좋습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;sooftware.io/rnn&quot;&gt;RNN (Recurrent Neural Network)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;LSTM 등장 배경&lt;/h2&gt;
&lt;p&gt;RNN은 순환 경로를 포함하여 과거의 정보를 기억할 수 있었다.&lt;br&gt;
구조가 단순하다는 장점이 있지만, 성능이 좋지 못하다는 단점도 존재한다.&lt;/p&gt;
&lt;p&gt;이러한 단점의 원인은 많은 경우에 시계열 데이터에서 시간적으로 많이 떨어진&lt;br&gt;
장기 의존 관계(Long Term)를 잘 학습할 수 없다는 데 있다.&lt;/p&gt;
&lt;p&gt;여기서 “장기 의존 관계”가 무엇인지 짚고 넘어가자.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Sooft는 그의 방에서 TV를 보고 있었다. Ware는 그의 방으로 들어갔다. 
그리고 Ware는 ?에게 &apos;안녕&apos;이라고 인사를 했다.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위의 예시를 보자. ?에 들어갈 단어는 ‘Sooft’이다.&lt;br&gt;
위의 문제에 올바르게 답하려면, 앞의 “Sooft는” 이라는 정보를 기억해둬야 한다.&lt;/p&gt;
&lt;p&gt;하지만 기본적인 RNN의 구조에서는 이러한 장기 의존 관계에 취약하다.&lt;/p&gt;
&lt;h2&gt;RNN의 문제점&lt;/h2&gt;
&lt;p&gt;그렇다면 왜 RNN은 이러한 장기 의존 관계에 대해서 약한 것일까?&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134299504-6704fb9d-2578-4c38-a5e1-0de5438bf546.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;이 점에 대해서는 RNN의 Backpropagation을 살펴보면 알 수 있다.&lt;br&gt;
위의 그림과 같이 RNN에서의 Backpropagation은 RNN 계층이 과거 방향으로&lt;br&gt;
시간을 거슬러 가면서 gradient를 전달하게 된다.&lt;/p&gt;
&lt;p&gt;하지만 이러한 기울기는 RNN 계층이 길어지게 되면 기울기가 작아지게 된다.&lt;br&gt;
이를 Vanishing Gradient Problem(기울기 소실)이라고 한다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134299528-6663aac1-8417-4d13-b4e8-f55751962ab0.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;그럼 RNN 계층에서 왜 Vanishing Gradient이 일어나는 원인을 살펴보자.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134299677-12bf24c3-0833-4c88-85e1-5b8d4da2db66.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;위는 RNN 셀의 구조이다.&lt;/p&gt;
&lt;p&gt;위의 구조 중 ‘tanh’에만 주목해보자.&lt;br&gt;
tanh와 dtanh의 그래프 모양은 다음과 같다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134299686-3c4d54ae-5571-4be9-a6d1-ded240259e7a.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;여기서 우리는 gradient에 관심이 있으므로, dtanh에 주목해보면&lt;br&gt;
dtanh 값은 항상 0~1 사이의 값인 것을 알 수 있다.&lt;/p&gt;
&lt;p&gt;이는 역전파에서 gradient가 tanh 노드를 지날 때마다 값이 계속 작아진다는 의미이다.&lt;br&gt;
tanh를 T번 통과하게 되면 gradient도 T번 반복해서 작아지게 된다.&lt;br&gt;
그렇기 때문에 RNN 계층이 길어지게 되면 Vanishing Gradient Problem이 발생하게 된다.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;L&lt;/strong&gt;ong &lt;strong&gt;S&lt;/strong&gt;hort &lt;strong&gt;T&lt;/strong&gt;erm &lt;strong&gt;M&lt;/strong&gt;emory (LSTM)&lt;/h2&gt;
&lt;p&gt;이제 이러한 Vanishing Gradient를 일으키지 않는다는 LSTM의 구조에 대해 살펴보자.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134299866-d4c1a2b3-b35a-47b6-bd16-1b921459fdc6.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;위 그림은 RNN과 LSTM의 인터페이스를 비교한 그림이다.&lt;/p&gt;
&lt;p&gt;인터페이스만 보더라도 LSTM 계층에는 c라는 경로가 추가된 것을 알 수 있다.&lt;/p&gt;
&lt;p&gt;이 c를 기억 셀&lt;sup&gt;memory cell&lt;/sup&gt;이라 하며, LSTM의 전용 기억 매커니즘이다.&lt;/p&gt;
&lt;p&gt;기억 셀의 특징은 데이터를 LSTM 계층 내에서만 주고 받고, 다른 계층으로는 출력하지 않는다는 것이다.&lt;br&gt;
즉, 이는 LSTM도 내부적으로만 다르지 사용하는 입장에서는 RNN과 같은 인터페이스를 갖는다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134299986-0311e778-edd4-4fd6-86b2-4093ecbacd7d.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;이제 LSTM의 구조를 차분히 살펴보자.&lt;br&gt;
앞서 이야기한 것처럼, LSTM에는 기억 셀 c&lt;sub&gt;t&lt;/sub&gt;가 있다.&lt;br&gt;
이 c&lt;sub&gt;t&lt;/sub&gt;에는 시각 t에서의 LSTM의 메모리가 저장되어 있는데, 과거로부터 시각 t까지에 필요한&lt;br&gt;
메모리가 저장되어 있다고 가정하자.&lt;/p&gt;
&lt;p&gt;그리고 필요한 정보를 모두 간직한 이 메모리를 바탕으로 외부 계층에 Hidden State h&lt;sub&gt;t&lt;/sub&gt;를 출력한다.&lt;br&gt;
이때 출력하는 h&lt;sub&gt;t&lt;/sub&gt;는 다음 그림과 같이 기억 셀의 값은 &lt;strong&gt;tanh&lt;/strong&gt; 함수로 변환한 값이다.&lt;br&gt;
(여기서의 tanh는 각 요소에 tanh 함수를 적용한다는 뜻이다.)&lt;/p&gt;
&lt;p&gt;여기서의 핵심은 3개의 입력 (x&lt;sub&gt;t&lt;/sub&gt;, h&lt;sub&gt;t-1&lt;/sub&gt;, c&lt;sub&gt;t-1&lt;/sub&gt;)를 이용하여 구한 c&lt;sub&gt;t&lt;/sub&gt;를 사용해&lt;br&gt;
Hidden State h&lt;sub&gt;t&lt;/sub&gt;를 계산한다는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;※ LSTM 구조의 핵심은 ht는 단기상태 (Short Term) ct는 장기 상태 (Long Term)라고 볼 수 있다. ※&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;게이트&lt;sup&gt;gate&lt;/sup&gt;&lt;/h2&gt;
&lt;p&gt;여기서 뒷 내용을 이해하기 위해 게이트의 개념에 대해 이해하고 넘어가자.&lt;br&gt;
게이트는 데이터의 흐름을 제어한다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134300359-a89a80a6-0d78-495f-b3c5-143818f45018.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;위의 그림처럼 물의 흐름을 제어하는 것이 게이트의 역할이다.&lt;/p&gt;
&lt;p&gt;위의 그림처럼 LSTM에서의 게이트는 ‘열기/닫기’ 뿐 아니라, 어느 정도 열지를 조절할 수 있다.&lt;br&gt;
그리고 이 열기 ~ 닫기 까지의 정도를 0.0 ~ 1.0의 실수로 표현할 수 있다.&lt;br&gt;
그리고 이 0.0 ~ 1.0의 값이 다음으로 넘어갈 데이터의 양을 결정한다 !!&lt;/p&gt;
&lt;p&gt;여기서 중요한 점은 &lt;strong&gt;‘게이트를 얼마나 열지’라는 것도 데이터로부터 자동으로 학습된다는 점&lt;/strong&gt;이다.&lt;/p&gt;
&lt;p&gt;그리고 여기서 0.0 ~ 1.0이라는 범위에 주목해보자.&lt;br&gt;
우리는 이러한 범위를 가지는 매우 좋은 함수를 알고있다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134300507-0b0111d5-0917-4e12-8a41-919fc9fc6fad.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;바로 Sigmoid 함수이다.&lt;/p&gt;
&lt;p&gt;Sigmoid 함수를 이용하면 어떤 값을 넣더라도 0.0 ~ 1.0의 값을 가질 수 있다.&lt;br&gt;
그렇기 때문에 LSTM의 게이트에서는 tanh가 아닌 Sigmoid 함수를 사용한다.&lt;/p&gt;
&lt;h2&gt;LSTM의 Output 게이트&lt;/h2&gt;
&lt;p&gt;다시 LSTM 이야기로 돌아와보자.&lt;br&gt;
게이트 얘기를 하기 전에 Hidden State h&lt;sub&gt;t&lt;/sub&gt;는 기억 셀 c&lt;sub&gt;t&lt;/sub&gt;에 단순히 tanh 함수를 적용한것 뿐이라고 했다.&lt;/p&gt;
&lt;p&gt;그럼 방금 배운 게이트의 개념을 tanh(c&lt;sub&gt;t&lt;/sub&gt;)에 적용하는 것을 생각해보자.&lt;br&gt;
즉, tanh(c&lt;sub&gt;t&lt;/sub&gt;)의 각 원소가 ‘다음 시각의 Hidden State에 얼마나 중요한가’를 조정해보자.&lt;/p&gt;
&lt;p&gt;output 게이트의 열림 상태의 계산식은 다음과 같다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134300707-e5302087-99e9-4985-a1a5-79c44ba4aff0.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;위의 식을 보게되면 RNN 계층의 내부 계산에서 tanh가 아닌 Sigmoid를&lt;br&gt;
사용했다는 점만 다르다는 것을 확인할 수 있다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134300788-173eac4b-0991-4a61-8c21-9795a9875f44.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;다음은 tanh(c&lt;sub&gt;t&lt;/sub&gt;)에 Output게이트를 추가한 모습이다.&lt;br&gt;
output 게이트에서 수행하는 식은 σ로 표시했다.&lt;/p&gt;
&lt;p&gt;그리고 이 σ의 출력을 o라고 한다면, h&lt;sub&gt;t&lt;/sub&gt;는 다음과 같이 계산된다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134300906-386cbac8-02a4-442b-a2c8-41bcc1d4182e.png&quot; width=&quot;150&quot;&gt;  
&lt;p&gt;여기서의 ⊙는 Hardmard Product (아다마르 곱) 이라고 하여, 행렬의 원소별 곱셈을 의미한다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134300914-cee72f4d-2a6d-4c68-a78e-c0d8c08740bc.png&quot; width=&quot;600&quot;&gt;  
&lt;h2&gt;LSTM의 forget 게이트&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134301001-e1c7f1e9-0060-4f76-ab07-5e7215e33114.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;다음으로 할 일은 잊을건 잊어버리는 것이다.&lt;br&gt;
굳이 필요없는 정보를 계속 들고갈 필요는 없다.&lt;br&gt;
그러므로 기억 셀에 ‘무엇을 잊을까’를 지시하는 것이다.&lt;br&gt;
여기에도 앞의 게이트 개념을 사용한다.&lt;/p&gt;
&lt;p&gt;전 층에서 넘어온 기억셀 c&lt;sub&gt;t-1&lt;/sub&gt;에 대해서 불필요한 개념을 잊게 해주는&lt;br&gt;
게이트를 forget 게이트라고 한다.&lt;/p&gt;
&lt;p&gt;여기서도 위의 Output 게이트와 마찬가지로 다음 식을 수행한다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134301091-1e0c21d7-87cf-4e1b-9472-cd1d75ffb3c0.png&quot; width=&quot;250&quot;&gt;
&lt;p&gt;Output게이트의 식과 동일한 것을 확인할 수 있다.&lt;br&gt;
여기서도 마찬가지로, forget게이트의 출력인 f와 이전 기억 셀 c&lt;sub&gt;t-1&lt;/sub&gt;의 아다마르 곱으로 계산한다.&lt;/p&gt;
&lt;h2&gt;LSTM의 새로운 기억 셀&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134301235-a7d0a8f5-151c-4ed6-88a9-32057a50cd5a.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;forget 게이트를 거치면서 이전 시각의 기억 셀로부터 잊어야 할 기억이 삭제됐다.&lt;br&gt;
이제는 새로 들어온 데이터로부터 정보를 추가해야한다.&lt;br&gt;
그러기 위해서 위의 그림과 같이 tanh 노드를 추가한다.&lt;/p&gt;
&lt;p&gt;이 때, Sigmoid가 아닌 tanh 노드를 추가하는 이유는 이 ‘새로운 기억 셀’은 게이트가 아닌,&lt;br&gt;
새로운 데이터를 기억 셀에 추가하는 것이기 때문이다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134301294-71bbd02a-39fe-4beb-8661-85b9f985c0cf.png&quot; width=&quot;400&quot;&gt;  
&lt;p&gt;이제 이렇게해서 잊는 것 뿐만이 아닌, 새로운 정보까지 추가가 되었다.&lt;/p&gt;
&lt;h2&gt;LSTM의 input 게이트&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134301396-8a91d2ad-6775-450f-acc5-10a1b86709cc.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;마지막으로 새로운 정보가 들어있는 g에 게이트를 하나 추가할 생각이다.&lt;br&gt;
앞에서 새로운 데이터에 대해서 추가를 했으니, 이 데이터를 얼마나 반영할지도 판단하는 것이다.&lt;br&gt;
즉, 새로운 정보를 무비판적으로 수용하기보다는 적절히 취사선택하는 것이 이 게이트의 역할이다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134301434-0d113597-778b-4b45-b4d1-450b1566958c.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;Output 게이트, forget와 동일한 식을 계산한다.&lt;br&gt;
이후 똑같이 아다마르 곱을 통해 기억 셀에 추가해준다.&lt;/p&gt;
&lt;p&gt;이상이 LSTM 계층 내에서 이뤄지는 처리이다.&lt;/p&gt;
&lt;h2&gt;LSTM의 계산그래프&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134301543-75285f6b-5bfb-489b-b7a6-6432b39d1447.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;앞에서까지 살펴본 LSTM의 계산그래프와 내부 연산은 위의 그림과 같다.&lt;br&gt;
RNN에 비해 훨씬 복잡한 구조인 것을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;그리고 위의 LSTM 계산그래프의 게이트를 구분해보면 다음과 같다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134301619-964918c6-bf4f-4c7b-8e77-384730bbcf7e.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;위의 계산그래프를 이해하고 기억해둔다면,&lt;br&gt;
LSTM에서 내부적으로 어떤 일이 일어나는지를 알 수 있을 것이다.&lt;/p&gt;
&lt;h2&gt;LSTM의 Gradient Flow&lt;/h2&gt;
&lt;p&gt;STM의 구조는 설명했지만, 이것이 어떤 원리로 Vanishing Gradient를 방지해주는 걸까?&lt;br&gt;
그 원리는 기억 셀 c의 역전파에 주목하면 볼 수 있다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134301709-95fe8243-603b-403a-8a83-80c3b07cf10f.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;위의 그림은 기억 셀에만 집중하여, 그 역전파의 흐름을 그린 것이다.&lt;br&gt;
이때 기억 셀의 역전파에서는 ’+‘와 ‘X’ 노드만을 지나게 된다.&lt;br&gt;
’+’ 노드는 Gradient를 그대로 흘릴 뿐이므로 남는 것은 ‘X’ 노드이다.&lt;/p&gt;
&lt;p&gt;근데 여기서 중요한 점이 이 노드는 RNN과 같은 ‘행렬 곱’이 아닌 &lt;strong&gt;아다마르 곱&lt;/strong&gt;을 계산한다.&lt;br&gt;
그리고 RNN과 같이 똑같은 가중치 행렬을 사용하는게 아닌,&lt;br&gt;
새로 들어온 데이터에 대해서 행렬곱을 수행하게 된다.&lt;/p&gt;
&lt;p&gt;그러므로 매번 새로운 값와 행렬 곱이 되므로 곱셈의 효과가 누적되지 않아&lt;br&gt;
Vanishing Gradient가 일어나기 어려운 구조인 것이다.&lt;/p&gt;
&lt;p&gt;또한 여기서 ‘X’ 노드에 주목해보자.&lt;br&gt;
이 ‘X’ 노드의 계산은 &lt;strong&gt;forget 게이트&lt;/strong&gt;가 제어한다.&lt;/p&gt;
&lt;p&gt;역전파 계산시 forget 게이트의 출력과 상류 gradient의 곱이 계산되므로,&lt;br&gt;
forget 게이트가 ‘잊어야 한다’고 판단한 기억 셀의 원소에 대해서는&lt;br&gt;
해당 기울기가 작아지고, ‘잊어서는 안 된다’고 판단한 원소에 대해서는&lt;br&gt;
그 기울기가 약화되지 않은 채로 과거 방향으로 전해진다.&lt;br&gt;
따라서 중요한 정보의 기울기는 소실 없이 전파된다.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;G&lt;/strong&gt;ated &lt;strong&gt;R&lt;/strong&gt;ecurrent &lt;strong&gt;U&lt;/strong&gt;nit (GRU)&lt;/h2&gt;
&lt;p&gt;앞에서까지 LSTM에 대해 자세하게 설명했다.&lt;br&gt;
LSTM은 아주 좋은 계층이지만, 매개변수가 많아서 계산이 오래 걸리는게 단점이다.&lt;/p&gt;
&lt;p&gt;그래서 최근에는 LSTM을 대신할 변형된 RNN이 많이 제안되고 있다.&lt;br&gt;
그 중 유명하고 그 성능이 검증된 GRU&lt;sup&gt;Gated Recurrent Unit&lt;/sup&gt;라는 RNN에 대해 알아보자.&lt;/p&gt;
&lt;p&gt;( 여담으로, 이 GRU는 우리나라 ‘조경현’ 박사님이 제안한 구조이다. )&lt;/p&gt;
&lt;p&gt;GRU는 LSTM의 게이트를 사용한다는 개념은 유지한 채, 매개변수를 줄여 계산시간을 줄여준다.&lt;br&gt;
LSTM과 GRU의 인터페이스만 비교하더라도 둘의 차이점이 명확하게 드러난다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134301998-d0cfca1b-6c1e-49e1-ad28-654a7a3df27a.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;그럼 GRU 내부에서 수행하는 계산을 살펴보자.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134302043-04439d8c-052b-49c0-8f07-846a5d024e05.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;GRU에서 수행하는 계산은 이 4개의 식으로 표현된다.&lt;br&gt;
위의 식만 보더라도 6개였던 LSTM에 비해 간단해진 것을 확인할 수 있다.&lt;br&gt;
그리고 GRU의 계산 그래프는 다음 슬라이드의 그림과 같다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134336742-a931fb8a-f8ca-4009-93a6-f6633ded89dc.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;앞의 LSTM에 비해 게이트의 수가 줄어든 것을 확인할 수 있다.&lt;br&gt;
이처럼 GRU는 LSTM보다 계산 비용과 매개변수 수를 줄일 수 있다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134336822-3fb171a2-3286-4bfd-be87-52d0ba309adc.png&quot; width=&quot;600&quot;&gt;  
&lt;p&gt;위의 그림처럼 GRU에는 기억 셀은 없고,&lt;br&gt;
시간 방향으로 전파하는 것은 Hidden State인 h&lt;sub&gt;t&lt;/sub&gt;뿐이다.&lt;/p&gt;
&lt;p&gt;그리고 r과 z라는 2개의 게이트를 사용한다.&lt;br&gt;
여기서 r은 reset, z는 update 게이트이다.&lt;/p&gt;
&lt;p&gt;reset 게이트 r은 과거의 은닉 상태를 얼마나 ‘무시’할지를 결정한다.&lt;br&gt;
만약 r이 0이면&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134336936-2caa1447-455c-4fdb-93f1-19600c73f887.png&quot; width=&quot;300&quot;&gt;  
&lt;p&gt;위의 식으로부터, 새로운 Hidden State는 입력 x&lt;sub&gt;t&lt;/sub&gt;만으로 결정된다.&lt;br&gt;
과거의 Hidden State를 완전히 무시하는 것이다.&lt;/p&gt;
&lt;p&gt;한편, Update 게이트는 Hidden State를 갱신하는 게이트이다.&lt;br&gt;
LSTM의 forget 게이트와 input 게이트의 2가지 역할을 혼자 담당하는 것이다.&lt;/p&gt;
&lt;p&gt;forget 게이트로써의 기능은 다음 식이 수행되는 부분이다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134337049-a9aac156-9e93-477f-a1d6-4634d50c195e.png&quot; width=&quot;200&quot;&gt;
&lt;p&gt;과거의 Hidden State에서 잊어야 할 정보를 삭제한다.&lt;/p&gt;
&lt;p&gt;그리고 input 게이트로서의 기능은 다음 식이 수행되는 부분이다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134337097-bf71b71b-d1e1-4cde-ba90-6d57ac8b33a0.png&quot; width=&quot;200&quot;&gt;  
&lt;p&gt;새로 추가된 정보에 input 게이트의 가중치를 부여한다.&lt;/p&gt;
&lt;h2&gt;LSTM vs GRU&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134337195-b609bb36-7d0d-44ee-9433-6331bde5be79.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;LSTM과 GRU 중 어느 쪽을 사용해야 하는지를 묻는다면,&lt;br&gt;
주어진 문제와 하이퍼파라미터 설정에 따라 승자가 달라진다고 대답할 수 있다.&lt;/p&gt;
&lt;p&gt;최근 연구에서는 LSTM이 많이 사용되지만, GRU도 꾸준히 인기를 끌고 있다.&lt;br&gt;
GRU는 매개변수가 적고 계산량도 적기 때문에, 데이터셋이 작거나 모델 설계 시 반복 시도를 많이 해야 할 경우 특히 적합할 수 있다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - Attention-Based Models for Speech Recognition Paper Review]]></title><description><![CDATA[Attention-Based Models for Speech Recognition Paper Review title http://papers.nips.cc/paper/5847-attention-based-models-for-speech…]]></description><link>https://sooftware.github.io/loc-attention/</link><guid isPermaLink="false">https://sooftware.github.io/loc-attention/</guid><pubDate>Mon, 20 Jan 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Attention-Based Models for Speech Recognition Paper Review&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134008551-c7b29862-1cf1-4ffc-98d0-36186a61dd39.png&quot; alt=&quot;title&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://papers.nips.cc/paper/5847-attention-based-models-for-speech-recognition.pdf&quot;&gt;http://papers.nips.cc/paper/5847-attention-based-models-for-speech-recognition.pdf&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;본 논문에서는 최근 도입된 (당시는 최근이였음) 어텐션 매커니즘이 여러 분야에서 좋은 성능을 보였지만, 음성 인식 분야의 특성을 충분히 반영한 매커니즘은 없었다고 주장한다.&lt;/p&gt;
&lt;p&gt;음성 인식은 NMT 등의 task에 비해 상당히 긴 input sequence를 가진다.&lt;br&gt;
단어 단위로 수개에서 수십개의 인풋을 가지는 NMT에 비해 음성 인식에서는 20 ~ 40ms로 자른 프레임들이 수백~수천개의 인풋으로 들어가게 된다&lt;/p&gt;
&lt;p&gt;본 논문은 이러한 음성 인식 분야의 특성에 맞게 새로운 어텐션 매커니즘을 제안한다.&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134008561-29ab5819-3617-4fa6-8502-c0c61b2874d1.png&quot; alt=&quot;2paper&quot;&gt;&lt;/p&gt;
&lt;p&gt;참고로 본 논문은 2015년 당시 음성 인식 분야에서 “Listen, Attend and Spell” 논문과 함께 Innovation이라고 불릴만큼 큰 파장을 준 논문이였다.
기존 CTC 방식이 압도적이였던 당시에, End-to-End 방식의 포문을 열어준 논문이였기 때문이다.&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;h2&gt;General Framework&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134008574-b70ac298-d51f-4588-9777-d2362600815f.png&quot; alt=&quot;base_attention&quot;&gt;&lt;/p&gt;
&lt;p&gt;기본적인 어텐션에 대한 큰 그림이다.&lt;br&gt;
(본 논문에서는 α는 alignment, g는 glimpse라고 칭함 )&lt;/p&gt;
&lt;p&gt;어떠한 매커니즘을 거쳐서 alignment (α) 를 구하고 나면, alignment와 인코더의 아웃풋들을 곱해서 glimpse를 구한다.&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;h3&gt;Attention의 개념&lt;/h3&gt;
&lt;p&gt;본 논문에서는 나와 있지 않지만 간단하게 개념을 정리하고 가자면, “alignment는 어떤 인코더를 고려해야 할까?”를 수치화해준 벡터이고, glimpse는 수치화 된 alignment와 인코더의 아웃풋들을 각각 곱해서 현재 디코딩에 필요한 인코더의 정보를 압축한 벡터이다. 그리고 glimpse와 디코더의 아웃풋을 고려해서 현재 스텝의 값을 예측한다.&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134008583-eff08f57-d0d3-4241-b5cd-39aa3b407a3c.png&quot; alt=&quot;alignment&quot;&gt;&lt;/p&gt;
&lt;p&gt;그럼 alignment는 어떻게 구하지?&lt;br&gt;
란 물음에 답해주는 부분이다.&lt;/p&gt;
&lt;p&gt;특정 방식으로 Score를 구한 뒤, 해당 점수를 Softmax 함수에 넣어서 전체 값을 0~1의 값으로, 전체 합을 1로 만들어 준다.&lt;br&gt;
=&gt; 각 인코더 아웃풋을 얼마씩 참고할지를 수치화하는 것이다.&lt;/p&gt;
&lt;p&gt;그럼 Score를 구하는 특정 방식은 무엇이냐??&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134008595-d555ad41-1e2d-4aa3-bf30-54a1d6ce45ed.png&quot; alt=&quot;score_func&quot;&gt;&lt;/p&gt;
&lt;p&gt;어텐션 스코어를 구하는 방법은 위와 같이 다양하다. 사실 위는 정말 몇 개만 뽑아온 것이다.&lt;/p&gt;
&lt;p&gt;어텐션 매커니즘의 종류는 이 스코어 함수가 무엇이냐에 따라 달라진다.&lt;/p&gt;
&lt;p&gt;그리고, 본 논문은 새로운 “스코어 함수”를 제안한 논문인 것이다.&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;p&gt;본 논문에서는 2가지 어텐션 방식에 주목했다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Content-Based Attention&lt;/li&gt;
&lt;li&gt;Location-Based Attention&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Content-Based Attention&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134008607-25acb65f-6277-4cb1-868a-151c70f3ab18.png&quot; alt=&quot;content-based&quot;&gt;&lt;/p&gt;
&lt;p&gt;아마 어텐션을 처음 공부할 때에 대부분 Dot-Product Attention으로 배웠을 것이다.&lt;/p&gt;
&lt;p&gt;해당 스텝의 디코더의 출력과 인코더의 모든 출력들을 내적하여 어텐션 스코어를 구하는 방식이다.&lt;/p&gt;
&lt;p&gt;Content-Based Attention은 Dot-Product보다 조금 더 복잡한 수식으로 점수를 낸다.&lt;/p&gt;
&lt;p&gt;단순한 내적이 아닌, 해당 스텝의 디코더의 출력과 인코더의 모든 출력들에 웨이트를 준다.&lt;/p&gt;
&lt;p&gt;그리고 편향 및 Hyperbolic tangent를 걸어주고, 마지막으로 웨이트를 다시 걸어준다.&lt;/p&gt;
&lt;p&gt;Dot-Product Attention에 비해서는 진보된 방법이지만, Content-Based 방식의 문제점은 시퀀스에서의 자신의 위치에 상관없이 스코어링을 한다는 점이다.&lt;br&gt;
이를 “similar speech fragments” 문제라고 한다고 한다.&lt;/p&gt;
&lt;h2&gt;Location-Based Attention&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134008621-a79409c0-e98e-4d2e-8af9-7728cfdb867a.png&quot; alt=&quot;location-based&quot;&gt;&lt;/p&gt;
&lt;p&gt;그럼 이번에는 Location-Based 방식을 살펴보자.&lt;br&gt;
이 방식은 alignment 계산시, 해당 스텝 디코어의 출력과, 이전 alignment를 고려해줌으로써, 현재 시퀀스에서 어느 위치인지를 알 수 있게끔 해주는 방식이다.&lt;/p&gt;
&lt;p&gt;하지만 이 방식은 인코더의 아웃풋을 전혀 고려하지 않고, 디코더의 아웃풋만을 가지고 예측하기 때문에 분명한 한계점이 존재한다.&lt;/p&gt;
&lt;h2&gt;Hybrid Attention&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134008627-84e04a75-7ebe-43df-ba03-ba3133215c53.png&quot; alt=&quot;hybrid&quot;&gt;&lt;/p&gt;
&lt;p&gt;본 논문은 이러한 2 방식의 어텐션을 적절히 결합한 음성 인식용 어텐션을 제안한다.&lt;/p&gt;
&lt;p&gt;( 해당 어텐션을 Hybrid, Location-Aware, Location-Sensitive 등 여러 이름으로 불린다 )&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134008637-9fbf2912-0ad8-4814-85af-ce79d71b9dbe.png&quot; alt=&quot;hybrid-attention&quot;&gt;&lt;/p&gt;
&lt;p&gt;기존 Content-Based 방식에서 약간의 수식만이 추가됐을 뿐이다.&lt;/p&gt;
&lt;p&gt;기존 Content-Based 방식에서 이전 스텝의 alignment를 고려해준다.&lt;/p&gt;
&lt;p&gt;이때 이전 alignment에 웨이트를 주기 이전에, Convolution으로 1xC의 형상에서 KxC의 형상으로 늘려준다. (C: Classfication Number)&lt;/p&gt;
&lt;p&gt;그리고 해당 행렬에 웨이트를 주어서 Content + location 방식을 완성한다.&lt;/p&gt;
&lt;h2&gt;3 Potential Issue&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134008657-11650c58-d6a0-49e1-b91d-20fae065606c.png&quot; alt=&quot;Eq6&quot;&gt;&lt;/p&gt;
&lt;p&gt;앞에서 살펴봤던 위의 수식에는 3가지의 이슈가 있다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;인풋 시퀀스가 길다면, glimpse에는 노이즈가 섞여있을 가능성이 크다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;만약 인풋 시퀀스가 길다면, 어떤 시점 t에서 멀리 떨어져 있는 t + k라는 시점에서의 음성과는 서로 관련이 없을 것이다. 하지만 Softmax 함수 특성상, 모든 인풋들에 값을 부여한다. 이러한 Softmax의 특성에 의해 많은 관련없는(irrelevant) 인코더의 출력들이 고려될 것이다. 이는 Noise로 작용된다.&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;시간 복잡도가 크다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;인풋 시퀀스의 길이가 L이라고 할 때, 디코더는 매 타임 스텝마다 이 L개의 frame을 고려해주어야 한다. 그리고, 디코딩 길이를 T라 할 때, 위의 과정을 T만큼 반복하게 된다.  이는 O(LT) 라는 높은 시간 복잡도를 만들게 된다.&lt;/p&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Softmax 함수는 Single Vector에만 집중 (focus) 하는 경향이 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이러한 경향은 top-score를 받은 여러 프레임을 고려할 수 없게 한다.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Sharpening&lt;/strong&gt; &amp;#x26; &lt;strong&gt;Windowing&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;본 논문은 위의 문제를 간단하게 해결하기 위해 “Sharpening”이라는 개념의 제안했다. Softmax 수식을 약간 수정하는 것이다.&lt;br&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134008662-bffb507a-d196-4742-ae3f-474e707e042c.png&quot; alt=&quot;sharpening&quot;&gt;&lt;br&gt;
when, β &gt; 1&lt;/p&gt;
&lt;p&gt;본 논문에서는 inverse temperature를 걸어준다고 표현했다.&lt;br&gt;
위의 수식이 왜 1번 문제를 해결해 주는지에 대해서는 아직 이해를 하지 못하였다.&lt;/p&gt;
&lt;p&gt;그리고 본 논문은 위의 방식이거나, top-k개의 프레임만을 뽑아서 re-normalization을 해주는 방식으로도 해결 가능하다고 말한다.&lt;br&gt;
하지만, 위의 2 방식 모두 2번째 시간복잡도의 문제는 해결하지 못했으며, 2번째 방법의 경우는 오히려 시간 복잡도를 더 늘리게 된다.&lt;/p&gt;
&lt;p&gt;그리고 Windowing이라는 방법이 나오게 되는데, 이전 alignment의 중간값(median)을 기준으로 윈도우 크기 만큼만 고려해주는 방식이다. 해당 방법은 O(L+T)로 시간 복잡도를 낮춰준다.&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;p&gt;Sharpening은 long-utterance (긴 발화)에서의 퍼포먼스는 개선했지만, 전체적인 퍼포먼스면에서는 좋지 못한 결과로 이어졌다.&lt;br&gt;
(짧은 발화에서는 퍼포먼스가 별로였다)&lt;br&gt;
하지만 해당 실험은 최상위 점수를 받은 프레임들을 선택하여 집계하는 방식이 좋을 것이라는 가정을 하도록 만들었다고 한다.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Smoothing&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;그래서 나오게 된 방법이 Smoothing 방법이다.&lt;br&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134008674-f43e28a6-18ee-4ea4-aa4a-59e5ca666ef9.png&quot; alt=&quot;smoothing&quot;&gt;&lt;/p&gt;
&lt;p&gt;위의 식처럼 기존 Softmax 식에 Sigmoid를 추가해준 방식이다.&lt;br&gt;
Sigmoid로 Top-k frame과 아닌 frame들을 구분해주는 방식이라고 나는 이해했다.&lt;br&gt;
이러한 방식은 다양성을 가져온다고 본 논문은 말한다.&lt;/p&gt;
&lt;h2&gt;Result&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134008689-030fae61-b92c-4a5b-8bb9-61b7a29e097b.png&quot; alt=&quot;result&quot;&gt;&lt;/p&gt;
&lt;p&gt;본 논문에서 진행한 실험의 결과이다.&lt;br&gt;
기본 모델보다는 Convolution을 적용한 모델이 더 좋은 결과를 내었고,&lt;br&gt;
Smoothing까지 적용한 모델이 최상의 성적을 내었다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - SpecAugment Paper Review]]></title><description><![CDATA[SpecAugment: 「A Simple Data Augmentation Method for Automatic Speech Recognition」  Review title https://arxiv.org/abs/1904.08779 Abstract…]]></description><link>https://sooftware.github.io/specaugment/</link><guid isPermaLink="false">https://sooftware.github.io/specaugment/</guid><pubDate>Sun, 12 Jan 2020 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;SpecAugment:&lt;/h1&gt;
&lt;h2&gt;「A Simple Data Augmentation Method for Automatic Speech Recognition」  Review&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007258-2d041cd9-e68c-4339-8417-bb0defcfa33c.png&quot; alt=&quot;title&quot;&gt;&lt;br&gt;
&lt;a href=&quot;https://arxiv.org/abs/1904.08779&quot;&gt;https://arxiv.org/abs/1904.08779&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;p&gt;모델의 Overfitting을 막기 위해 가장 좋은 방법은 데이터가 많은 것입니다. 하지만 데이터가 뿅! 하고 생기는 것이 아니기 때문에 기존 데이터를 활용하여 새로운 데이터를 만들어내는 Augmentation이라는 기법을 사용합니다. 본 논문에서는 음성인식을 위한 간단한 Data-Augmentation을 제안하고, 이를 SpecAugment라고 명명했습니다. 본 논문은 오디오에서 뽑은 피쳐 벡터 (MFCC or Mel-Spectrogram etc ..) 를 input으로 Time warping, Frequency masking, Time masking 3가지 방법으로 Augmentation을 적용했습니다. 성능 테스트를 위한 모델로는 &lt;a href=&quot;https://github.com/sh951011/Paper-Review/blob/master/Review/Listen%2C%20Attend%20and%20Spell.md&quot;&gt;「Listen, Attend and Spell」&lt;/a&gt; (LAS) 모델을 사용했으며, Language Model과의 &lt;strong&gt;Shallow Fusion&lt;/strong&gt;을 통해 인식률 개선을 이뤄냈다고 밝히고 있습니다. 본 논문의 모델은 &lt;a href=&quot;http://www.openslr.org/12/&quot;&gt;LibriSpeech 960h&lt;/a&gt; 데이터셋과 &lt;a href=&quot;https://catalog.ldc.upenn.edu/LDC97S62&quot;&gt;Swichboard 300h&lt;/a&gt; 데이터셋에서 &lt;strong&gt;State-Of-The-Art (SOTA)&lt;/strong&gt; 를 달성했습니다. 달성한 결과는 아래 표에 정리했습니다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;center&quot;&gt;Dataset&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;LibriSpeech 960h&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;LibriSpeech 960h&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;Swichboard 300h&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;Swichboard 300h&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;Method&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;No LM&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;With LM&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;No LM&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;With LM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;Previous&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;-&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;7.5&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;-&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;8.3 / 17.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;&lt;strong&gt;LAS + SpecAugment&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;6.8&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;5.8&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;7.2 / 14.6&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;6.8 / 14.1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;Data Augmentation&lt;/h3&gt;
&lt;p&gt;자세히 들어가기 앞서, Data-Augmentation이 뭔지 부터 살펴봅시다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007275-48e3b310-5faa-41f7-9979-d824c669bc8e.png&quot; alt=&quot;Augmentation&quot;&gt;&lt;/p&gt;
&lt;p&gt;Augmentation이란, 데이터를 부풀려서 모델의 성능을 향상시키는 기법입니다.&lt;br&gt;
이미지 인식 분야에서 많이 쓰이는 방법으로, 좌우 반전, 사진의 일부 발췌, 밝기 조절 등을 적용하여 한정된 데이터를 조금씩 변형시켜 새로운 데이터처럼 활용하는 방법입니다.&lt;/p&gt;
&lt;h3&gt;Augmentation을 하는 이유&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Preprocessing 및 .Augmentation을 하면 대부분의 경우 성능이 향상된다.&lt;/li&gt;
&lt;li&gt;원본 데이터를 활용하여 추가하는 개념이므로 성능이 저하될 염려가 없다.&lt;/li&gt;
&lt;li&gt;방법이 간단하며 패턴이 정해져 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;단기간에 성능 향상을 원한다면, Ensemble, Augmentation을 활용하라는 말이 있을 정도로 그 효과가 검증됐다고 합니다.&lt;br&gt;
저번 네이버 해커톤 - Speech 대회 참여 당시에도, 상위권 팀들은 Ensemble, Augmentation을 거의 모두 적용했었습니다. 또한 Augmentation을 적용하는 방법은 매우 다양하기 때문에, 여러 방법도 적용이 가능하다는 장점이 있습니다.&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;딥러닝은 음성인식 분야에 성공적으로 적용이 되었습니다. 하지만, 음성 인식 분야의 연구는 대부분 모델에 초점이 맞춰져서 진행이 되었는데, 본 논문은 이러한 모델들은 쉽게 Overfitting 현상이 발생하며, 많은 양의 데이터를 필요로 한다고 지적하고 있습니다.&lt;/p&gt;
&lt;h3&gt;Traditional Data-Augmentation for Audio&lt;/h3&gt;
&lt;p&gt;그리고 본 논문은 기존의 Augmentation이 어떤 방식으로 적용되었었는지에 대한 설명을 간략하게 합니다.&lt;/p&gt;
&lt;h4&gt;Noise injection&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007294-65cd737e-71b8-4217-bb84-c406493dbe18.png&quot; alt=&quot;noise-ingection&quot;&gt;&lt;/p&gt;
&lt;p&gt;기존 데이터에 임의의 난수를 더하여 Noise를 추가해주는 방법입니다.&lt;/p&gt;
&lt;h4&gt;Shifting Time&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007299-10b640b0-be3c-4c3a-98bc-beadd3a43667.png&quot; alt=&quot;shiftting-time&quot;&gt;&lt;/p&gt;
&lt;p&gt;임의의 값만큼 음성 신호를 좌/우로 shift하고 빈 공간은 0으로 채우는 방법입니다.&lt;/p&gt;
&lt;h4&gt;Changing Pitch&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007316-d3b9da34-6d41-479c-9f92-48cbfe843717.png&quot; alt=&quot;changing-pitch&quot;&gt;&lt;/p&gt;
&lt;p&gt;기존 음성 신호의 Pitch(음높이, 주파수)를 랜덤하게 변경해주는 방법입니다.&lt;/p&gt;
&lt;h4&gt;Changing Speed&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007324-d7fb0123-999c-4645-8c61-a80babcdc882.png&quot; alt=&quot;changing-speed&quot;&gt;&lt;/p&gt;
&lt;p&gt;기존 음성 신호의 속도를 빠르게 / 느리게 바꿔주는 방법입니다.&lt;/p&gt;
&lt;p&gt;기존 음성 신호에 대한 Augmentation은 위와 같이 raw audio를 변형하는 방법들이었습니다.&lt;br&gt;
하지만 본 논문에서는 이와 같이 주장합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;어차피 사용하는 피쳐는 MFCC / log mel spectrogram인데, 이쪽을 변형하는게 쉽고 빠르지 않아?&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;또한 이러한 방법을 이와 같이 표현합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;This method is simple and computationally cheap to apply.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;log mel spectrogram을 이미지처럼 다루는 겁니다. 이렇게 계산 비용이 적게 들기 때문에 학습을 하면서 바로바로 Augmentation을 적용할 수 있었다고 합니다. SpecAugment는 앞에서 언급했듯이 3가지 종류의 변형을 적용했습니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Time Warping&lt;/li&gt;
&lt;li&gt;Frequency Masking&lt;/li&gt;
&lt;li&gt;Time Masking&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Augmentation Policy&lt;/h2&gt;
&lt;p&gt;그럼 이제 본 논문에서 제안하는 SpecAugment에 대해 상세하게 알아봅시다.&lt;br&gt;
별로 어렵지 않은 내용이라, 쉽게 이해가 되실거라 생각합니다.&lt;/p&gt;
&lt;h3&gt;Time Warping&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007533-9e5ceea1-5c82-4a57-96bb-f6aeefb52d66.png&quot; alt=&quot;time-warping&quot;&gt;&lt;/p&gt;
&lt;p&gt;Computer Vision에서 사용되는 Image Warping을 응용한 방법입니다.&lt;br&gt;
축의 중심을 이동한다(?)라고 생각하시면 되는데 아마 감이 잘 안오실 겁니다.&lt;/p&gt;
&lt;p&gt;쉽게 생각해보자면 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007547-012b55df-2837-4d12-a872-acb90f67428a.png&quot; alt=&quot;cloth-warp&quot;&gt;&lt;/p&gt;
&lt;p&gt;위와 같이 보자기의 중심에 손가락을 가져다가 한쪽으로 밀게되면 우측의 이미지와 같이 보자기가 꾸겨지게 됩니다.&lt;br&gt;
(보자기가 없어 수건으로 사진을 찍었습니다 ㅎㅎ..)&lt;/p&gt;
&lt;p&gt;하지만, 우측 이미지를 보더라도 우리는 보자기라는 것을 알 수 있습니다.&lt;br&gt;
이러한 점을 이용해서 Vision에서는 Image Warp라는 Augmentation 방법을 성공적으로 적용하였고, 본 논문은 여기에 영감을 받아, log mel spectrogram을 이미지라 생각하고, Time Warp를 적용합니다.&lt;/p&gt;
&lt;h3&gt;Frequency Masking&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007557-fbc56570-8b0c-4563-a6af-f3f8583c4752.png&quot; alt=&quot;freq-mask&quot;&gt;&lt;/p&gt;
&lt;p&gt;굉장히 간단한 방법입니다.&lt;br&gt;
주파수와 시간 축으로 이루어진 Spectrogram의 주파수 축을 따라 일정 영역을 0으로 마스킹해버립니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;code&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;freq_masking&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;feat&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; F &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; freq_mask_num &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    feat_size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; feat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    seq_len &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; feat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# freq mask&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; _ &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;freq_mask_num&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        f &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; np&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;uniform&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;low&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; high&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;F&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        f &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        f0 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;randint&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; feat_size &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        feat&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; f0 &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; f0 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; feat&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Time Masking&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007573-e5fcec5d-1ca8-451f-8677-6b1146b70fc6.png&quot; alt=&quot;time-mask&quot;&gt;&lt;/p&gt;
&lt;p&gt;Frequency Masking과 똑같습니다.&lt;br&gt;
다만, 주파수 축기 아닌, 시간 축에 대해서 일정 영역을 0으로 마스킹해버립니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;code&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;time_masking&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;feat&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; T &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; time_mask_num &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    feat_size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; feat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    seq_len &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; feat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# time mask&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; _ &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;time_mask_num&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        t &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; np&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;uniform&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;low&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; high&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;T&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        t &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        t0 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;randint&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; seq_len &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        feat&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;t0 &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; t0 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; feat&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Frequency Masking과 Time Masking 적용 시 주의점은, 마스킹하는 영역의 범위를 적당하게 지정해주어야 합니다.&lt;br&gt;
너무 많이 / 적게 적용한다면 Augmentation의 효과가 덜하거나 심한 경우 Noise가 될 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007673-cd8aa64b-d5d2-4afb-b117-b0dfc6deae52.png&quot; alt=&quot;single-apply&quot;&gt;&lt;/p&gt;
&lt;p&gt;Figure 1은 위에서 아래 방향으로 기존 Spectrogram, Time Warp, Frequency Mask, Time Mask가 각각 적용된 Spectrogram입니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007699-fc2e4ea2-c01c-4a73-b166-205a59e2cb82.png&quot; alt=&quot;double-apply&quot;&gt;&lt;/p&gt;
&lt;p&gt;본 논문은 Frequency Masking과 Time Masking을 동시에 적용하는 것을 고려했다고 합니다. 2 마스킹을 동시에 적용하게 되면 Figure 2와 같은 Spectrogram이 나오게 됩니다.&lt;/p&gt;
&lt;p&gt;본 논문은 각각 적용하는 것과 동시에 적용하는 실험을 진행했고, 결과로 나온 파라미터는 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007708-75d7d338-42bf-44df-9237-2c6fc72475cf.png&quot; alt=&quot;experiment-table1&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;LB : LibriSpeech Basic&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LD : LibriSpeech Doucle&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SM : Switchboard Mild&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SS : Switchboard String&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Frequency Masking과 Time Masking을 동시에 적용하는 코드는 아래와 같이 사용하시면 됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;code&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;spec_augment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;feat&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; T &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; F &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; time_mask_num &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; freq_mask_num &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    feat_size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; feat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    seq_len &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; feat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# time mask&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; _ &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;time_mask_num&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        t &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; np&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;uniform&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;low&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; high&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;T&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        t &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        t0 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;randint&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; seq_len &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        feat&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;t0 &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; t0 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# freq mask&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; _ &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;freq_mask_num&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        f &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; np&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;uniform&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;low&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; high&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;F&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        f &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        f0 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;randint&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; feat_size &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        feat&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; f0 &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; f0 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; feat&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Model&lt;/h2&gt;
&lt;p&gt;본 논문은 &lt;a href=&quot;https://github.com/sh951011/Paper-Review/blob/master/Review/Listen%2C%20Attend%20and%20Spell.md&quot;&gt;「Listen, Attend and Spell」&lt;/a&gt; 모델을 사용했습니다. LAS 모델 같은 경우는 음성 인식 분야에서 end-to-end의 대표적인 모델로써, 구조가 간단하며, 관련 연구도 많이 진행된 구조입니다. 첫번째 절에서 이 모델에 대한 Review 및 파라미터들에 대해 소개하고, 2번째 절에서는 Learning Rate Schedules에 대해 다룹니다. 이 Learning Rate Schedule은 퍼포먼스에 많은 영향을 미쳤다고 소개합니다. 또한 앞에서 언급했던 shallow fusion에 대해서 3번째 절에서 다룹니다.&lt;/p&gt;
&lt;h3&gt;LAS Network Architectures&lt;/h3&gt;
&lt;p&gt;본 논문은 LAS Network 중 &lt;a href=&quot;https://arxiv.org/abs/1902.01955&quot;&gt;「Model Unit Exploration for Sequence-to-Sequence Speech Recognition」&lt;/a&gt;에서 사용된 구조를 사용했다고 밝힙니다. ( 제가 진행하고 있는 한국어 음성인식 프로젝트도 역시 LAS Network를 사용하기 때문에 해당 논문도 읽고 리뷰를 쓸 예정입니다. )&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007720-e516809f-96e7-44f5-85d7-178d340d04ad.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;해당 논문은 log mel spectrogram을 입력으로 받아, 2-Layer의 maxpooling이 적용된 CNN을 거칩니다. (stride = 2) 그리고 이렇게 CNN을 거쳐서 나온 아웃풋을 인코더의 stacked Bi-LSTM의 입력으로 넣습니다. 그리고 인코딩을 거친 아웃풋을 어텐션 기반의 디코더에 넣어 예측 시퀀스를 뽑아냅니다. (디코더 레이어 사이즈 = 2)&lt;/p&gt;
&lt;h3&gt;Learning Rate Schedules&lt;/h3&gt;
&lt;p&gt;이 섹션에서는 학습율을 어떻게 관리했는지에 대해서 소개하고 있습니다. 이렇게 하나의 학습율을 사용하는 것이 아닌, 학습 도중 학습율을 조정하면서 사용하는 것을 Multi-step Learning Rate라고 합니다. 본 논문에서는 총 4단계의 Learning Rate Scheduling을 적용했습니다.&lt;/p&gt;
&lt;p&gt;다음 그림으로 보시면 이해가 조금 더 쉬울 겁니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007891-a3957747-762c-4b07-8090-eaea381b10d0.png&quot; width=&quot;500&quot;&gt;  
&lt;p&gt;좌측의 lr의 특정 값은 제가 진행하고 있는 프로젝트에서 적용한 값이므로 무시하셔도 좋습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ramp-up&lt;/strong&gt;: 학습율이 0부터 시작하여 특정 값까지 급격하게 증가시키는 구간입니다. [0, s_r]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;High Plateau&lt;/strong&gt;: 특정 값에 다다르면 학습율을 유지시키는 구간이 High Plateau입니다. [s_r, s_i]&lt;br&gt;
&lt;strong&gt;Exponential Decay&lt;/strong&gt;: 스텝이 s_i에 다다르면, s_f까지 High Plateau에서 사용한 학습율의 1 / 100로 지수적으로 감소시키면서 진행합니다. [s_i, s_f]&lt;br&gt;
&lt;strong&gt;Low Plateau&lt;/strong&gt;: 이 시점 이후에는 학습률을 계속 유지합니다. [s_f, ~]&lt;/p&gt;
&lt;p&gt;High Plateau 구간 중 [s_r, s_noise]까지는 학습율에 deviation이 0.075인 noise를 끼워서 진행하고, s_noise 이후에는 기존 학습율을 유지한다고 합니다. 학습율이 가장 중요한 하이퍼파라미터라는 말답게 상당히 많은 고민을 한 모습입니다.&lt;/p&gt;
&lt;p&gt;그리고 본 논문에서는 이러한 구간을 총 3개로 나눠서 실험을 진행했습니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;B&lt;/strong&gt;(asic): (s_r, s_noise, s_i, s_f) = (0.5K, 10K, 20K, 80K)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;D&lt;/strong&gt;(ouble): (s_r, s_noise, s_i, s_f) = (0.5K, 20K, 40K, 160K)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;L&lt;/strong&gt;(ong): (s_r, s_noise, s_i, s_f) = (1K, 20K, 140K, 320K)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이에 대한 실험의 결과는 뒤에서 살펴보겠습니다.&lt;/p&gt;
&lt;h3&gt;Label-Smoothing&lt;/h3&gt;
&lt;p&gt;또한 본 논문은 Label-Smoothing을 적용했다고 밝힙니다. Label-Smoothing은 데이터에 대한 Over-Confidence를 조금 덜어주는 역할을 합니다. 아마 Overfitting은 많이 봤겠지만, Over-Confidence는 생소한 분들이 많으실 겁니다. Over-Confidence란 데이터를 너무 믿는다는 겁니다. 아무래도 레이블링이라는 작업이 결국은 사람이 하는 것이다 보니, 어느 정도의 오류가 있습니다. 이러한 오류가 있는 데이터를 학습하다보면 아무래도 정확한 학습하기가 힘듭니다. 그래서 이러한 Over-Confidence를 줄여주기 위하여 Label-Smoothing이라는 개념이 있습니다.&lt;/p&gt;
&lt;p&gt;정확히 말하자면 Label-Smoothing loss입니다. loss를 계산할 때 적용이 됩니다. loss 계산시에, 원-핫 인코딩 되어 있는 레이블링에 의해 정답에 대해서만 loss가 계산되지만, 이때 정답 레이블은 1, 나머지 레이블은 0으로 되어 있는 것이 아니라, 정답 레이블은 confidence, 나머지 레이블은 uncertainty로 바꾸어 loss 계산을 합니다.&lt;/p&gt;
&lt;p&gt;confidence + uncertainty = 1.0이 되도록 설정을 합니다.&lt;/p&gt;
&lt;p&gt;아래는 이를 PyTorch로 이를 구현한 코드입니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LabelSmoothingLoss&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Module&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; vocab_size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ignore_index&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; smoothing&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dim&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;LabelSmoothingLoss&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__init__&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;confidence &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; smoothing
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;smoothing &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; smoothing
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vocab_size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vocab_size
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dim &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dim
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ignore_index &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ignore_index

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; logit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;no_grad&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            label_smoothed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zeros_like&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;logit&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            label_smoothed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fill_&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;smoothing &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vocab_size &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            label_smoothed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scatter_&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;unsqueeze&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;confidence&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            label_smoothed&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;target &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ignore_index&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;label_smoothed &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; logit&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; criterion &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; LabelSmoothingLoss&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;vocab_size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ignore_index&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; smoothing&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dim&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;본 논문은 confidence는 0.9, uncertainty는 0.1을 적용했다고 합니다.&lt;/p&gt;
&lt;h3&gt;Shallow Fusion with Language Model&lt;/h3&gt;
&lt;p&gt;Augmentation만으로도 State-Of-The-Art를 달성했지만, 조금 더 개선하기 위해 Language Model과 Shallow Fusion을 진행했다고 합니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007910-3607daa9-cbea-4b37-934f-6fe2dd3af251.png&quot; alt=&quot;shallow-fusion&quot;&gt;&lt;/p&gt;
&lt;p&gt;ASR 모델에서 나온 log-probability와 LM 모델에서 나온 log-probability를 적절히 고려해주어서 y_hat을 결정하게 됩니다. 앞에서 언급했었던 성능향상을 위해 적용하는 기법 중 하나인 Ensemble과 비슷한 효과를 내는 방법이라고 합니다.&lt;/p&gt;
&lt;h2&gt;Experiments&lt;/h2&gt;
&lt;p&gt;실험 결과에 대한 자세한 설명은 생략하겠습니다.&lt;br&gt;
아래 표를 참고 혹은 &lt;a href=&quot;https://arxiv.org/abs/1904.08779&quot;&gt;본 논문&lt;/a&gt;을 참고하시면 자세한 결과를 보실 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007927-856a82af-9c96-4c69-897e-16eed90830e4.png&quot; alt=&quot;table-2&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007944-7c2756ed-10d2-422e-91a7-96ed6afd539a.png&quot; alt=&quot;table-3&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134007962-b57d1f9b-7b5a-4b86-93a2-ed5aebd3fd1c.png&quot; alt=&quot;table-4&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Discussion&lt;/h2&gt;
&lt;p&gt;자, 이제 얻어진 결과에 대해 해석해보는 시간입니다.&lt;/p&gt;
&lt;h3&gt;Time waiping contributes, but is not a major factor in improving performance.&lt;/h3&gt;
&lt;p&gt;제안한 Time Warp, Frequency Masking, Time Masking 중 Time Warp는 계산은 오래 걸리는데 반하여, 성능이 그리 좋지는 않습니다. 그래서 학습시간이 넉넉치 않다면 Frequency Masking, Time Masking만을 적용하더라도 충분한 결과를 얻을 수 있을 것이라고 언급하고 있습니다.&lt;/p&gt;
&lt;h3&gt;Label smoothing introduces instability to training.&lt;/h3&gt;
&lt;p&gt;Label Smoothing은 Augmentation과 같이 적용될 때 눈에 띄는 성과를 냈다고 언급합니다. 그 이유에 대해 추측해보자면, Masking, Warp와 같은 조작이 들어가게 되면 어느 정도의 변형이 된 것이기 때문에 완벽하게 ~~한 데이터라고 표현할 수는 없을 것입니다. 그래서 이러한 Confidence를 줄여주는 Label-Smoothing과 Collaboration이 되면 더 큰 효과를 내는 것이 아닐까 추측해봅니다 ㅎㅎ..&lt;/p&gt;
&lt;h3&gt;Augmentation converts an over-fitting problem into an under-fitting problem.&lt;/h3&gt;
&lt;p&gt;Augmentation은 오버피팅 되는 문제를 언더피팅으로 바꿔주는 효과가 있다는 말입니다. Augmentation이 적용 되지 않은 데이터셋으로만 학습을 하게 되면, 아무래도 오버피팅이 날 확률이 높습니다. 하지만, Augmentation을 적용해주게 되면 아무래도 기존의 Training 데이터셋에 대하여 Overfitting이 나기 힘든 환경이 될 것입니다. 본 논문에서는 이를 over-fitting =&gt; under-fitting 되는 효과가 있다고 표현했습니다.&lt;/p&gt;
&lt;h3&gt;Common methods of addressing under-fitting yield improvements.&lt;/h3&gt;
&lt;p&gt;그럼 이때 발생하는 under-fitting 문제를 어떻게 해결했는지에 대한 답입니다. 간단합니다. 네트워크를 깊게 만들고 학습을 오래시키면 됩니다. 보통 over-fitting이 문제지, under-fitting이 문제라면 전통적인 방법인 네트워크를 깊게하고, 학습을 오래시키면 해결 가능합니다.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;다른 논문들은 인식률 개선을 위해 &lt;strong&gt;Network&lt;/strong&gt;에 집중할 때, Augmentation, Learning Rate Schedule, Loss 계산 등에 집중해서 &lt;strong&gt;State-Of-The-Art&lt;/strong&gt;를 달성한 “기본에 충실하자”라는 깨달음을 준 논문입니다. 또한 제가 진행하고 있는 한국어 음성 인식 프로젝트에 많은 영감을 줬고, 실제로 논문에 등장한 거의 대부분의 내용을 적용하여 학습을 진행중입니다. 기회가 된다면 해당 모델로 나온 결과에 대해서도 리뷰하겠습니다. 읽어주셔서 감사합니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware NLP - RNN (Recurrent Neural Network)]]></title><description><![CDATA[Sooftware NLP - RNN (Recurrent Neural Network) 본 포스팅을 이해하기 위해서는 피드포워드 네트워크에 대한 이해가 선행되는 것이 좋습니다. RNN의 등장 배경 RNN에 대해 알아보기 전에 RNN…]]></description><link>https://sooftware.github.io/rnn/</link><guid isPermaLink="false">https://sooftware.github.io/rnn/</guid><pubDate>Thu, 26 Dec 2019 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Sooftware NLP - RNN (Recurrent Neural Network)&lt;/h1&gt;
&lt;p&gt;본 포스팅을 이해하기 위해서는 피드포워드 네트워크에 대한 이해가 선행되는 것이 좋습니다.&lt;/p&gt;
&lt;h2&gt;RNN의 등장 배경&lt;/h2&gt;
&lt;p&gt;RNN에 대해 알아보기 전에 RNN이라는 놈이 왜 나왔는지 부터 생각해보자.&lt;/p&gt;
&lt;h3&gt;피드포워드 신경망의 문제점&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134012351-39033340-44ce-435c-a8dc-d3fe1df705a1.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;피드포워드란 흐름이 단방향인 신경망을 뜻한다. 피드포워드 구조는 구성이 단순하여 구조를 이해하기 쉽고 많은 문제에 응용할 수 있다는 장점이 있지만, 커다란 단점이 하나 있으니 바로 시계열 데이터를 잘 다루지 못한다는 것이다. 즉, 단순한 피드포워드 신경망에서는 시계열 데이터의 성질(패턴)을 충분히 학습할 수 없다. 그래서 순환신경망&lt;sup&gt;Recurrent Neural Network(RNN)&lt;/sup&gt;이 등장하게 된다.&lt;/p&gt;
&lt;h2&gt;순환하는 신경망&lt;/h2&gt;
&lt;p&gt;RNN의 특징은 순환하는 경로 (닫힌 경로)가 있다는 것이다. 이 순환 경로를 따라 데이터는 끊임없이 순활할 수 있다. 그리고 데이터가 순환되기 때문에 과거의 정보를 기억하는 동시에 최신 데이터로 갱신될 수 있다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134012485-b71a5fac-4111-4873-bda6-60cf9ad2c1f0.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;위의 그림처럼 RNN 계층은 순환하는 경로를 포함한다.&lt;br&gt;
이 순환 경로를 따라 데이터를 계층 안에서 순환시킬 수 있다.&lt;/p&gt;
&lt;p&gt;여기서 Xt는 (X0, X1, …, Xt) 가 RNN 계층에 입력됨을 표현한 것이다.&lt;br&gt;
그리고 그 입력에 대응하여 (h0, h1, …, ht) 가 출력된다.&lt;/p&gt;
&lt;h2&gt;순환 구조 펼치기&lt;/h2&gt;
&lt;p&gt;RNN의 순환 구조는 피드포워드 구조에서는 볼 수 없던 구조이지만, 이 순환 구조를 펼치면 친숙한 피드포워드와 유사한 신경망으로 변신시킬 수 있다. 위의 그림에서 보듯, RNN 계층의 순환 구조를 펼침으로써 오른쪽으로 진행하는 피드포워드 신경망과 비슷한 구조가 된 것을 볼 수 있다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134012663-ee63b994-77a5-4d37-aaf1-cac8f29435a8.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;위의 그림에서 보듯, RNN 계층의 순환 구조를 펼침으로써 오른쪽으로 진행하는 피드포워드 신경망과 비슷한 구조가 된 것을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;하지만 RNN에서는 다수의 RNN 계층 모두가 실제로는 ‘같은 계층’인 것이 피드포워드 신경망과는 다르다.&lt;/p&gt;
&lt;p&gt;위의 그림에서 알 수있듯, 각 시각의 RNN 계층은 그 계층으로의 입력과 그 전의 RNN 계층으로부터의 출력을 받는다.&lt;/p&gt;
&lt;p&gt;그리고 이 두 정보를 바탕으로 현 시각의 출력을 계산한다. 이때 수행하는 계산 수식은 다음과 같다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134012757-dcb7a411-532d-43bc-8fc8-4aa5aa0c106f.png&quot; width=&quot;300&quot;&gt;  
&lt;p&gt;앞의 그림에서 보이듯이, RNN은 2개의 입력을 받는다. 그렇기에 각 입력에 대해 2개의 가중치가 있다. 하나는 입력 x를 출력 h로 변환하기 위한 가중치 W&lt;sub&gt;x&lt;/sub&gt;이고, 다른 하나는 1개의 RNN 출력을 다음 시각의 출력으로 변환하기 위한 가중치 W&lt;sub&gt;h&lt;/sub&gt;이다. 위의 식에서 행렬 곱을 계산하고 그 합을 tanh 함수를 이용해 변환한다.&lt;/p&gt;
&lt;p&gt;즉, 이 식에서 볼 수 있듯이 현재의 출력 h&lt;sub&gt;t&lt;/sub&gt;는 한 시각 이전 출력 h&lt;sub&gt;t-1&lt;/sub&gt;에 기초해 계산됨을 알 수 있다.&lt;/p&gt;
&lt;p&gt;이러한 구조를 갖고 있기에 RNN 계층을 메모리가 있는 계층이라고 한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;
RNN의 h는 상태를 기억해 시각이 1 스텝 진행될 때마다 위의 식 형태로 갱신된다.
이 h를 통상적으로 은닉 상태 (Hidden State) 혹은 은닉 상태 벡터 (Hidden State Vector)라고 한다.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위의 식이 어떻게 동작하는지를 자세히 살펴보기 전에 Hyperbolic tangent에 대해 살펴보고 가자.&lt;/p&gt;
&lt;h2&gt;Hyperbolic tangent&lt;/h2&gt;
&lt;p&gt;해당 부분은 &lt;a href=&quot;http://taewan.kim/post/tanh_diff/&quot;&gt;http://taewan.kim/post/tanh_diff/&lt;/a&gt; 을 참고했습니다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134013283-75af9e82-0dbf-49f1-9e67-1d140a635344.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;Hyperbolic tangent 함수는 머신러닝에서 자주 사용되는 활성화 함수인 Sigmoid의 대체제로 사용될 수 있는 활성화 함수이다.&lt;/p&gt;
&lt;p&gt;tanh는 sigmoid와 매우 유사한데, tanh와 sigmoid의 차이점은 sigmoid의 출력 범위가 0 ~ 1인 반면 tanh의 출력 범위는 -1 ~ +1 사이라는 점이다.&lt;/p&gt;
&lt;p&gt;Sigmoid와 비교하여 tanh는 출력 범위가 더 넓고 경사면이 큰 범위가 더 크기 때문에 더 빠르게 수렴하여 학습하는 특성이 있다.&lt;/p&gt;
&lt;h3&gt;Hyperbolic tangent의 미분&lt;/h3&gt;
&lt;p&gt;RNN의 역전파를 계산하기 위해 필요한 tanh의 미분은 다음과 같다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134013301-aec980e9-d91c-4dd1-bd4f-447e3d0f160c.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;이후 RNN의 역전파 (Backpropagation) 에서 해당 수식이 사용된다.&lt;/p&gt;
&lt;h2&gt;RNN 계층의 순전파&lt;/h2&gt;
&lt;p&gt;앞에서 RNN 계층에서의 순전파에 사용되는 수식을 살펴봤다. 1개의 인풋 데이터에 대한 입력과, 한 시각 이전의 Hidden State가 입력된다는 점과 이를 tanh 함수에 넣는다는 점을 기억하자.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134013593-a47a383d-6d50-4ded-9b32-902dafe5f938.png&quot; width=&quot;300&quot;&gt;
&lt;p&gt;해당 수식을 시각화하여 표현하면 다음 그림과 같다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134013617-0a32f7fa-bc1d-4ee3-83d5-8ef3207cd2db.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;X와 h&lt;sub&gt;prev&lt;/sub&gt;를 입력으로 받아 내부적인 계산을 거친 후, h&lt;sub&gt;next&lt;/sub&gt;라는 출력을 분기시켜 내놓는다.&lt;/p&gt;
&lt;p&gt;다음 과정을 파이썬 코드로 표현하면 다음과 같다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134013811-6e993d35-2ab7-41a8-b8c2-2f0f406aa06f.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;순전파는 위의 그림만 머리에 넣었다면 쉽게 이해할 수 있을 것이다. 그러면 이제 RNN에서의 역전파 (Backpropagation) 를 살펴보자.&lt;/p&gt;
&lt;h2&gt;BPTT (Backpropagation Through Time)&lt;/h2&gt;
&lt;p&gt;앞에서 봤듯이 RNN 계층은 가로로 펼친 신경망으로 간주할 수 있다. 따라서 RNN의 학습도 보통의 신경망과 같은 순서로 진행할 수 있다. 이를 그림으로 보면 다음과 같다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134013934-a141a438-4184-4e84-9362-ba0759c238ec.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;위의 그림에서 보듯, 순환 구조를 펼친 후의 RNN에는 피드포워드 오차역전파법을 적용할 수 있다. 즉, 먼저 순전파를 진행하고 이어서 역전파를 수행하여 원하는 기울기&lt;sup&gt;gradient&lt;/sup&gt;를 구할 수 있다.&lt;/p&gt;
&lt;p&gt;여기서의 오차역전파법은 ‘시간 방향’으로 펼친 신경망의 오차역전파법이라는 뜻으로 BPTT&lt;sup&gt;Backpropagation Through Time&lt;/sup&gt;이라고 한다.&lt;/p&gt;
&lt;p&gt;이 BPTT를 이용하면 RNN을 학습할 수 있다. 하지만 위의 BPTT를 그대로 적용하게 되면 문제가 하나 있다.&lt;/p&gt;
&lt;p&gt;바로 긴 시계열 데이터를 학습할 때 시계열 데이터의 크기가 커지는 것에 비례하여 BPTT가 소키하는 컴퓨팅 자원도 증가하기 때문이다. 또한 시간 크기가 커지면 역전파 시에 기울기 값이 조금씩 작아져서 0에 가까워지는 &lt;strong&gt;Vanishing Gradient Problem&lt;/strong&gt;도 발생하게 된다.&lt;/p&gt;
&lt;h2&gt;Truncated BPTT&lt;/h2&gt;
&lt;p&gt;이러한 문제를 해결하기 위해 나온 방법이 &lt;strong&gt;Truncated BPTT&lt;/strong&gt;이다.
시간축 방향으로 길어진 신경망을 적당한 지점에서 잘라내 여러 개로 만든다는 아이디어다.
그리고 이 잘라낸 작은 블록 단위로 오차역전파법을 수행한다.
이것이 &lt;strong&gt;Truncated BPTT&lt;/strong&gt;라는 기법이다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134014257-438b6043-6906-4302-8f04-7ac0df6d7b3e.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;여기서 주의할 점은 역전파의 연결만 끊고, 순전파의 연결은 반드시 그대로 유지해야한다는 점이다. 즉, 순전파의 흐름은 끊어지지 않고 전파되어야 한다.&lt;/p&gt;
&lt;h2&gt;Backpropagation Review&lt;/h2&gt;
&lt;p&gt;이제 본격적인 RNN 계층의 역전파에 들어가기 전에, 기본적으로 필요한 역전파에 대한 개념을 간단히 살펴보자.&lt;/p&gt;
&lt;h3&gt;덧셈 노드의 역전파&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134014470-79b927d1-e970-45c2-8392-f77bbf97c155.png&quot; width=&quot;400&quot;&gt;  
&lt;p&gt;덧셈 노드의 역전파는 상류에서 전해진 미분을 그대로 흘려보낸다.&lt;br&gt;
z = x + y 라는 식이 있을 때 역전파를 생각해보면 다음과 같다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;σz/σx = 1, 
σz/σy = 1 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;즉, 상류에서 전해진 미분에 x1 을 하는 것이므로 그대로 흘려보내는 것과 같다.&lt;/p&gt;
&lt;h3&gt;곱셈 노드의 역전파&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134014479-759fc3eb-dbe2-4d9e-8043-77a9dfb9fde7.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;곱셈 노드의 역전파는 상류의 값에 순전파 때의 입력 신호들을 ‘서로 바꾼 값’을 곱해서 하류로 보낸다.
z = xy 라는 식의 역전파를 생각해보면 다음과 같다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;σz/σx = y, 
σz/σy = x &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;전파 때의 입력신호들을 서로 바꾼 값이 되는 것을 확인할 수 있다. 그러므로 상류에서 들어온 신호에 순전파 때의 입력 신호들을 서로 바꾼 값을 곱해서 하류로 흘려보내면 된다.&lt;/p&gt;
&lt;p&gt;여기서 그냥 곱셈인 경우와 행렬 곱셈은 다르지 않나? 라고 생각할 수 있는데, 행렬도 어차피 각 요소간의 곱으로 이루어진 집합이기 때문에 결과적으로는 같은 결과를 보인다.&lt;/p&gt;
&lt;h2&gt;Backpropagation in RNN&lt;/h2&gt;
&lt;p&gt;그럼 이제 본격적으로 RNN에서의 역전파를 살펴보자.&lt;/p&gt;
&lt;h3&gt;RNN 계층의 역전파  -  (1) dh&lt;sub&gt;next&lt;/sub&gt;&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134014902-01635d08-73fb-47e2-8cb4-7e43a114cfc6.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;먼저 다음 층의 역전파인 dhnext를 넘겨받는다. 피드포워드 신경망에서와 마찬가지로 순전파때의 반대 방향으로 역전파가 진행되는 점 주의&lt;/p&gt;
&lt;h3&gt;RNN 계층의 역전파  -  (2) d&lt;sub&gt;tanh&lt;/sub&gt;&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134015092-d5405345-bf7a-44dd-9ced-58a225b1abdb.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;먼저 tanh의 미분결과가 1 - tanh2(x)이였던 점을 기억하자.&lt;br&gt;
다음으로 위에서 흘러온 dh&lt;sub&gt;next&lt;/sub&gt;와 1 - tanh2(x)값을 곱해서 d&lt;sub&gt;tanh&lt;/sub&gt;를 계산한다.&lt;/p&gt;
&lt;h3&gt;RNN 계층의 역전파  -  (3) 덧셈 노드&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134015263-787b2f3b-4299-4a48-afe3-97a72994db08.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;앞에서 간단히 살펴봤듯이 덧셈 노드의 경우 역전파를 그대로 흘려보낸다.&lt;br&gt;
그러므로 db를 제외한 역전파는 dtanh를 그대로 흘려보내주면 되므로 따로 계산하지 않는다.&lt;br&gt;
여기서는 미니배치 단위 학습을 고려해서 코드를 작성하므로 db는 NxH 형상을 가진다.&lt;br&gt;
그러므로 편향 (b) 의 역전파는 데이터를 단위로 한 축인 axis=0의 합으로 계산한다.&lt;/p&gt;
&lt;h3&gt;RNN 계층의 역전파  -  (4) 곱셈 노드&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134015383-601a04ce-3541-41d1-8208-1155b9503f6b.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;역시 앞에서 간단히 살펴봤듯이 곱셈 노드의 경우 상류에서 들어온 값에 순전파 때의 입력 신호들을 서로 바꾼 값을 곱해준다.&lt;br&gt;
해당 법칙에 따라 나머지 모든 역전파를 계산한다.&lt;/p&gt;
&lt;h2&gt;Time RNN&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134015580-32f33314-f54f-44fb-bda5-d04e9caa9532.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;앞에서까지는 하나의 RNN 계층에서 일어나는 순전파 및 역전파에 대해 살펴봤다.&lt;br&gt;
이제 RNN 계층 T개를 연결한 신경망을 완성해보자.&lt;br&gt;
이렇게 T개의 RNN을 연결한 신경망을 TimeRNN이라고 부를 것이다.&lt;br&gt;
그리고 이 구현에서는 Truncated BPTT로 구현한다.&lt;/p&gt;
&lt;h3&gt;Time RNN의 순전파&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134015697-1fa6975c-e316-4113-b39f-dac65917eb6d.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;순전파는 아래로부터 T개의 입력데이터인 xs를 입력으로 받는다.&lt;br&gt;
미니배치 처리까지 고려했을 때의 xs의 형상은 NxTxD가 된다.&lt;br&gt;
(N : 미니배치 수, T : 시계열 데이터 수, D : 입력벡터 차원 수)&lt;/p&gt;
&lt;p&gt;앞에서 각 RNN 층에서의 순전파를 구현해놨기 때문에 이를 적당히 이어주기만 하면 된다.&lt;br&gt;
Hidden State인 h는 처음 호출 시 영행렬로 초기화를 하고, 시계열 데이터의 수만큼 for문을 돌면서Hidden State를 업데이트 한다.&lt;br&gt;
그리고 이 Hidden State T개의 집합인 hs를 반환한다.&lt;/p&gt;
&lt;h3&gt;Time RNN의 역전파&lt;/h3&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134015858-d773df4c-8c81-4f13-bd92-db1c2f843121.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;RNN은 순전파시에 출력이 2개로 분기되었던 점을 떠올리자.&lt;br&gt;
이렇게 순전파시 분기한 경우, 역전파에서는 각 기울기가 합산되어야 한다.&lt;br&gt;
따라서 역전파 시 RNN 계층에서는 기울기 (dh&lt;sub&gt;t&lt;/sub&gt;, dh&lt;sub&gt;next&lt;/sub&gt;)가 한산되어야 한다.&lt;/p&gt;
&lt;p&gt;각 RNN 계층에서 역전파를 이미 구현해놨기 때문에 위 사항만 주의하여 적절하게 이어주면 된다.&lt;/p&gt;
&lt;p&gt;추가적으로 주의할 점은 Truncated BPTT 방식이기 때문에 처음 dh는 0으로 시작된다는 점이다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;각 시각의 기울기인 dx를 모아서 dxs에 저장하고, 가중치 매개변수 역시 각 RNN 계층의 가중치 기울기를 합산하여 최종 결과를 멤버 변수 self.grads에 덮어쓴다.&lt;/p&gt;
&lt;p&gt;이상으로 RNN의 등장배경부터 개념 및 순전파 역전파 등에 대해서 알아봤다.&lt;br&gt;
다음에는 해당 RNN을 개선한 LSTM에 대해 알아보자.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[네이버 2019 해커톤 - Speech 결선진출]]></title><description><![CDATA[네이버 2019 해커톤 - Speech 결선진출 네이버  2019 해커톤 - Speech 대회 예선전에서 100 팀 중 11위를 기록하며 예선전을 통과했다 !! 오늘 아침까지만 해도 10위여서 Top 1…]]></description><link>https://sooftware.github.io/naver_2019_hackathon/</link><guid isPermaLink="false">https://sooftware.github.io/naver_2019_hackathon/</guid><pubDate>Thu, 21 Nov 2019 10:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;네이버 2019 해커톤 - Speech 결선진출&lt;/h2&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134181220-509b6452-468c-4455-b1fd-d35d7fd56752.png&quot; width=&quot;600&quot;&gt;
&lt;p&gt;네이버  2019 해커톤 - Speech 대회 예선전에서 100 팀 중 11위를 기록하며 예선전을 통과했다 !!&lt;br&gt;
오늘 아침까지만 해도 10위여서 Top 10 으로 결선을 갈 수 있겠구나 하며 팀원들과 기대하고 있었는데,&lt;br&gt;
‘행복코딩’ 팀이 8위로 급상승하면서 11위로 내려와서 Top 10은 들어가지 못해서 꽤나 아쉬웠다 ㅋㅋㅋㅋ&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134181345-fdb7c896-c19c-46bf-90a4-5fef10228812.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;실력은 아직 많이 부족해서 우리 팀은 시간 투자를 많이했다.  위의 사진에서 Count란의 숫자를 보게 되면 압도적으로 높은 140이 우리의 모델 Submit 횟수이다.  처음부터 50, 60 점 가까이 맞아가는 다른 팀들을 보면서 아직 멀었구나라는 사실을 다시 한번 느꼈지만, 우리 팀은 4점부터 시작해서 17점 35점 41점 50점 ,52, 56, 58, 59, 61 …  70점까지 빠득빠득 올라갔다 ㅋㅋㅋ 역시 뭐든지 시간을 때려박으면 되는 것 같다.&lt;/p&gt;
&lt;p&gt;팀이름 Kai.Lib는 현재 우리가 진행하고 있는 1년간의 졸업과제 프로젝트 팀이름이기도 한데,&lt;br&gt;
우리가 재학중인 학교이름을 넣어서 Kwangwoon A.I Library 라는 뜻으로 만들었다 ㅋㅋㅋ
나중에 최종적으로 만든 소스코드 및 모델을 오픈소스 라이브러리 형태로 배포하자는 포부에서 만든 팀명이다.&lt;/p&gt;
&lt;p&gt;위의 Score는 CRR이라고 하여 Character Recognition Rate . 즉 문자 단위로 점수를 계산하는 방식이다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134181601-38750dae-e398-4195-a5eb-bb4eca5ff078.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;데이터는 네이버에서 제공한 100시간 한국어 전화망 DB만을 사용하여 학습을 진행했다.&lt;br&gt;
그리고 음성인식의 모델 학습 같은 경우는 네이버에서 만든 NSML이라는 플랫폼을 이용하여&lt;br&gt;
우리가 소스코드를 짜서 NSML 프로그램으로 run을 하면, 네이버측에서 gpu와 cpu를 이용해서 학습을 진행해주었다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134181692-c5be8679-3b36-423f-ab7f-ae845945af8e.png&quot; width=&quot;500&quot;&gt;
&lt;p&gt;그래픽 카드는 Tesla p40 으로 초고사양의 그래픽 카드로 학습을 할 수가 있었고, 한 번에 최대 gpu 2개 cpu 8개로 한 모델을 학습시킬 수가 있었다.  대회 초기에는 제한이 많이 안 걸려서 한 번에 모델 6개를 학습시키도 했던 것 같다 ㅎㅎㅎ&lt;/p&gt;
&lt;p&gt;그리고 학습시킨 모델을 submit하게 되면 네이버에서 가지고 있는 테스트셋으로 결과를 계산해서 점수를 알려주고 바로 랭킹에 반영하는 방식으로 대회가 진행되었다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134181844-8b9a3242-0aa0-417a-9117-e4e908bd0c69.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;예선전 같은 경우는 단순 인식률 (CRR) 만을 보고서 진행이 됐지만,&lt;br&gt;
결선은 이제 모델 사이즈, 인식 속도, 인식률 이 3가지를 종합해서 고려하여 랭킹을 매긴다고 한다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134181862-ca4e34b7-65a7-4231-8c42-c1ec8c5013e3.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;오프라인 결선 날짜 같은 경우는 네이버측의 사정으로 날짜가 추후 공지된다고 한다.&lt;br&gt;
결선 진행 장소인 춘천에 있는 ‘네이버 커넥트원’ 이라는 곳을 가보는 것 또한 기대가 된다 ㅎㅎ&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134182054-d7eea886-30e5-4328-8260-7b40f0510822.png&quot; width=&quot;400&quot;&gt;
&lt;p&gt;우리 팀은 목표를 결선에서 Top 10 안에 드는 것을 목표로 뒀다.&lt;br&gt;
수상을 하면 좋겠지만 워낙 쟁쟁한 분들이 많기에 목표를 조금 낮췄다 ㅎㅎ..&lt;br&gt;
앞으로 남은 온라인 결선 및 오프라인 결선에서 더 나은 모델이 나오기를 바란다.&lt;/p&gt;
&lt;p&gt;(추가) 네이버 결선 관련 공지&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134182125-db727e23-19fb-471d-9ddd-96ed90625092.png&quot; width=&quot;400&quot;&gt;  
&lt;p&gt;예선 팀들이 기대 이상으로 매우 높은 인식률을 달성해줬다고 한다.
그 중 한 팀이 우리 팀이란 생각에 기분이 좋다 ^.^&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - DeepSpeech Paper Review]]></title><description><![CDATA[Deep Speech: Scaling up end-to-end speech recognition title https://arxiv.org/pdf/1412.5567.pdf (Awni Hannun et al. 2014) Abstract…]]></description><link>https://sooftware.github.io/deepspeech/</link><guid isPermaLink="false">https://sooftware.github.io/deepspeech/</guid><pubDate>Mon, 11 Nov 2019 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Deep Speech: Scaling up end-to-end speech recognition&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006014-e0ea7aa9-fa25-4b31-90fe-c1144cd68d40.png&quot; alt=&quot;title&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/pdf/1412.5567.pdf&quot;&gt;https://arxiv.org/pdf/1412.5567.pdf&lt;/a&gt; (Awni Hannun et al. 2014)&lt;/p&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;p&gt;본 논문은 2014년도에 나온 논문이다. 논문을 읽어본 결과, 당시에는 음성인식에 End-to-End 방식의 딥러닝을 적용한 사례가 없던 모양이다. (또는 주목할만한 성과가 나오지 않았던 모양이다.) 본 논문에서는 End-to-End 방식으로 Switchboard Hub5’00 데이터셋에서 16.0%의 Error Rate를 기록하며 &lt;strong&gt;State-Of-The-Art&lt;/strong&gt; (SOTA) 를 달성한 성과를 밝히고 있다. 기존 음성인식의 traditional한 방식은 전처리 과정이 상당히 많이 필요했지만, 이러한 과정 없이 데이터와 레이블만을 이용한 End-to-End 방식으로 이러한 성과를 냈음을 거듭 강조하고 있다. 그리고 이전 방식으로는 노이즈가 있는 환경에서 급격히 떨어졌는데 반하여, 본 논문 방식으로는 노이즈가 있는 환경에서도 좋은 성능을 기록했다고 한다. 즉, 기존 방식보다 더 간단하면서도 좋은 성능을 기록한 End-to-End 방식의 Speech-Recognition 모델을 소개하는 논문이다.&lt;/p&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Abstract에서 강조한 내용을 다시 한번 강조한다. 기존 traditional한 방식은 전문가들의 손이 많이 가야했다. (노이즈 필터링 등..) 하지만 그러한 노력에도 불구하고, 실제 노이즈가 낀 상황에서의 인식률은 좋지 못했다. 하지만 End-to-End 방식으로 이러한 2가지의 단점을 개선할 수 있다고 주장한다.&lt;/p&gt;
&lt;p&gt;물론 End-to-End 방식으로 가기 위해서는 몇가지 고려해야할 사항들이 있었지만, 본 논문에서는 기존 연구 결과들을 참고하여 End-to-End 방식을 시도할 수 있었다고 말한다. 그리고, 본 논문에서는 RNN 모델을 사용했다. 뒤에 더 자세히 설명하겠지만 본 논문에서는 학습 시간을 단축시키기 위해 많은 고려를 한 것으로 보인다.&lt;/p&gt;
&lt;h2&gt;RNN Training Setup&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006049-0cdcb969-0383-4722-b675-87b9f3587488.png&quot; alt=&quot;model&quot;&gt;&lt;/p&gt;
&lt;p&gt;해당 챕터에서는 자신들이 어떤 식으로 모델을 구성했는지에 대해 설명한다.&lt;br&gt;
모델의 핵심은 RNN으로 구성되어 있으며, 트레이닝 셋은 ${(x_1, y_1), (x_2, y_2), … (x_t, y_t)}$ 와 같은 딕셔너리 형식으로 구성했다고 한다. (x는 스펙트로그램, y는 문자로 구성 )&lt;/p&gt;
&lt;p&gt;모델은 총 5개의 히든 레이어로 구성했다고 한다.
논문을 읽으면서 모델 아키텍쳐가 상당히 특이하다고 생각했다.&lt;/p&gt;
&lt;p&gt;현재 내가 알고있는 방식과는 사뭇 다른 방식이였는데, 히든 레이어 중 1, 2, 3번째 레이어는 병렬적 (Parallel) 하게 처리하기 위해 서로 독립적으로 포워딩 된다고 한다. RNN 아키텍쳐를 사용하게 되면 이전 셀의 아웃풋이 필요하기 때문에 어쩔 수 없이 병렬처리의 한계점이 있기 때문에 학습 속도 개선을 위해 각 인풋을 독립적으로 처리했다고 한다.&lt;br&gt;
여기서도 나는 본 논문이 학습 시간을 단축시키기 위해 상당히 노력했다는 인상을 받았다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006132-c4eef972-3f32-4839-953f-8950ddc08b47.png&quot; alt=&quot;forward&quot;&gt;&lt;/p&gt;
&lt;p&gt;위의 수식을 통해 포워딩이 진행되는데, 여기서 g는 최소 0, 최대 20의 값을 가지는 ReLU 함수이다.&lt;br&gt;
그리고 4번째 레이어에서는 Bidirectional-RNN으로 구성했다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006150-b5ab3ce6-27a3-44fd-9a61-50e96e031071.png&quot; alt=&quot;Bi-RNN&quot;&gt;&lt;/p&gt;
&lt;p&gt;(f)는 정방향 (forward), (b)는 역방향 (backward)을 표현한 것이다.&lt;br&gt;
이때 주의할 점으로는, forward는 t = 1 에서 t = T 방향으로 흐르고, backward는 t = T에서 t = 1 방향으로 흐른다는 점이다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006159-84108cbf-f8d5-47d7-aa57-43400eb37c1d.png&quot; alt=&quot;5-layer&quot;&gt;&lt;/p&gt;
&lt;p&gt;그리고 마지막 5번째 레이어는 이렇게 forward, backward의 결과에 웨이트를 주고 1, 2, 3 번째 레이어와 동일한 ReLU를 활성화 함수로 사용했다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006172-ba0e1f77-acc5-4f55-a469-57df1bb95881.png&quot; alt=&quot;softmax&quot;&gt;&lt;/p&gt;
&lt;p&gt;그리고 이렇게 나온 결과는 Softmax 함수에 넣어서 최종적으로 Classfication을 진행한다. 또한 loss 계산시에는 CTC loss를 사용했다.&lt;/p&gt;
&lt;p&gt;여기서 또 특이했던 점으로, LSTM이 아닌 기본 RNN을 사용했다는 점이다.&lt;br&gt;
그 이유로 본 논문에서는 LSTM의 단점은 메모리가 많이 소요되고, 학습이 오래걸린다는 점을 꼽았다.&lt;/p&gt;
&lt;p&gt;총 5개의 히든 레이어 중 실제 RNN 계층은 1개 뿐이라는 점과, LSTM이 아닌 RNN을 사용했다는 점이 인상깊었다.&lt;br&gt;
최근 연구에서는 기본 RNN을 사용하는 모습을 거의 볼 수 없는데, 당시에는 아직 GPU의 성능이 그리 좋지 않던 때라 그런지 학습 속도에 대해 굉장히 고려를 많이한 모습이 보였다.&lt;/p&gt;
&lt;h3&gt;Regularization&lt;/h3&gt;
&lt;p&gt;본 논문은 학습 시, 드랍아웃 비율을 5 - 10%정도를 유지했다고 한다.&lt;br&gt;
그리고 Spectrogram의 프레임 길이는 10ms, 포워딩은 5ms를 사용했다.&lt;br&gt;
(해당 부분은 오류가 있을수도 있습니다)&lt;/p&gt;
&lt;p&gt;통상적으로 음성 인식에서 프레임 길이는 20 - 40ms를 사용하기 때문에 프레임 길이가 상당히 짧다고 생각했다.&lt;br&gt;
해당 부분은 다른 이유가 있어서 짧게 한 건지, 당시에 프레임 길이에 대한 연구가 현재보다 덜 발달해서 그런 것인지는 확인을 해봐야 할 듯 하다.&lt;/p&gt;
&lt;h3&gt;Language Model&lt;/h3&gt;
&lt;p&gt;본 논문의 모델은 성능 테스트시에, 정확히 맞추거나 그럴싸하게 틀렸다고 한다.&lt;br&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006322-cd818c2b-5b83-4875-a558-26b21cdcf2aa.png&quot; alt=&quot;performance-test&quot;&gt;&lt;/p&gt;
&lt;p&gt;arther =&gt; are there, n tickets =&gt; any tickets 등 꽤나 말이 되도록 틀린 것을 볼 수 있다.&lt;br&gt;
본 논문은 이보다 더 정확한 인식을 위하여 N-gram Language Model을 사용했다고 한다.&lt;/p&gt;
&lt;p&gt;매우 방대한 텍스트 Corpus로 N-gram language model을 학습시켰으며, 해당 언어 모델은 다음 공식에 사용됐다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006338-ca5fd3b0-575f-4bcc-b512-1785a11b8d51.png&quot; alt=&quot;scoring&quot;&gt;&lt;/p&gt;
&lt;p&gt;여기서 알파, 베타는 설정 가능한 파라미터이다.&lt;br&gt;
본 논문에서는 성능을 향상시키기 위해 빔서치를 사용했는데, 이때 빔 사이즈를 1,000 - 8,000으로 상당히 크게 준 것을 볼 수 있었다.&lt;br&gt;
이후에 나온 논문들을 봤을 때, 빔 사이즈 단위는 기껏 해봐야 수십 정도였는데 본 논문은 상당히 큰 빔 사이즈를 사용한 것을 볼 수 있었다.&lt;/p&gt;
&lt;h2&gt;Optimizations&lt;/h2&gt;
&lt;p&gt;해당 장에서는 어떻게 최적화를 했는지에 대해 설명하고 있다.&lt;br&gt;
주로 빠른 학습을 시키기 위해 어떤 노력을 했는지를 설명했다.&lt;/p&gt;
&lt;h3&gt;Data Parallelism&lt;/h3&gt;
&lt;p&gt;데이터를 효과적으로 처리하기 위해 2-level data parallelism을 사용했다고 한다.&lt;/p&gt;
&lt;p&gt;미니배치 단위로 처리를 했는데, 이때 배치의 크기를 GPU 메모리 한계까지 사용했다고 한다.&lt;/p&gt;
&lt;p&gt;또한, 학습을 빨리하기 위해 NMT와 같은 Text-NLP에서 많이 사용되는, 길이 순으로 정렬해서 비슷한 길이끼리 배치로 묶었다고 한다. 이렇게 비슷한 길이끼리 배치로 묶게 되면, 배치 안에서 Max Length를 맞추기 위해 PAD token을 최소화 할 수 있다.&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;p&gt;본 논문은 음성 인식의 기반을 다진 논문인지라 논문에 소개된 대부분의 내용이 음성인식 튜토리얼 내용과 비슷했습니다.&lt;br&gt;
해당 논문 리뷰는 여기까지만 하겠습니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - Listen, Attend and Spell Paper Review]]></title><description><![CDATA[「Listen, Attend and Spell」 Review title https://arxiv.org/abs/1508.01211  (William Chan et al. 2015)  Introduction 어텐션 기반 Seq2seq…]]></description><link>https://sooftware.github.io/las/</link><guid isPermaLink="false">https://sooftware.github.io/las/</guid><pubDate>Fri, 20 Sep 2019 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;「Listen, Attend and Spell」 Review&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006522-b6c82f01-7912-407a-b6d6-dc4537f859d9.png&quot; alt=&quot;title&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/1508.01211&quot;&gt;https://arxiv.org/abs/1508.01211&lt;/a&gt;  (William Chan et al. 2015)&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;h2&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;어텐션 기반 Seq2seq 구조를 음성 인식에 적용한 논문이다.&lt;/p&gt;
&lt;p&gt;당시에는 CTC (Connectionist temporal classification) 이 음성 인식 분야를 점유하고 있던 시절이였던 터라, End-to-End 방식으로 본 논문 모델과 같은 성능을 낸 것은 굉장히 혁명적인 일이였다고 한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006536-a9b4d4eb-c13b-49c5-aef3-955e7e781350.png&quot; alt=&quot;end-to-end&quot;&gt;&lt;/p&gt;
&lt;p&gt;본 논문 이후 Speech 분야는 CTC와 LAS로 나뉜다고 한다.&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;h2&gt;&lt;strong&gt;Model&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;모델의 전체적인 구조는 Listener (encoder) 와 Speller (decoder) 로 이루어져 있다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006548-2e0f34fd-34e5-472f-8c2c-37601c058c00.png&quot; alt=&quot;las_model&quot;&gt;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Listener&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006557-cfb9ef22-c262-420f-a7c8-bbcf4a08bab1.png&quot; alt=&quot;listener&quot;&gt;&lt;/p&gt;
&lt;p&gt;데이터의 피쳐를 입력받는 Encoder&lt;br&gt;
입력 시퀀스 x를 High level feature인 h로 변형하는 역할을 담당한다&lt;br&gt;
(더 의미있는 시퀀스로 변형한다)&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Speller&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006565-14cebeeb-2fd6-479d-ab67-caad4db6f2fb.png&quot; alt=&quot;speller&quot;&gt;&lt;/p&gt;
&lt;p&gt;리스너가 변형한 High Level feature인 h를 어텐션을 사용하여 문자로 출력한다. (Decoder)&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;h3&gt;&lt;strong&gt;pBLSTM&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006706-e8c86aa2-f746-420a-875d-5bb655022cb8.png&quot; alt=&quot;pBLSTM&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006716-ce9a6994-c191-41d0-92e6-aa61a9fb55e4.png&quot; alt=&quot;pblstm_math&quot;&gt;&lt;/p&gt;
&lt;p&gt;모델의 첫 번째 특징으로는 Pyrimidal Bidirectional LSTM을 사용했다.&lt;br&gt;
이전 레이어의 2i, 2i+1 번째 시퀀스를 Concatenate하여 다음 레이어의 i번째 RNN 셀의 입력으로 넣는 구조이다.&lt;/p&gt;
&lt;p&gt;상대적으로 매우 긴 시퀀스 길이를 가지는 Speech 모델의 단점을 완화 해주는 역할을 한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006731-2115be84-5c7d-4627-9548-2711dbacce8d.png&quot; alt=&quot;blstm_pblstm&quot;&gt;&lt;/p&gt;
&lt;p&gt;위의 그림처럼 기존 BLSTM 구조에 반해, 시퀀스의 길이가 상당히 줄어드는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;pBLSTM 레이어 1층 당 시퀀스 길이가 반씩 줄어들게 되는데, 본 논문에서는 이러한 레이어를 3개를 둠으로써, 총 시퀀스 길이를 8 분의 1로 줄였다고 한다.&lt;/p&gt;
&lt;p&gt;이러한 시퀀스 길이의 감소는 디코딩 &amp;#x26; 어텐션 과정에서 연산량 감소를 가능하게한다.&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;h3&gt;&lt;strong&gt;Exposure Bias Problem&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Seq2seq에서 티쳐 포싱이라는 개념이 있다.&lt;br&gt;
티쳐 포싱의 개념은 &lt;a href=&quot;https://blog.naver.com/sooftware/221790750668&quot;&gt;이글&lt;/a&gt;을 참고하기를 바랍니다.&lt;/p&gt;
&lt;p&gt;당시에는 티쳐 포싱은 Seq2seq 아키텍쳐에서 디폴트 100%로 사용됐던 것 같다.&lt;br&gt;
티쳐 포싱은 학습을 빠르게 해준다는 장점이 있지만, Exposure Bias Problem이란게 존재한다.&lt;/p&gt;
&lt;p&gt;티쳐 포싱은 학습 시에 레이블을 제공받지만, 실제 추론 시에는 레이블을 제공 받을 수가 없다.&lt;br&gt;
이러한 차이점이 실제 추론과 학습시의 성능에 차이가 있을 수 있다는 점이다.&lt;br&gt;
이를 Exposure Bias Problem이라고 한다.&lt;/p&gt;
&lt;p&gt;본 논문에서는 이러한 문제점을 완화 및 실험해보기 위하여 티쳐 포싱 비율이 100%인 모델과 90%인 모델 2개를 학습시켰다고 한다.&lt;/p&gt;
&lt;p&gt;( 2019년 5월에 나온 「Exposure Bias for Neural Language Generation」논문에서는 이런 노출 편향 문제가 생각만큼 큰 영향을 미치지는 않는다는 연구 결과를 냈다고 한다 )&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;h3&gt;&lt;strong&gt;Decoding&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;본 논문에서는 역시 빔서치를 사용했다고 한다. (빔사이즈 = 32)&lt;br&gt;
빔서치에 대한 설명은 &lt;a href=&quot;https://blog.naver.com/sooftware/221809101199&quot;&gt;이글&lt;/a&gt;을 참고하길 바랍니다.&lt;/p&gt;
&lt;p&gt;본 논문에서 설명하기를, 기존 음성 인식 모델들은 모든 빔이 &lt;eos&gt;를 만나고 나면, 가장 높은 점수를 받은 빔을 선택한 후, Dictionary (사전) 을 통해 언어 교정을 하는 방식을 많이 사용했다고 한다.&lt;/p&gt;
&lt;p&gt;하지만, 본 논문에서 실험시에, 이 DIctionary 방식은 별로 필요가 없다고 주장한다.&lt;/p&gt;
&lt;p&gt;본 논문의 모델로 실험해본 결과, 어느 정도 학습 후에는 거의 항상 단어 단위에서는 완벽한 단어를 내놓기 때문에, 이러한 교정 과정이 필요가 없다는 것이다.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Rescoring&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;그래서 본 논문에서는 Dictionary 방식이 아닌 Rescoring 방식을 제안한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006752-c4fb0449-9da4-4a84-812c-882cc46f7ba3.png&quot; alt=&quot;rescoring&quot;&gt;&lt;/p&gt;
&lt;p&gt;빔 사이즈 만큼의 후보를 뽑아놓은 후에, 여기에 Language Model을 이용하여 점수를 매긴 뒤, 기존 점수와 LM에서 나온 점수를 적절히 결합하여 새로 점수를 매기는 것이다.&lt;br&gt;
해서, 최종적으로 가장 높은 점수를 받은 빔을 최종 선택지로 사용하는 것이다.&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;h2&gt;&lt;strong&gt;Experiments&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;본 논문에서 진행한 실험 환경은 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006766-cd720767-2c86-4705-baac-e426b53a6ea3.png&quot; alt=&quot;experiment_environ&quot;&gt;&lt;/p&gt;
&lt;p&gt;위의 환경에서 진행한 실험 결과는 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006787-318572b3-268a-428a-a987-7b6fd86d6946.png&quot; alt=&quot;result&quot;&gt;&lt;/p&gt;
&lt;p&gt;Language Model을 적용하기 전에는 노이즈가 없는 환경에서는 14.1%의 WER (Word Error Rate), 노이즈가 있는 환경에서는 16.5%의 WER을 기록했다.&lt;/p&gt;
&lt;p&gt;결과를 보면, 100%의 티쳐 포싱 비율을 가진 모델보다, 90%의 티쳐 포싱 비율을 가진 모델이 더 좋은 결과를 기록한 것을 알 수 있다.&lt;/p&gt;
&lt;p&gt;그리고 본 논문에서 제안한 &lt;strong&gt;Beam Search + Language Model&lt;/strong&gt;의 퍼포먼스는 매우 훌륭했다.&lt;/p&gt;
&lt;p&gt;모든 면에서 약 4%의 성능을 개선한 것을 확인할 수 있다.&lt;br&gt;
인식률이 85%가 넘어가는 상황에서의 4%는 엄청난 발전이라고 볼 수 있다.&lt;/p&gt;
&lt;p&gt;본 논문은 위의 결과를 통해 새로 제안한 Rescoring 방식이 의미 있는 결과를 냈다는 것을 검증했다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/134006971-80b75612-9641-4031-827d-f8a831dcc381.png&quot; alt=&quot;sota&quot;&gt;&lt;/p&gt;
&lt;p&gt;또한, 본 논문의 모델은 당시 SOTA (State-Of-The-Art) 모델인 CLDNN-HMM 모델과 비교하여 2.3% WER 정도만의 차이를 기록했다.&lt;br&gt;
CTC를 사용하지 않고도 이 정도의 성능을 낼 수 있다는 것을 보여준 셈이다.&lt;/p&gt;
&lt;p&gt;본 논문에서는 SOTA 모델과 자신들의 모델의 차이를 Convolution filter의 유무에 의해 생겼다고 추정하고 있다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sooftware Speech - MFCC (Mel-Frequency Cepstral Coefficient)]]></title><description><![CDATA[MFCC (Mel-Frequency Cepstral Coefficient) ‘Voice Recognition Using MFCC Algorithm’ 논문 참고 MFCC란? 음성인식에서 MFCC, Mel-Spectrogram…]]></description><link>https://sooftware.github.io/mfcc/</link><guid isPermaLink="false">https://sooftware.github.io/mfcc/</guid><pubDate>Tue, 18 Jun 2019 10:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;MFCC (Mel-Frequency Cepstral Coefficient)&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;‘Voice Recognition Using MFCC Algorithm’ 논문 참고&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;MFCC란?&lt;/h2&gt;
&lt;p&gt;음성인식에서 MFCC, Mel-Spectrogram는 빼놓고 얘기할 수 없는 부분이다.&lt;br&gt;
간단히 말하면, MFCC는 ‘음성데이터’를 ‘특징벡터’ (Feature) 화 해주는 알고리즘이다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/133935462-acaf3951-da9b-42ad-bc24-4ea96b742736.png&quot;&gt;
&lt;p&gt;머신러닝에서 어떠한 데이터를 벡터화 한다는 것은 곧 학습이 가능하다는 의미이기 때문에 상당히 중요한 부분이라고 할 수 있다.
데이터에서 Feature를 어떤 방법으로 뽑느냐에 따라 모델의 성능이 상당히 좌우될 수 있기 때문에 굉장히 중요하다.&lt;/p&gt;
&lt;p&gt;이러한 MFCC Feature는 파이썬에서는 제공되는 librosa라는 라이브러리를 이용해서 간단하게 뽑아올 수 있다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; librosa

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_librosa_mfcc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n_mfcc&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    SAMPLE_RATE &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16000&lt;/span&gt;
    HOP_LENGTH &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;
    N_FFT &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;512&lt;/span&gt;

    signal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; librosa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;core&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;load&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; SAMPLE_RATE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; librosa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feature&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mfcc&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; hop_length&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;HOP_LENGTH&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n_fft&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N_FFT&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 코드는 음성데이터의 파일 경로를 넘겨받아 해당 음성데이터의 MFCC Feature를 뽑아주는 함수이다.&lt;br&gt;
여기서 SAMPLE_RATE는 음성데이터의 형식에 따라 다를 수 있다.&lt;br&gt;
( Ex MP4 : 44100, PCM, WAV 16000 etc.. )&lt;/p&gt;
&lt;p&gt;밑으로는 MFCC Algorithm이 어떤 식으로 Feature를 뽑는지에 대해 수식 없이 직관적인 내용만으로 설명하겠다.&lt;/p&gt;
&lt;h2&gt;Mel-Scale&lt;/h2&gt;
&lt;p&gt;MFCC를 알기 위해서 먼저 Mel이 뭔지를 알아야 한다. Mel은 사람의 달팽이관을 모티브로 따온 값이라고 생각하면 된다! 기계에게 음성을 인식시키기 전에, 사람은 어떤 식으로 음성을 인식하는지를 살펴보자.&lt;/p&gt;
&lt;img src=&quot;https://mblogthumb-phinf.pstatic.net/20150421_279/wyepark_14296057390206BzFo_JPEG/image043.jpg?type=w2&quot;&gt;  
&lt;p&gt;사람은 소리를 달팽이관을 통해 인식한다.&lt;/p&gt;
&lt;p&gt;그럼 달팽이관은 어떤 식으로 소리를 인식할까??&lt;/p&gt;
&lt;p&gt;달팽이관을 똘똘 말려있지만, 실제로 길게 펴서 보면 달팽이관의 각 부분은 각기 다른 진동수(주파수)를 감지한다.&lt;br&gt;
이 달팽이관이 감지하는 진동수를 기반으로 하여 사람은 소리를 인식한다.&lt;/p&gt;
&lt;p&gt;그렇기 때문에 이 주파수(Frequency)를 Feature로 쓰는 것은 어떻게 보면 당연한 얘기이다.
하지만, 달팽이관은 특수한 성질이 있다.&lt;/p&gt;
&lt;p&gt;주파수가 낮은 대역에서는 주파수의 변화를 잘 감지하는데,
주파수가 높은 대역에서는 주파수의 변화를 잘 감지하지 못한다는 것이다.&lt;/p&gt;
&lt;p&gt;예를 들어, 실제로 사람은 2000Hz에서 3000Hz로 변하는 소리는 기가막히게 감지하는데, 12000Hz에서 13000Hz로 변하는 소리는 잘 감지를 하지 못한다.&lt;br&gt;
이 이유를 달팽이관의 구조로 살펴보면, 달팽이관에서 저주파 대역을 감지하는 부분은 굵지만 고주파 대역을 감지하는 부분으로 갈수록 얇아진다&lt;/p&gt;
&lt;p&gt;그렇다면, 특징벡터로 그냥 주파수를 쓰기 보다는 이러한 달팽이관의 특성에 맞춰서 특징을 뽑아주는 것이 더욱 효과적인 피쳐를 뽑는 방법일 것이다.&lt;/p&gt;
&lt;p&gt;그래서 위와 같이 사람 달팽이관 특성을 고려한 값을 Mel-scale이라고 한다.&lt;/p&gt;
&lt;h2&gt;Short-Time Fourier Transform&lt;/h2&gt;
&lt;p&gt;그리고 두 번째로 고려해야 할 사항이 있다.
음성데이터에서 주파수(frequency)를 성분을 뽑아내야 한다면 당연히 Fourier Transform을 해야 할 것이다. 그렇다면 음성데이터에 대해서 전체를 퓨리에 변환을 했다고 생각해보자.&lt;/p&gt;
&lt;p&gt;사람이 발성하는 음성은 그 길이가 천차만별일 것이다.
“안녕하세요”라고 하더라도, 어떤 사람은 1초, 어떤 사람은 3초가 걸릴 수도 있다.
그래서 음성 데이터에서 한 번에 Mel-Scale을 뽑게 되면, 이 천차만별인 길이에 대하여 같은 “안녕하세요”라는 음성이라고 학습시키기는 어려울 것이다.&lt;/p&gt;
&lt;p&gt;위와 같은 문제를 해결하기 위해 음성데이터를 모두 20~40ms로 쪼갠다. 여기서 사람의 음성은 20~40ms 사이에서는 음소(현재 내고 있는 발음)가 바뀔 수 없다는 연구결과들을 기반으로 음소는 해당 시간내에 바뀔 수 없다고 가정한다.&lt;/p&gt;
&lt;p&gt;그래서 MFCC에서는 음성데이터를 모두 20~40ms 단위로 쪼개고, 쪼갠 단위에 대해서 Mel 값을 뽑아서 Feature로 사용하는 것이다.&lt;/p&gt;
&lt;h2&gt;MFCC (Mel Frequency Cepstral Coefficient)&lt;/h2&gt;
&lt;p&gt;위에서까지 MFCC가 어떤 건지에 대해 대략적으로 이해했다면, 이제 MFCC 내부에서 어떤 식으로 동작하는지를 살펴보자.&lt;br&gt;
다음은 MFCC 추출 과정을 잘 설명한 블록 다이어그램이다.&lt;/p&gt;
&lt;p&gt;(출처 : ‘Voice Recognition Using MFCC Algorithm’ 논문)&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/133935469-e3cd70cd-9095-481c-b0c0-224cdb6584c3.png&quot;&gt;  
&lt;p&gt;위의 과정을 하나하나 직관적으로 살펴보자.&lt;/p&gt;
&lt;h3&gt;Pre-Emphasis&lt;/h3&gt;
&lt;p&gt;간단히 말하면 High-pass Filter이다. 사람이 발성 시 몸의 구조 때문에 실제로 낸 소리에서 고주파 성분은 많이 줄어들게 되서 나온다고 한다. (이게 본인이 생각하는 본인 목소리와 다른 사람이 생각하는 본인 목소리가 다른 이유라고 한다) 그래서 먼저 줄어든 고주파 성분을 변조가 강하게 걸리도록 High-pass Filter를 적용해주는 과정이다.&lt;/p&gt;
&lt;h3&gt;Sampling and Windowing&lt;/h3&gt;
&lt;p&gt;Pre-emphasis 된 신호에 대해서 앞에서 언급했던 이유 때문에 신호를 20~40ms 단위의 프레임으로 분할한다. 여기서 주의할 점은, 이 때 프레임을 50%겹치게 분할한다는 것이다. 프레임끼리 서로 뚝뚝 떨어지는 것이 아니라 프레임끼리 연속성을 만들어주기 위해 프레임을 50% 겹치게 분할한다. (물론 겹치는 정도는 조정가능한 파라미터이다)&lt;/p&gt;
&lt;p&gt;여기서 왜 연속성이 필요한지 궁금할 수 있다. 만약 프레임이 서로 뚝뚝 떨어지게 샘플링을 한다면, 프레임과 프레임의 접합 부분에서 순간 변화율이 ∞ (무한대) 가 될 수 있다.   이러한 부분을 방지하기 위한 과정이다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/133935493-64bca70f-8966-4035-9bfc-11b0c929eb17.png&quot;&gt;
&lt;p&gt;그리고 이 프레임들에 대해 Window를 각각 적용한다. 보통 Hamming Window를 많이 사용한다. 여기서 각각의 프레임들에 대해서 window를 적용하는 이유는, A frame과 B frame이 서로 연속되지 않는다면, 프레임이 접합하는 부분에서의 주파수 성분이 무한대가 되어버린다. 이러한 일을 방지하기 위해 프레임의 시작점과 끝점을 똑같이 유지해주기 위해서 Hamming Window를 적용한다.(Window 종류는 굉장히 다양한데, Hammin window가 Default라고 생각하면 된다)&lt;/p&gt;
&lt;h3&gt;Fast Fourier Transform&lt;/h3&gt;
&lt;p&gt;각각의 프레임들에 대하여 Fourier Transform을 통하여 주파수 성분을 얻어낸다. 여기 FFT 까지만 적용하더라도 충분히 학습 가능한 피쳐를 뽑을 수 있다. 하지만 사람 몸의 구조를 고려한 Mel-Scale을 적용한 feature가 보통 더 나은 성능을 보이기 때문에 아래의 과정을 진행한다.&lt;/p&gt;
&lt;h3&gt;Mel Filter Bank&lt;/h3&gt;
&lt;p&gt;가장 중요한 부분이다. 각각의 프레임에 대해 얻어낸 주파수들에 대해서 Mel 값을 얻어내기 위한 Filter를 적용한다. 아래의 그림으로 보면 쉽게 이해가 쉬울 듯 하다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/133935498-99001844-3bf9-4e76-ba29-5f7bf18552ff.png&quot;&gt;  
&lt;p&gt;앞에서 언급했듯이, 달팽이관의 특성을 고려해서 낮은 주파수에서는 작은 삼각형 Filter를 가지고, 고주파 대역으로 갈수록 넓은 삼각형 Filter를 가진다고 생각하면 된다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/133935503-fb449744-9f98-49e7-bc56-07e14f147674.png&quot;&gt;
&lt;p&gt;그래서 위와 같은 삼각형 필터 N개를 모두 적용한 필터를 Mel-filter Bank 라고 부른다. 하여, 퓨리에 변환을 통과한 신호를 위의 Mel-filter Bank를 통과하게 되면 Mel-Spectrogram이라는 피쳐가 뽑히게 된다. 최근에는 뒤의 과정을 거치지 않고 여기까지 구한 Mel-Spectrogram을 사용하는 경우가 많다.&lt;/p&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/42150335/133935537-132f1ba0-c327-48cf-a334-000403541797.png&quot;&gt;
&lt;h3&gt;Discrete Cosine Transform (DCT) 연산&lt;/h3&gt;
&lt;p&gt;앞에서 나온 Mel-Spectrogram이라는 피쳐에 대해 행렬을 압축해서 표현해주는 DCT 연산을 수행한다. 여기까지 해주면, Output으로 MFCC (Mel-Frequency Cepstral Coefficient)가 나오게 된다. 앞의 Mel-Spectrogram은 주파수끼리 Correlation이 형성되어 있는데, 이러한 상관관계를 De-Correlate해주는 역할 또한 수행한다. 위의 과정을 파이썬 NumPy를 이용해서 구현한 블로그가 있다. 코드를 하나하나 보면서 자세히 이해하고 싶은 분들은 아래의 링크를 추천한다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://haythamfayek.com/2016/04/21/speech-processing-for-machine-learning.html&quot;&gt;https://haythamfayek.com/2016/04/21/speech-processing-for-machine-learning.html&lt;/a&gt;&lt;/p&gt;</content:encoded></item></channel></rss>