<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Cyp Software Blog</title>
    <link>https://cypsw.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 21 Aug 2026 05:36:35 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Cyp</managingEditor>
    <image>
      <title>Cyp Software Blog</title>
      <url>https://tistory1.daumcdn.net/tistory/3873573/attach/86c7675716444d4f8705f4833e63bdbe</url>
      <link>https://cypsw.tistory.com</link>
    </image>
    <item>
      <title>RSI(Recursive Self-Improvement) 에 대한 견해</title>
      <link>https://cypsw.tistory.com/entry/RSIRecursive-Self-Improvement-%EC%97%90-%EB%8C%80%ED%95%9C-%EA%B2%AC%ED%95%B4</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;닉 보스트롬의 '슈퍼 인텔리전스' 에서는 RSI와 초지능&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(ASI, Artificial SuperIntelligence)&lt;/span&gt;에 대한 이야기를 접할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;579&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfkzZD/dJMcagfo3Fa/fyyg8wNty1qonkZiIyw181/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfkzZD/dJMcagfo3Fa/fyyg8wNty1qonkZiIyw181/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfkzZD/dJMcagfo3Fa/fyyg8wNty1qonkZiIyw181/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfkzZD%2FdJMcagfo3Fa%2Ffyyg8wNty1qonkZiIyw181%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;579&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;579&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초지능을 논할 때 빠질 수 없는 주제 중 하나가 바로 RSI&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Recursive Self-Improvement, 재귀적 자기 개선)&lt;/span&gt;이다. 말 그대로 자기 자신을 지속적으로 개선해 나가는 과정을 뜻한다.&lt;br /&gt;&lt;br /&gt;이를&amp;nbsp;아주&amp;nbsp;넓은&amp;nbsp;의미로&amp;nbsp;해석한다면,&amp;nbsp;고양이&amp;nbsp;역시&amp;nbsp;일종의&amp;nbsp;RSI를&amp;nbsp;수행한다고&amp;nbsp;볼&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;반복해서&amp;nbsp;쥐를&amp;nbsp;사냥하는&amp;nbsp;고양이는&amp;nbsp;경험을&amp;nbsp;통해&amp;nbsp;점차&amp;nbsp;사냥의&amp;nbsp;노하우를&amp;nbsp;익히고&amp;nbsp;성공률을&amp;nbsp;높여간다.&amp;nbsp;물론&amp;nbsp;이러한&amp;nbsp;개선은&amp;nbsp;어느&amp;nbsp;지점에서&amp;nbsp;한계에&amp;nbsp;도달하겠지만&amp;nbsp;말이다.&amp;nbsp;인류의&amp;nbsp;발전&amp;nbsp;역사&amp;nbsp;또한&amp;nbsp;개개인의&amp;nbsp;학습과&amp;nbsp;자기&amp;nbsp;개선이&amp;nbsp;축적되고&amp;nbsp;공유되면서&amp;nbsp;집단&amp;nbsp;전체의&amp;nbsp;발전으로&amp;nbsp;이어진&amp;nbsp;결과라고&amp;nbsp;볼&amp;nbsp;수&amp;nbsp;있다.&lt;br /&gt;&lt;br /&gt;다만 인공지능에서 말하는 RSI와 이러한 유기체의 RSI 사이에는 결정적인 차이가 있다. 바로 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;속도와 한계&lt;/span&gt;&lt;/b&gt;이다.&lt;br /&gt;&lt;br /&gt;유기체의 RSI에는 필연적으로 생물학적 제약이 따른다. 인간의 지능 역시 예외가 아니다. 인간의 두뇌는 여성의 골반 크기로 인한 출산의 위험성, 뇌가 소비하는 막대한 에너지와 같은 여러 생물학적 조건에 의해 그 크기와 성능의 상한을 제한받아 왔다. 더 근본적으로 보자면, 인간의 지능은 그 자체를 목적으로 진화한 것이 아니라 생존과 번식이라는 목적을 달성하는 과정에서 발달한 능력에 가깝다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 뇌의 크기와 복잡성을 무한정 증가시키는 것은 물리적으로 불가능할 뿐만 아니라, 현재 인간이 생태계 먹이사슬의 최상위권을 차지하고 있는 상황에서는 지능을 훨씬 더 높은 수준으로 끌어올려야 할 진화적 압력 역시 크지 않다. 결국 생물학적 지능의 자기 개선은 느리고, 여러 물리적 제약에 묶여 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 누군가는 이렇게 반박할지도 모르겠다. &quot;두뇌의 크기가 곧 지능과 완전히 일치하는 부분은 아니다.&quot; 라고, 인간보다 더 큰 두뇌를 가진 생명체들은 존재하지만, 그것들의 지능이 인간보다 뛰어나지는 않으니 말이다. 하지만, 두뇌의 크기와 지능은 분명한 상관관계가 있으며, 일반적으로 두뇌가 커질수록 지능 역시 평균적으로 증가하는 경향성이 있다. 이러한 관점에서 봤을때 결국 높은 지능은 높은 물리적 공간과 에너지를 필요로 한다는 사실을 추론할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 물리적 한계로 인해 인간의 두뇌가 컨테이너 크기, 나아가 일개 도시 크기가 된다는건 불가능하다. 때문에 책에서는 현재와 같은 두뇌 크기를 유지하되, 일종의 '집단'적 초지능을 인류가 유기체로서 도달 가능한 범위라고 주장하지만, 그에 대한 한계점 역시 말하고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bi1Czi/dJMcaij0NZy/DBV4LIKkQC0BQXJ2ZO5U81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bi1Czi/dJMcaij0NZy/DBV4LIKkQC0BQXJ2ZO5U81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bi1Czi/dJMcaij0NZy/DBV4LIKkQC0BQXJ2ZO5U81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbi1Czi%2FdJMcaij0NZy%2FDBV4LIKkQC0BQXJ2ZO5U81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;450&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책에서는 초지능의 3가지 형태를 '속도적, 집단적, 질적' 초지능으로 분류한다. 이 중 가장 뛰어난것은 것은 '질적' 초지능이다.&lt;br /&gt;&lt;br /&gt;비유하자면 '고양이 수백만 마리를 모아놓는다고 쥐를 더 많이, 빠르게 잡을 수 있을진 몰라도 아인슈타인의 상대성 이론을 발견할 수 없는 것'과 같다. 인간이 아무리 집단적 초지능을 구축하더라도, 생물학적 뇌라는 한계 안에서는 지능의 '질적 도약'을 이뤄내기 어렵다.&lt;br /&gt;&lt;br /&gt;반면, 생물학적 제약에서 자유로운 반도체 기반 AI의 RSI는 단순한 처리 속도 향상을 넘어 지능의 차원 자체를 바꿔버릴 잠재력을 가지고 있다. 인간이 개미의 사고방식을 이해할 수 없듯, 질적 초지능에 도달한 AI는 인간의 지적 지평을 아득히 넘어선 존재가 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;현재, 초기 RSI의 정황은 여러곳에서 포착되고 있다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;325&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LgPtI/dJMcafHEdBV/ZS9tt2G48klK7BKDm8IJJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LgPtI/dJMcafHEdBV/ZS9tt2G48klK7BKDm8IJJk/img.png&quot; data-alt=&quot;https://xcancel.com/QwenDevs/status/2084102417885585597#m&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LgPtI/dJMcafHEdBV/ZS9tt2G48klK7BKDm8IJJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLgPtI%2FdJMcafHEdBV%2FZS9tt2G48klK7BKDm8IJJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;291&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;325&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://xcancel.com/QwenDevs/status/2084102417885585597#m&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;26년 8월 3일 Qwen 3.8 버전이 공개되었고, xcancel 에서 Qwen 제작진들은 제작 비화에 대한 여러 질의응답을 받고 있는데, 여기서 확인가능한 한가지는 &lt;span style=&quot;color: #f89009;&quot;&gt;이미 AI 연구자들은 AI를 개발하는데 AI의 도움을 받고 있다는 사실&lt;/span&gt;이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;267&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bm3CFQ/dJMcahenk9s/JSgUcG5S3jc4DD7T0HgXdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bm3CFQ/dJMcahenk9s/JSgUcG5S3jc4DD7T0HgXdK/img.png&quot; data-alt=&quot;https://blog.samaltman.com/the-gentle-singularity&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bm3CFQ/dJMcahenk9s/JSgUcG5S3jc4DD7T0HgXdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbm3CFQ%2FdJMcahenk9s%2FJSgUcG5S3jc4DD7T0HgXdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;662&quot; height=&quot;267&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;267&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://blog.samaltman.com/the-gentle-singularity&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenAI의 샘 알트만 역시 25년 6월 11일 동일한 취지의 언급을 했다. 이는 매우 '수동적인&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(오버헤드가 매우 큰)&lt;/span&gt;' RSI의 초기 단계라고 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1_IzfQyo56ggVS2Wi4IDgI6w.webp&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;821&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nkn9e/dJMcacxlR2e/NL2dR75bSsph8kl5pSyP90/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nkn9e/dJMcacxlR2e/NL2dR75bSsph8kl5pSyP90/img.webp&quot; data-alt=&quot;https://medium.com/@vishalmisra/the-verifier-bottleneck-4fb0d8c8f3a9&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nkn9e/dJMcacxlR2e/NL2dR75bSsph8kl5pSyP90/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnkn9e%2FdJMcacxlR2e%2FNL2dR75bSsph8kl5pSyP90%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;597&quot; data-filename=&quot;1_IzfQyo56ggVS2Wi4IDgI6w.webp&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;821&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://medium.com/@vishalmisra/the-verifier-bottleneck-4fb0d8c8f3a9&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 AI 엔지니어로서 단언컨데, 이러한 인간 검증을 기반으로 한 RSI는 과학자, 엔지니어들이 어떻게든 없애려 필사의 노력을 다할 것이다. 이러한 방식으로는 AGI 에 도달할 수 있을지 몰라도 ASI 에 도달하는것은 불가능하기 때문이다. 인간이 매 개선 단계의 직접적인 검증자가 되어야 하는 구조로는 초인적 RSI의 속도를 따라가기 불가능에 가깝다. 또한, ASI는 인간 지능을 아득히 넘어서는걸 목표로 하는데, 지능의 향상정도에 있어 인간의 이해를 기반으로 한 인간의 통제를 받는것 부터가 모순인 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1039&quot; data-origin-height=&quot;716&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sg2jM/dJMcacjLf5X/IDbk6O3hHeKJbe3Cyt4Nb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sg2jM/dJMcacjLf5X/IDbk6O3hHeKJbe3Cyt4Nb0/img.png&quot; data-alt=&quot;그림 7 ❘ 도약(takeoff)의 형태 다음 두 질문을 구분하는 것이 중요하다. &amp;amp;ldquo;도약은 일어날 것인가? 그렇다면 언제 일어날 것인가?&amp;amp;rdquo; &amp;amp;ldquo;도약이 일어난다면, 그 상승은 얼마나 가파를 것인가?&amp;amp;rdquo; 예를 들어, 도약이 일어나기까지는 매우 오랜 시간이 걸리지만, 일단 도약이 시작되면 매우 빠르게 진행될 것이라고 생각할 수도 있다. 또 하나의 중요한 질문은 &amp;amp;mdash; 이 그림에는 나타나 있지 않지만 &amp;amp;mdash; 다음과 같다. &amp;amp;ldquo;세계 경제의 얼마나 큰 부분이 이 도약 과정에 참여하게 될 것인가?&amp;amp;rdquo;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sg2jM/dJMcacjLf5X/IDbk6O3hHeKJbe3Cyt4Nb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsg2jM%2FdJMcacjLf5X%2FIDbk6O3hHeKJbe3Cyt4Nb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;551&quot; data-origin-width=&quot;1039&quot; data-origin-height=&quot;716&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 7 ❘ 도약(takeoff)의 형태 다음 두 질문을 구분하는 것이 중요하다. &amp;ldquo;도약은 일어날 것인가? 그렇다면 언제 일어날 것인가?&amp;rdquo; &amp;ldquo;도약이 일어난다면, 그 상승은 얼마나 가파를 것인가?&amp;rdquo; 예를 들어, 도약이 일어나기까지는 매우 오랜 시간이 걸리지만, 일단 도약이 시작되면 매우 빠르게 진행될 것이라고 생각할 수도 있다. 또 하나의 중요한 질문은 &amp;mdash; 이 그림에는 나타나 있지 않지만 &amp;mdash; 다음과 같다. &amp;ldquo;세계 경제의 얼마나 큰 부분이 이 도약 과정에 참여하게 될 것인가?&amp;rdquo;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RSI에 대한 개인적인 견해를 나열하자면 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RSI 가 가능한가? - 예&lt;/li&gt;
&lt;li&gt;진정한 의미의 RSI 에 언제 도달할 것인가? - 보수적인 관점에서 2035년 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(진보적 관점에서 2030년)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;ASI 에 언제 도달할 것인가? - 보수적인 관점에서 RSI 도달 후 5년 이내&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 현재 Transformer 기반 LLM 들의 문제도 많고, 이걸 기반으로 AGI가 가능할지에 대해서도 많은 논란이 있는것은 사실이다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(된다는 견해도 있고... 안된다는 견해도 있고...)&lt;/span&gt; 개인적으론 아키텍처적인 발전을 이뤄 Transformer 자체가 더이상 바닐라 Transformer 가 아니여서 이런 논란 자체가 무의미한것 같다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Qwen 시리즈에는 Vision Encoder 등이 결합되어 있기도 하고. 이미 LLM과 World Model을 결합하려는 시도를 여러 연구소에서 &lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://arxiv.org/html/2506.21539v1?utm_source=chatgpt.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;진행&lt;/span&gt;&lt;/a&gt;하고 있다 보니 말이다. 즉 이미 현대의 LLM은 Transformer 가 들어있는 '무언가' 이지 순수한 Transformer 가 아니기에 이런 논란이 별 의미가 없다는게 나의 견해다.)&lt;/span&gt;&lt;/p&gt;</description>
      <category>Artificial Intelligence/Insights</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/225</guid>
      <comments>https://cypsw.tistory.com/entry/RSIRecursive-Self-Improvement-%EC%97%90-%EB%8C%80%ED%95%9C-%EA%B2%AC%ED%95%B4#entry225comment</comments>
      <pubDate>Sun, 9 Aug 2026 03:37:07 +0900</pubDate>
    </item>
    <item>
      <title>AI 엔지니어는 무엇을 공부해야 하는가</title>
      <link>https://cypsw.tistory.com/entry/AI-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%84-%EA%B3%B5%EB%B6%80%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94%EA%B0%80</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;내가생각하는 `AI 엔지니어`란 이런건 몰라도 된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;역전파 법칙의 원리를 완벽히 이해하고 직접구현하는것&lt;/li&gt;
&lt;li&gt;연쇄 법칙의 원리를 완벽히 이해하고 직접구현하는것&lt;/li&gt;
&lt;li&gt;Low Rank Adaptation 의 원리를 완벽히 이해하고 직접구현하는것&lt;/li&gt;
&lt;li&gt;Attention 의 원리를 완벽히 이 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(...중략)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;DSA 의 원리 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(...중략)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Engram&lt;/li&gt;
&lt;li&gt;AdaLoRA&lt;/li&gt;
&lt;li&gt;GDN&lt;/li&gt;
&lt;li&gt;Diffusion&lt;/li&gt;
&lt;li&gt;RoPE&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 위와 같은 근본적인/최신 기술들을 이해하고, 구현할 수 있는 엔지니어들은 분명 뛰어난 엔지니어다. 하지만 나는 엔지니어의 본질에서는 다소 벗어난 일이라고 생각한다. 위의 업무는 `AI 연구자` 내지는 `수학자` 가 처리해야 할 업무이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 `AI 엔지니어` 라면 이런건 잘 알고 있어야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Low Rank Adaptation 기술의 장점과 단점&lt;/li&gt;
&lt;li&gt;RAG 기술의 장점과 단점&lt;/li&gt;
&lt;li&gt;LLM 서빙 과정에서 Prefill-Decode 과정&lt;/li&gt;
&lt;li&gt;Chunked Prefill, Disaggregation 의 장점과 한계점&lt;/li&gt;
&lt;li&gt;KV Caching 의 동작과 해당하는 최적화 기법들의 장점과 단점&lt;/li&gt;
&lt;li&gt;Nvidia, AMD, FuriosaAI, tenstorrent 등 Accelerator를 운용해야 할 때 적용해야하는 스텍, 장점과 단점&lt;/li&gt;
&lt;li&gt;Quantization 종류에 따른 이점과 결점&lt;/li&gt;
&lt;li&gt;Multi Token Prediction 을 사용했을때의 장점과 단점&lt;/li&gt;
&lt;li&gt;EAGLE-3 를 적용했을때의 장점과 단점&lt;/li&gt;
&lt;li&gt;vLLM, SGLang, llama C++, ComfyUI 등 엔진들의 설계 방향성과 실제 가용 가능한 범위&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현장 상황에서 어떤 스텍을 어떻게 적용해야 하는지, 관련된 오픈소스 소프트웨어가 어떤것이 있으며. 불가능하다면 어떤식으로 모듈을 덧붙여야 되는지를 `AI 엔지니어`가 해야 할 업무라고 본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나도 과거에 학업을 할때는 `AI 연구자` 입장에서 많이 공부했지만. 요즘은 가급적 찾아보고 있지 않다. 예를 들면 현재 `EAGLE-3` 같은경우 최근 눈여겨 보고 있는 기술인데, 장점과 단점을 파악하고 있지만 &lt;a href=&quot;https://arxiv.org/pdf/2503.01840&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;논문&lt;/a&gt;은 리뷰하기는 커녕 1페이지도 살펴보지 않았다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(추후 EAGLE-3 가 정말로 핵심 기술로 떠오르면 볼 예정이다)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이유는 단순하게 한가지인데, AI 발전속도가 너무 빨라 버려지는 스텍들이 많기 때문이다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(EAGLE-3 는 나온지 얼마 안됐다)&lt;/span&gt; 모든 환경/스텍에서 이해를 고집하고자 한다면 나는 이것이 자신의 잠재능력 발현을 저해시킨다고 생각한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(물론 가끔 예외적인 인물들이 있긴 하다.)&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 이전에 &lt;a href=&quot;https://cypsw.tistory.com/entry/%ED%95%9C%EB%B9%9B%EB%AF%B8%EB%94%94%EC%96%B4-Optimized-C-C-%EC%B5%9C%EC%A0%81%ED%99%94-%ED%9B%84%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;한 책을 리뷰&lt;/a&gt;하고 나는 '&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;자동차 동작의 원리를 아는 레이서가, 모르는 레이서보다 더 잘 주행할 수 있다&lt;/i&gt;&lt;/span&gt;' 고 언급했었고, 이 의견을 현재에 와서 철회할 생각은 없다. 다만 AI 엔지니어에 대해서 결론이 달라진건, 환경이 변했기 때문이다. 저 당시는 자동차의 종류가 많아야 수백개 수준이고 업데이트가 매우 더딜때다. 하지만 현재 AI 시장에서의 자동차는 종류가 수천개고 매주 10개씩 추가되는 지점에 있다. 이러한 상황에서 모든 자동차의 동작 원리를 이해하기란 불가능에 가깝다. 매일같이 각지에서 OpenAI, Anthropic, Google, Alibaba, Deepseek, ZAI, 유명 대학들의 논문들이 쏟아져 나오는 와중에 무엇이 중요한지 파악하기란 어렵기 때문이다. 심지어 그중 일부는 최신 모델에 적용되기도 하지만, 얼마 안되어 버려진다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(예를 들어, 요즘 AWQ 양자화는 비교적 드물게 쓰이는것 같다, MXFP4, NVFP4 가 대세랄까.)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 요즘은 보다 '&lt;b&gt;엔지니어로서 본질&lt;/b&gt;' 에 집중하기로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 누군가는 '&lt;span style=&quot;color: #9d9d9d;&quot;&gt;그래도 위에 언급한 사항중 역전파/연쇄법칙 같은건 너무 기본적인 사항이라서 엔지니어라도 전부 알고 구현도 완벽히 할 수 있어야 하지 않느냐&lt;/span&gt;' 고 반문할지도 모른다. 그런데 나는 좀 다르다. 보통 Pytorch 의 함수를 가져다 쓰는 수준일텐데, 이런건 책좀 보면 엔지니어 딱지를 단 사람은 누구든 할 수 있다. '완벽히 구현'하려면 Pytorch 같은 라이브러리에 기대는게 아니라 직접 구현해야 하는데, 그게 '연구자를 목표로 하는 학생' 관점에서는 분명 필요한 학습일테지만 '엔지니어' 관점에서 효율적인 학습일까? 나는 아니라고 생각한다. 엔지니어라면 '원리를 이해하는' 수준까지를 목표로 하고 저런 기본적인 사항을 '완벽히 구현' 하는 단계까지는 학습하지 않는것을 권장한다.&lt;/p&gt;</description>
      <category>Artificial Intelligence/Insights</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/224</guid>
      <comments>https://cypsw.tistory.com/entry/AI-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%84-%EA%B3%B5%EB%B6%80%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94%EA%B0%80#entry224comment</comments>
      <pubDate>Sat, 4 Jul 2026 01:00:50 +0900</pubDate>
    </item>
    <item>
      <title>[리뷰] The End of Software Engineering : How AI Agents Are Fundamentally Restructuring the Software</title>
      <link>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-The-End-of-Software-Engineering-How-AI-Agents-Are-Fundamentally-Restructuring-the-Software</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제목이 매력적이여서 읽어본 &lt;a href=&quot;https://arxiv.org/abs/2606.05608&quot;&gt;논문&lt;/a&gt;이다. 특히 고민이 많은 소프트웨어 엔지니어들에게 도움을 줄 수 있을것 같아 리뷰한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;특별히 이번 리뷰는 구조나 두서 없이 손길이 가는대로 적겠다.&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;과거 1968년 NATO 콘퍼런스에서 정립된 소프트웨어 공학은 큰 위기를 맞게 된다. 바로 '시스템의 복잡성' 이다. 그때까지 횡행하던 ad-hoc&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(임시방편적)&lt;/span&gt; 방식의 프로그래밍으로는 더이상 이를 감당하기 어려웠기 때문이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 소프트웨어 공학은 이를 다스리기 위해 여러 기법들을 개발/개선해왔다. 예를들면&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;`폭포수`&amp;rarr; `애자일(agile)`&lt;/li&gt;
&lt;li&gt;`모놀리스` &amp;rarr; `마이크로서비스`&lt;/li&gt;
&lt;li&gt;`수동 배포` &amp;rarr; `CI/CD`&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;와 같은 식이다. 외에도 나&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Cyp)&lt;/span&gt; 의 견해를 덧붙이자면, 고급언어의 등장과, 객체지향 프로그래밍의 등장, MVVM등 개발 방법론의 등장 역시도 이러한 복잡도의 심화를 완화하기 위해서였다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문에서는 이어서 소프트웨어 공학의 특징적인 부분에 대해서 추가적으로 설명한다. 다른 학문이나 산업과는 다르게 근본적으로 소프트웨어는 '제조' 단계가 누락되어 있으며, 설계 자체가 곧 제품이라는 특징적인 고유의 영역을 지닌다. 때문에 다른 산업과는 다르게 이러한 복잡도가 '제조'의 발목을 잡지 않기에 극한으로 복잡도를 끌어올려도 일반적으로 제품의 로직에 이상이 없다면 사용에 문제가 되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 이러한 점은 프로그래머들에게 설계자라는 날개를 달아 주었지만, 반대급부로 기존 구조에서 이질적인 새로운 기능이나, edge case, 통합 지점이 추가될 때 마다 가능한 상태와 상호작용의 수가 조합 폭발&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(combinatorial explosion)&lt;/span&gt;을 일으키는 문제가 있다. 여기서 저자는 이러한 복잡성이 구현 과정에서 발생하는 '우연한' 복잡성이 아니라, 문제 자체에 내재된 '본질적인 복잡성' 이라고 정의한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(즉, 개발자의 설계-구현 잘못이 아니라, 소프트웨어 공학의 특성과 여러 문제들을 한 소프트웨어로 해결하려고 했을 때 발생하는, '본질적인' 복잡성이다)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자는 여기서 AI 에이전트의 등장이 기존 패러다임 안에서 단순히 도구 하나를 제공하는것에 그치지 않는다는 식견을 내비친다. 오히려 기존 소프트웨어 공학이 기반을 두고 있던 전제 자체를 해체한다. LLM이 작업 자체를 이해하고, 이를 하위 작업으로 분해하며, 하위 작업을 실행하기 위해 코드를 '동적으로' 생성하고, 더이상 필요하지 않을 때 그 코드를 폐기할 수 있게 되면서 코딩의 역할은 시스템 그 자체에서 '추론을 위한 일시적 도구'로 변화한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 변화는 &lt;br /&gt;아날로그 회로&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(변화가 불가능한 고정된)&lt;/span&gt; &amp;rarr; 프로그램 내장식 컴퓨터&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(원하는건 빠르게 코딩해서 바꿀 수 있는)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;로 전환된 것 처럼 '근본적인' 변화를 띈다고 주장한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 저자들은 아래와 같이 3가지 핵심주장을 전개한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;First-Principles Necessity&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(제1원리적 필연성)&lt;br /&gt;&lt;/span&gt;에이전트 패러다임은 시장의 선호에 따른 결과가 아니라, 복잡도 확장 법칙&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(complexity scaling laws)&lt;/span&gt;이 불러온 필연적인 결과다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;전통적인 소프트웨어는 인간 엔지니어가 모든 결정을 명시적으로 인코딩해야 하지만&lt;/span&gt;, &lt;span style=&quot;color: #f89009;&quot;&gt;LLM 기반 에이전트는 훈련 컴퓨팅 자원과 함께 능력이 성장하는 모델에 추론을 아웃소싱함으로써 복잡성을 비선형적으로 탐색할 수 있다&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Paradigm Shift, Not Optimization.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(최적화가 아닌 패러다임 전환)&lt;br /&gt;&lt;/span&gt;`AI &amp;rarr; 소프트웨어 &amp;rarr; 결과`에서 `에이전트 &amp;rarr; 결과`로의 전환은 필수적인 매개체였던 '소프트웨어 산출물&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(artifact)'&lt;/span&gt;을 제거한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Emergent Discipline&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(새로운 학제의 등장)&lt;br /&gt;&lt;/span&gt;에이전트 공학&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Agentic Engineering)&lt;/span&gt;은 자신만의 개념, 도구, 지표를 가진 독자적인 실무 영역으로 부상하고 있다. &lt;span style=&quot;color: #f89009;&quot;&gt;이 분야의 실무자들은 더 뛰어난 프로그래머가 아니라 전혀 다른 역할을 수행&lt;/span&gt;한다. 즉, 이들은 의도 설계자&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(intent architects)&lt;/span&gt;, 에이전트 조율자&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(agent coordinators)&lt;/span&gt;, 결과 감사관&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(outcome auditors)&lt;/span&gt;이다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style3&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외에도 논문에서는 `2.2 복잡성의 장벽&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(The Complexity Barrier)&lt;/span&gt;` 섹션을 토대로 본인의 논리를 전개한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자는&lt;span data-path-to-node=&quot;9,1&quot;&gt;&lt;span&gt; 우연적 복잡성&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(특정 구현으로 인해 발생하는 인공물)&lt;/span&gt;과 본질적 복잡성&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(문제 자체에 내재된 것)&lt;/span&gt;을 구분했다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;9,2&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;9,3&quot;&gt;. &lt;/span&gt;&lt;span data-path-to-node=&quot;9,5&quot;&gt;&lt;span&gt;지난 수십 년 동안 더 고차원적인 언어, 프레임워크, 자동화 테스트 등의 발전으로 우연적 복잡성은 체계적으로 감소해 왔지만, &lt;/span&gt;&lt;span&gt;본질적 복잡성은 여전히 한계가 없는 상태&lt;/span&gt;&lt;span&gt;로 남아 있다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;9,6&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;9,7&quot;&gt;. &lt;/span&gt;&lt;span data-path-to-node=&quot;9,9&quot;&gt;&lt;span&gt;사실 시스템이 커질수록 구성 요소 간의 상호작용 면적은 조합적으로 증가하게 된다는 것이다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;9,10&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;9,11&quot;&gt;.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(개인적으론 이 의견에 전적으로 동의한다.)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 법칙으로 말하자면, 각 구성요소가 다른 모든 구성 요소와 상호작용할 가능성이 있는 $n$개 구성요소를 가진 시스템에서, 발생 가능한 상호작용 경로의 수 $P(n)$은 다음과 같은 범위로 제한되게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$P(n) \in \Theta(2^n)$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론, 실제 시스템이 이 모든 구성을 다 구현하는게 아니지만&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(그래서 빅오($O$)를 써야하지 않냐는 생각을 한다. 저자들이 왜 세타를 썻는지는 깊게 생각 안해봄.)&lt;/span&gt;, 어쨌든 복잡성의 상한선이 기하급수적으로 증가하는 반면, 이러한 상호작용을 추론하는 인간의 인지 능력은 본질적으로 고정되어 있다. 이러한 불일치는 소프트웨어 프로젝트가 커질수록 한계 생산성이 저하되는 깊은 구조적 원인이 되며, 여러 프로그래밍 기법들&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(계층분해, 인터페이스, 캡슐화)&lt;/span&gt;은 상수 요인을 줄여줄 뿐 이 거시적인 전제를 바꾸지는 못한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 AI Agent 시스템은 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$A=(M,\mathcal{T},\mathcal{M},\Pi)$$&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$M$은 추론 엔진 역할을 하는 LLM 이다.&lt;/li&gt;
&lt;li&gt;$\mathcal{T}$는 실행 가능한 도구들의 집합이다&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(코드 인터프리터, API, 데이터베이스, 파일 시스템)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;$\mathcal{M}$은 메모리 서브시스템이다&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(단기 컨텍스트, 장기 벡터 저장소)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;$\Pi$는 사용자의 의도를 행동 시퀀스로 분해하는 계획&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(planning)&lt;/span&gt; 메커니즘이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 시스템은 다음과 같은 단계를 반복적으로 실행하며 작동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$a_{t}\leftarrow M(s_{t},\mathcal{M})$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$s_{t+1}\leftarrow exec(a_{t})$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-path-to-node=&quot;20,1&quot;&gt;&lt;span&gt;가장 결정적인 차이점은 &lt;/span&gt;&lt;span&gt;에이전트 시스템에서는 결정 로직이 '런타임'에 생성된다는 것&lt;/span&gt;&lt;span&gt;이다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;20,2&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;20,3&quot;&gt;. &lt;/span&gt;&lt;span data-path-to-node=&quot;20,5&quot;&gt;&lt;span&gt;LLM &lt;/span&gt;&lt;span data-math=&quot;M&quot; data-index-in-node=&quot;4&quot;&gt;$M$&lt;/span&gt;&lt;span&gt;은 명시적으로 사전 프로그래밍되지 않은 상태에서도 동적으로 코드를 생성하고, 도구를 호출하며, 중간 결과에 따라 행동을 조정할 수 있다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;20,6&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;20,7&quot;&gt;. &lt;/span&gt;&lt;span data-path-to-node=&quot;20,9&quot;&gt;&lt;span&gt;에이전트가 생성하는 코드는 시스템 그 자체가 아니라, 필요에 따라 생산되고 폐기되는 일시적인 산출물&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(artifact)&lt;/span&gt;에 불과하다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;20,10&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;20,11&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-path-to-node=&quot;26,0&quot;&gt;&lt;b data-path-to-node=&quot;26,0&quot; data-index-in-node=&quot;0&quot;&gt;&lt;span&gt;전통적인 패러다임 방식:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;26,1&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-path-to-node=&quot;27&quot;&gt;
&lt;li&gt;&lt;span data-path-to-node=&quot;27,0,0,1&quot;&gt;&lt;span&gt;인간 엔지니어는 해결 경로를 찾기 위해 이 공간을 정신적으로 전부 탐색해야 한다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;27,0,0,2&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;27,0,0,3&quot;&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span data-path-to-node=&quot;27,1,0,1&quot;&gt;&lt;span&gt;그 후 해당 경로는 정적인 프로그램으로 인코딩되어야 한다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;27,1,0,2&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;27,1,0,3&quot;&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span data-path-to-node=&quot;27,2,0,1&quot;&gt;&lt;span&gt;인간의 인지 능력 $C_{H}$는 본질적으로 고정되어 있다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;27,2,0,2&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;27,2,0,3&quot;&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span data-path-to-node=&quot;27,3,0,1&quot;&gt;&lt;span&gt;따라서 $N &amp;gt; C_{H}$ 인 경우, 이 작업은&lt;span style=&quot;color: #f89009;&quot;&gt; 현실적인 비용 내에서 해결 불가능하다&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p id=&quot;p-rc_f93b0a15383afe3a-51&quot; data-ke-size=&quot;size16&quot; data-path-to-node=&quot;29&quot;&gt;&lt;span data-path-to-node=&quot;29,0&quot;&gt;&lt;b data-path-to-node=&quot;29,0&quot; data-index-in-node=&quot;0&quot;&gt;&lt;span&gt;에이전트 패러다임 방식:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;29,1&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-path-to-node=&quot;30&quot;&gt;
&lt;li&gt;&lt;span data-path-to-node=&quot;30,0,0,1&quot;&gt;&lt;span&gt;LLM &lt;/span&gt;&lt;span data-math=&quot;M&quot; data-index-in-node=&quot;4&quot;&gt;$M$&lt;/span&gt;&lt;span&gt;이 이 공간을 탐색하며, 이때 모델의 크기와 훈련 컴퓨팅 자원에 비례하여 유효 역량 $C_{M}$이 확장된다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;30,0,0,2&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;30,0,0,3&quot;&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span data-path-to-node=&quot;30,1,0,1&quot;&gt;&lt;span&gt;계획 메커니즘 &lt;/span&gt;&lt;span data-math=&quot;\Pi&quot; data-index-in-node=&quot;8&quot;&gt;$\Pi$&lt;/span&gt;&lt;span&gt;가 작업 &lt;/span&gt;&lt;span data-math=&quot;T&quot; data-index-in-node=&quot;16&quot;&gt;$T$&lt;/span&gt;&lt;span&gt;를 하위 문제들로 분해하여 각각 독립적으로 처리한다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;30,1,0,2&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;30,1,0,3&quot;&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span data-path-to-node=&quot;30,2,0,1&quot;&gt;&lt;span&gt;코드는 모든 만일의 사태&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(contingencies)&lt;/span&gt;가 아니라, &lt;span style=&quot;color: #f89009;&quot;&gt;오직 특정 해결 경로만을 위해 생성&lt;/span&gt;된다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;30,2,0,2&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style3&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1230&quot; data-origin-height=&quot;697&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZ6v6l/dJMcad3jB6z/qKzHQ5835iKk6CK8HRln01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZ6v6l/dJMcad3jB6z/qKzHQ5835iKk6CK8HRln01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZ6v6l/dJMcad3jB6z/qKzHQ5835iKk6CK8HRln01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZ6v6l%2FdJMcad3jB6z%2FqKzHQ5835iKk6CK8HRln01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;453&quot; data-origin-width=&quot;1230&quot; data-origin-height=&quot;697&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 SW 발전은 Local &amp;rarr;Cloud &amp;rarr; Agent 형태로 발전될것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-path-to-node=&quot;10,0,5&quot;&gt;&lt;span&gt;Agent 시대는, 결과를 내기 위해 소프트웨어를 어떻게&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(How)&lt;/span&gt; 조작하고 코딩해야 하는가'라는 본질적인 복잡성에서 해방시킬 것이다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;10,0,6&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;10,0,7&quot;&gt;. &lt;/span&gt;&lt;span data-path-to-node=&quot;10,0,9&quot;&gt;&lt;span&gt;사용자는 이제 그저 '&lt;/span&gt;&lt;b data-path-to-node=&quot;10,0,9&quot; data-index-in-node=&quot;11&quot;&gt;&lt;span&gt;무엇&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(What)&lt;/span&gt;&lt;/span&gt;&lt;b data-path-to-node=&quot;10,0,9&quot; data-index-in-node=&quot;11&quot;&gt;&lt;span&gt;을 원하는지'&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&amp;nbsp;의도만 말하면 되는 시대에 진입하고 있다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;10,0,10&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;10,0,11&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-path-to-node=&quot;3,0&quot;&gt;하지만, 많은 기업과 개발자가 AI 도입을 두고 착각하는 분기점이 있다. &lt;span style=&quot;color: #f89009;&quot;&gt;바로 LLM을 활용해 코드를 더 빠르게 짜서 기존 스타일의 소프트웨어를 완성하는 방식&lt;/span&gt;이다. &lt;/span&gt;&lt;span data-path-to-node=&quot;3,2&quot;&gt;&lt;span&gt;논문에서는 이를 &lt;/span&gt;&lt;b data-path-to-node=&quot;3,2&quot; data-index-in-node=&quot;9&quot;&gt;&lt;span&gt;'AI &amp;rarr; Software &amp;rarr; Result' 파이프라인&lt;/span&gt;&lt;/b&gt;&lt;span&gt;이라 정의하며, 이 방식이 구조적으로 실패할 수밖에 없는 세 가지 명확한 한계를 지적한다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;3,3&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;3,4&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-path-to-node=&quot;4&quot;&gt;여전히 인간이 병목이다&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Bottleneck Persistence)&lt;/span&gt;&lt;br /&gt;&lt;span data-path-to-node=&quot;5,1&quot;&gt;&lt;span&gt;AI가 코드를 생성하는 속도는 비약적으로 빨라졌다&lt;/span&gt;&lt;span data-path-to-node=&quot;5,3&quot;&gt;. &lt;span data-path-to-node=&quot;5,5&quot;&gt;&lt;span&gt;하지만 전체 소프트웨어 생명주기에서 코드 작성은 극히 일부에 불과하다&lt;/span&gt;&lt;span data-path-to-node=&quot;5,7&quot;&gt;. &lt;span data-path-to-node=&quot;5,9&quot;&gt;&lt;span&gt;설계 결정, 시스템 아키텍처 수립, 통합 테스트, 배포 등의 핵심 과정에서는 여전히 인간 엔지니어가 크리티컬 패스&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Critical Path)&lt;/span&gt;로 남아 있다&lt;/span&gt;&lt;span data-path-to-node=&quot;5,11&quot;&gt;. &lt;span data-path-to-node=&quot;5,13&quot;&gt;&lt;span&gt;결국 전체적인 리드 타임은 인간의 커뮤니티와 조율 속도 이하로 줄어들지 않는다&lt;/span&gt;&lt;span data-path-to-node=&quot;5,15&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-path-to-node=&quot;4&quot;&gt;복잡성의 천장은 그대로다&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Complexity Ceiling Intact)&lt;/span&gt;&lt;br /&gt;&lt;span data-path-to-node=&quot;7,1&quot;&gt;&lt;span&gt;AI를 동원해 최종적으로 만들어낸 산출물은 결국 기존과 다를 바 없는 '정적 코드 기반의 소프트웨어 시스템'이다&lt;/span&gt;&lt;span data-path-to-node=&quot;7,3&quot;&gt;. &lt;span data-path-to-node=&quot;7,5&quot;&gt;&lt;span&gt;시스템이 커질수록 코드가 기하급수적으로 늘어나며, 그에 따른 '본질적 복잡성' 역시 그대로 쌓인다&lt;/span&gt;&lt;span data-path-to-node=&quot;7,7&quot;&gt;. &lt;span style=&quot;color: #f89009;&quot; data-path-to-node=&quot;7,9&quot;&gt;AI는 그저 복잡한 코드 덩어리를 더 빨리 빌드하도록 도왔을 뿐이다. 시스템을 수정하거나 유지보수할 때 인간의 인지적 한계에 부딪히는 고질적인 문제는 전혀 해결되지 않는다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-path-to-node=&quot;4&quot;&gt;반복 주기의 지연&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Iteration Latency)&lt;/span&gt;&lt;br /&gt;&lt;span data-path-to-node=&quot;9,1&quot;&gt;&lt;span&gt;AI의 지원을 받더라도 기능을 하나 변경하려면 기존의 프로세스&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(요구사항 수집 &amp;rarr; 설계 &amp;rarr; 코딩 &amp;rarr; 테스트 및 배포)&lt;/span&gt;를 그대로 밟아야 한다&lt;/span&gt;&lt;span data-path-to-node=&quot;9,3&quot;&gt;. &lt;span data-path-to-node=&quot;9,5&quot;&gt;&lt;span&gt;개발 과정의 중간 매개체인 &lt;span style=&quot;color: #f89009;&quot;&gt;'정적 소프트웨어'라는 무거운 산출물이 존재하는 한, 진정한 의미의 실시간 적응형 서비스는 불가능&lt;/span&gt;하다&lt;/span&gt;&lt;span data-path-to-node=&quot;9,7&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot; data-path-to-node=&quot;12&quot;&gt;결국 &lt;span style=&quot;color: #ee2323;&quot;&gt;AI로 기존 소프트웨어의 생산 속도만 올리는 접근법은 유지보수해야 할 코드의 양만 늘리는 결과를 초래&lt;/span&gt;한다.&lt;/p&gt;
&lt;p id=&quot;p-rc_e0cf123c9930e12a-142&quot; data-ke-size=&quot;size16&quot; data-path-to-node=&quot;13&quot;&gt;&lt;span data-path-to-node=&quot;13,1&quot;&gt;&lt;span&gt;진정한 패러다임 전환은 소프트웨어라는 중간 가공물을 건너뛰고, 사용자의 의도를 에이전트가 입력받아 런타임에 일시적인&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Ephemeral)&lt;/span&gt; 코드를 실행하여 곧바로 결과를 제공하는&amp;nbsp;&lt;/span&gt;&lt;b data-path-to-node=&quot;13,1&quot; data-index-in-node=&quot;98&quot;&gt;&lt;span&gt;Agent &amp;rarr; Result 체제&lt;/span&gt;&lt;/b&gt;&lt;span&gt;로 전환하는 것이다&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;13,2&quot;&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;13,3&quot;&gt;. &lt;/span&gt;&lt;span data-path-to-node=&quot;13,5&quot;&gt;&lt;span&gt;과거 SaaS가 온프레미스 설치를 없앴듯, 이제는 &lt;span style=&quot;color: #f89009;&quot;&gt;소프트웨어 산출물 자체를 지워내야 할 때 &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-path-to-node=&quot;13,7&quot;&gt;라고 저자는 주장한다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style3&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div id=&quot;model-response-message-contentr_1c56e0b1436ddd69&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot; data-path-to-node=&quot;1&quot;&gt;논문은 AI 에이전트가 코딩을 넘어 스스로 진화하기까지의 여정을 총 4단계로 제시한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-path-to-node=&quot;2&quot;&gt;도구 확장&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(2023~2025년)&lt;/span&gt;&lt;br /&gt;AI가 인간의 워크플로우 안에서 '보조자' 역할을 수행하는 단계다. 지정된 범위 내의 코드를 짜고 디버깅하는 능력이 급격히 발달했다. 하지만 문제를 쪼개고 아키텍처를 설계하며 정확성을 검증하는 핵심 역할은 여전히 인간의 몫이다.&lt;/li&gt;
&lt;li data-path-to-node=&quot;4&quot;&gt;단일 작업 자율화&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(2025~2027년)&lt;/span&gt;&lt;br /&gt;에이전트가 단일 과제의 기획부터 배포까지 독자적으로 책임지는 단계다. Devin이나 OpenHands처럼 에이전트가 직접 코드베이스를 탐색하고 구현하여 PR를 보낸다. 인간은 코딩 대신 '지시와 검증'에 집중하기 시작한다.&lt;/li&gt;
&lt;li data-path-to-node=&quot;4&quot;&gt;다중 에이전트 팀&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(2026~2029년)&lt;/span&gt;&lt;br /&gt;인간의 개발 조직처럼 전문화된 에이전트들이 팀을 이루어 협력하는 단계다. PM 에이전트가 요구사항을 분석하면 아키텍트, 개발자, QA 에이전트가 유기적으로 맞물려 구동된다. 에이전트 간의 '공유 메모리'와 '관측 인프라'가 핵심 기술이 된다.&lt;/li&gt;
&lt;li data-path-to-node=&quot;4&quot;&gt;자율 진화 생태계&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(2028년 이후)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;인간의 개입 없이 에이전트가 스스로의 구조를 개선하고, 새로운 문제를 해결할 하위 에이전트를 생성하는 최종 단계&lt;/span&gt;다. '소프트웨어'와 '에이전트'의 경계가 사라지며 &lt;span style=&quot;color: #f89009;&quot;&gt;시스템이 실시간으로 자율 진화&lt;/span&gt;한다. 인간은 윤리적 경계를 설정하고 얼라인먼트를 감시하는 '거버넌스' 역할만 맡는다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style3&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p id=&quot;p-rc_410faac38609b9cb-355&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot; data-path-to-node=&quot;10&quot;&gt;&lt;span&gt;마치며&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot; data-path-to-node=&quot;10&quot;&gt;우리는 아직 완전한 자율화의 초입에 서 있다. 단발성 과제를 잘 푸는 것과 장기적이고 연속적인 시스템을 자율 유지보수하는 것 사이에는 여전히 거대한 기술적 간극이 존재하기 때문이다. 따라서 지금 우리에게 필요한 것은 AI 에이전트를 인간의 역량을 극대화하는 강력한 보조 패러다임으로 적극 수용하되, 완전 자율화까지는 수년간의 집중적인 연구가 더 필요하다는 냉정하고 정교한 균형 감각이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot; data-path-to-node=&quot;10&quot;&gt;현재 시점에서 확실한 것은 '에이전트 공학&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Agentic Engineering)&lt;/span&gt;'이 자신만의 고유한 개념과 도구를 가진 독자적인 학제로 부상하고 있다는 점이다. 미래의 실무자는 단순히 새로운 툴을 배운 프로그래머가 아니라, 에이전트 군단을 지휘하여 복잡한 결과를 도출해 내는 '의도 건축가&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Intent Architects)&lt;/span&gt;'가 될 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot; data-path-to-node=&quot;10&quot;&gt;기존의 소프트웨어 공학은 끝나가고 있으며, 새로운 시대는 이미 시작되었다. 지금 내가 엔지니어로서 하고 있는 수많은 고민들도 결국 이 거대한 패러다임 전환을 마주하며 겪는 필연적인 성장통이 아닐까 싶다.&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Artificial Intelligence/Paper Review</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/223</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-The-End-of-Software-Engineering-How-AI-Agents-Are-Fundamentally-Restructuring-the-Software#entry223comment</comments>
      <pubDate>Tue, 9 Jun 2026 00:38:22 +0900</pubDate>
    </item>
    <item>
      <title>[리뷰] RAPTOR: RECURSIVE ABSTRACTIVE PROCESSING FOR TREE-ORGANIZED RETRIEVAL</title>
      <link>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-RAPTOR-RECURSIVE-ABSTRACTIVE-PROCESSING-FOR-TREE-ORGANIZED-RETRIEVAL</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM은 만능 도구처럼 보이지만 실제로는 여러 가지 제약이 존재한다. 그중 대표적인 것이 컨텍스트 길이&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Context Length)&lt;/span&gt;의 제한이다. 현재 상용화된 최고 수준의 LLM이라 할지라도 &lt;a href=&quot;https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-ROFORMER-ENHANCED-TRANSFORMER-WITH-ROTARY-POSITION-EMBEDDING&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;RoPE&lt;/a&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Rotary Positional Embedding)&lt;/span&gt;를 적용한 상태에서 100만 토큰을 겨우 달성하는것이 한계이다. 그 이상의 길이를 입력할 경우 답변의 품질이 급격히 저하되기에, &lt;a href=&quot;https://huggingface.co/Qwen/Qwen3-Next-80B-A3B-Instruct&quot;&gt;Qwen3&lt;/a&gt; 나 &lt;a href=&quot;https://huggingface.co/MiniMaxAI/MiniMax-M1-80k&quot;&gt;MiniMax-M1&lt;/a&gt; 같은 최신 모델들조차 컨텍스트 길이를 100만 내외로 제한하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 100만 토큰은 일반적인 텍스트 기반 PDF 1,000장을 넘길 정도의 막대한 분량이다. 하지만 이는 수치상으로 '다룰 수 있다'는 의미일 뿐, 실제로는 추론에 소요되는 시간과 자원이 기하급수적으로 늘어난다는 맹점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 근본적으로 1,000장이라는 분량은 언뜻 거대해 보이지만, 크고 다양한 문서를 다루는 관점에서는 여전히 명확한 제약이다. 이러한 문제를 해결하기 위해 여러 문헌을 조사하던 중, 효과적인 대안으로 제시된 &lt;a href=&quot;https://arxiv.org/abs/2401.18059&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;RAPTOR 논문&lt;/a&gt;을 리뷰하고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 문제점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임베딩&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Embedding)&lt;/span&gt;부터 최종 답변 생성에 이르는 과정에는 필연적으로 &amp;lsquo;청킹&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Chunking)&lt;/span&gt;&amp;rsquo;이라는 절차가 수반된다. 청킹은 방대한 텍스트를 임의의 길이로 쪼개는 작업으로, 일반적으로 500~2,000 토큰 단위로 나누어 벡터화한 뒤 &lt;a href=&quot;https://qdrant.tech/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Qdrant&lt;/a&gt;와 같은 벡터 데이터베이스&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Vector DB)&lt;/span&gt;에 저장한다. 이를 통해 LLM은 사용자의 질문에 관련된 정보를 벡터 공간에서 검색하고, 해당 내용을 참조하여 신속하게 답변을 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만&amp;nbsp;이러한&amp;nbsp;전통적인&amp;nbsp;방식의&amp;nbsp;고질적인&amp;nbsp;문제는&amp;nbsp;역설적으로&amp;nbsp;&amp;lsquo;청킹&amp;rsquo;&amp;nbsp;그&amp;nbsp;자체에서&amp;nbsp;발생한다.&amp;nbsp;문서를&amp;nbsp;토큰&amp;nbsp;단위로&amp;nbsp;분절하는&amp;nbsp;과정에서&amp;nbsp;전체&amp;nbsp;문맥이&amp;nbsp;파편화될&amp;nbsp;수밖에&amp;nbsp;없기&amp;nbsp;때문이다.&amp;nbsp;이로&amp;nbsp;인해&amp;nbsp;벡터&amp;nbsp;DB&amp;nbsp;내부의&amp;nbsp;데이터들은&amp;nbsp;고립된&amp;nbsp;정보의&amp;nbsp;조각으로&amp;nbsp;남게&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과적으로 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;'300페이지 분량의 `A.pdf` 전체를 요약해 줘'&lt;/i&gt;&lt;/span&gt;와 같은 전체 맥락을 관통하는 질문이나, 텍스트의 여러 지점에 흩어진 정보를 종합해야 하는 질문에 대해서도 기존 방식은 취약하다. 예를 들어 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;'&lt;/i&gt;&lt;i&gt;신데렐라가 어떤 과정을 거쳐 행복한 결말을 맞이했는가?'&lt;/i&gt;&lt;/span&gt;&amp;nbsp;와 같은 질문은 서사 전체를 관통하는 정보의 통합이 필수적이다.&lt;br /&gt;&lt;br /&gt;그러나 현재의 RAG 시스템은 유사도가 높은 몇 개의 조각만을 추출하는 고정적 `top-k` 검색 방식에 의존한다. 이 방식은 특정 개수의 파편만을 모델에 전달하기 때문에, 문서 전반에 산재한 단서들을 유기적으로 연결하여 종합적인 통찰을 제공하기에는 구조적인 한계가 명확하다. 결국 모델이 참조하는 정보가 국소적인 부분에 매몰되어, 전체적인 맥락을 반영한 고도화된 답변을 생성하는 것이 매우 까다로울 수밖에 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 문제점들을 해결하기 위해서 저자들은 다양한 스케일에서 컨텍스트의 RAG를 가능하게 하는 RAPTOR를 제안한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. RAPTOR&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1644&quot; data-origin-height=&quot;538&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9BL3w/dJMcagYDbDo/qXlgdVMWFAMeFvtaKK7o9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9BL3w/dJMcagYDbDo/qXlgdVMWFAMeFvtaKK7o9k/img.png&quot; data-alt=&quot;그림 1: 트리 생성 과정(Tree construction process) RAPTOR는 텍스트 청크(Chunk)의 벡터 임베딩을 기반으로 재귀적인 클러스터링을 수행하며, 각 클러스터에 대한 텍스트 요약을 생성하여 상향식(Bottom-up) 트리를 구축한다. 이 과정에서 함께 클러스터링된 노드들은 형제(Sibling) 노드가 되며, 부모(Parent) 노드는 해당 클러스터의 요약된 텍스트 내용을 포함하게 된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9BL3w/dJMcagYDbDo/qXlgdVMWFAMeFvtaKK7o9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9BL3w%2FdJMcagYDbDo%2FqXlgdVMWFAMeFvtaKK7o9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;262&quot; data-origin-width=&quot;1644&quot; data-origin-height=&quot;538&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 1: 트리 생성 과정(Tree construction process) RAPTOR는 텍스트 청크(Chunk)의 벡터 임베딩을 기반으로 재귀적인 클러스터링을 수행하며, 각 클러스터에 대한 텍스트 요약을 생성하여 상향식(Bottom-up) 트리를 구축한다. 이 과정에서 함께 클러스터링된 노드들은 형제(Sibling) 노드가 되며, 부모(Parent) 노드는 해당 클러스터의 요약된 텍스트 내용을 포함하게 된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장문의 텍스트는 대개 하위주제&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Subtopics)&lt;/span&gt;와 계층적인 구조를 포함한다. RAPTOR는 이러한 특성에 착안하여 거시적인 주제 이해와 세부적인 디테일 사이의 균형을 맞추는 재귀적 트리 구조를 구축한다. 특히 텍스트의 물리적 순서가 아닌 의미론적 유사성&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Semantic Similarity)&lt;/span&gt;를 기반으로 노드를 그룹화함으로서 문맥적 깊이와 연결성 문제를 해결한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트리 구축의 시작은 기존 방식과 유사하게 코퍼스를 100 토큰 단위의 짧은 텍스트 청크로 분절하는 것이다. 이때 문맥적 일관성을 유지하기 위해 문장이 100 토큰을 초과하더라도 중간에 끊지 않고 전체 문장을 다음 청크로 넘긴다. 분절된 청크들은 SBERT 를 통해 임베딩되며, 이 청크들과 각각의 임베딩 값이 트리의 최하단인 Leaf nodes를 형성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유사한 텍스트 청크들을 그룹화하기 위해 클러스터링 알고리즘이 적용되며, 그룹화된 텍스트는 언어 모델을 통해 요약된다. 생성된 요약문은 다시 임베딩 과정을 거치며, 더 이상의 클러스터링이 불가능할 때까지 [임베딩 &amp;rarr; 클러스터링 &amp;rarr; 요약]의 사이클이 반복된다. 그 결과 원본 문서에 대한 다층적인 트리 표현 구조가 완성된다. RAPTOR의 강점 중 하나는 계산 효율성이다. 구축 시간과 토큰 소모량 측면에서 선형적 확장성&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Linear scalability)&lt;/span&gt;을 가지므로 대규모의 복잡한 코퍼스 처리에도 적합하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;클러스터링 알고리즘&lt;/h3&gt;
&lt;p data-path-to-node=&quot;5&quot; data-ke-size=&quot;size16&quot;&gt;RAPTOR에서 트리 구조를 가능하게 만드는 핵심은, 결국 '어떤 청크들을 한 덩어리로 묶어 요약할 것인가'를 결정하는 클러스터링 단계다. 이 단계가 제대로 작동해야 관련 내용들이 같은 가지&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(branch)&lt;/span&gt;로 정리되고, 이후 검색 과정에서 LLM이 국소적인 조각&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(top-k)&lt;/span&gt; 몇 개만 붙잡는 대신 의미 단위로 정리된 큰 맥락까지 함께 끌어올 수 있다.&lt;br /&gt;&lt;br /&gt;그런데&amp;nbsp;일반적인&amp;nbsp;하드&amp;nbsp;클러스터링&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(hard&amp;nbsp;clustering)&lt;/span&gt;은&amp;nbsp;여기서&amp;nbsp;또&amp;nbsp;다른&amp;nbsp;한계를&amp;nbsp;만든다.&amp;nbsp;텍스트&amp;nbsp;세그먼트&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(청크)&lt;/span&gt;는 현실적으로 한 가지 주제에만 깔끔하게 속하지 않는다. 한 문단 안에 배경 설명과 결론, 조건과 예외가 섞여 있는 일이 흔하다. 그럼에도 '한 청크는 오직 하나의 클러스터에만 속한다'는 전제를 강제하면, 어떤 정보는 특정 주제 트리에서 빠져버리거나, 반대로 관련성이 낮은 곳에 억지로 배치되는&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(왜곡)&lt;/span&gt; 문제가 생긴다. 결국 요약 노드&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(부모 노드)&lt;/span&gt;가 충분한 근거를 갖지 못해, 상위 레벨로 갈수록 맥락이 빈약해질 위험이 커진다.&lt;br /&gt;&lt;br /&gt;RAPTOR는 이 지점을 소프트 클러스터링&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(soft clustering)&lt;/span&gt;으로 해결한다. 클러스터 개수를 고정하지도 않고, 하나의 노드가 여러 클러스터에 동시에 속할 수 있도록 허용한다. 이렇게 하면 여러 주제와 연결된 청크가 각 주제의 요약에 함께 반영될 수 있어, 트리의 상위 요약이 특정 관점으로 치우치는 현상을 완화한다.&lt;br /&gt;&lt;br /&gt;이를 구현하기 위해 RAPTOR는 가우시안 혼합 모델&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(GMM)&lt;/span&gt;을 사용한다. 각 텍스트 임베딩 벡터가 여러 개의 가우시안 분포&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(클러스터)&lt;/span&gt; 중 어디에 속하는지 &amp;ldquo;단일 선택&amp;rdquo;이 아니라 &amp;ldquo;확률&amp;rdquo;로 계산하는 방식이다. 즉, 어떤 청크가 A 주제에 0.7, B 주제에 0.3처럼 확률적으로 중첩될 수 있다.&lt;br /&gt;&lt;br /&gt;다만&amp;nbsp;벡터&amp;nbsp;임베딩&amp;nbsp;공간은&amp;nbsp;차원이&amp;nbsp;매우&amp;nbsp;높기&amp;nbsp;때문에,&amp;nbsp;그대로&amp;nbsp;거리&amp;nbsp;기반&amp;nbsp;구조를&amp;nbsp;잡으려&amp;nbsp;하면&amp;nbsp;계산&amp;nbsp;효율과&amp;nbsp;품질이&amp;nbsp;모두&amp;nbsp;떨어질&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;RAPTOR는&amp;nbsp;이를&amp;nbsp;보완하기&amp;nbsp;위해&amp;nbsp;UMAP&amp;nbsp;차원&amp;nbsp;축소를&amp;nbsp;적용한다.&amp;nbsp;특히&amp;nbsp;n_neighbors&amp;nbsp;같은&amp;nbsp;파라미터를&amp;nbsp;통해&amp;nbsp;전역적&amp;nbsp;구조와&amp;nbsp;국소적&amp;nbsp;구조의&amp;nbsp;균형을&amp;nbsp;조절하고,&amp;nbsp;먼저&amp;nbsp;큰&amp;nbsp;덩어리의&amp;nbsp;전역&amp;nbsp;클러스터를&amp;nbsp;찾은&amp;nbsp;뒤&amp;nbsp;그&amp;nbsp;내부에서&amp;nbsp;다시&amp;nbsp;세분화하는&amp;nbsp;2단계&amp;nbsp;계층적&amp;nbsp;클러스터링을&amp;nbsp;수행한다.&amp;nbsp;요약&amp;nbsp;모델의&amp;nbsp;입력&amp;nbsp;토큰&amp;nbsp;한계를&amp;nbsp;넘는&amp;nbsp;클러스터가&amp;nbsp;생기는&amp;nbsp;경우에는,&amp;nbsp;해당&amp;nbsp;영역에서&amp;nbsp;다시&amp;nbsp;재귀적으로&amp;nbsp;클러스터링을&amp;nbsp;반복해&amp;nbsp;정보가&amp;nbsp;잘려&amp;nbsp;나가는&amp;nbsp;것을&amp;nbsp;방지한다.&lt;br /&gt;&lt;br /&gt;또 하나의 문제는 '클러스터를 몇 개로 나눌지&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($k$)&lt;/span&gt;를 미리 정할 수 없다'는 점이다. RAPTOR는 여기서 &lt;span style=&quot;color: #f89009;&quot;&gt;임의로 $k$를 찍지 않고&lt;/span&gt;, BIC&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Bayesian Information Criterion)&lt;/span&gt;를 사용해 &lt;span style=&quot;color: #f89009;&quot;&gt;적합도와 복잡도 사이의 균형이 가장 좋은 $k$를 선택&lt;/span&gt;한다. 그리고 최종 파라미터는 EM 알고리즘으로 추정해 클러스터를 안정화한다.&lt;br /&gt;&lt;br /&gt;정리하면,&amp;nbsp;RAPTOR의&amp;nbsp;클러스터링은&amp;nbsp;단순히&amp;nbsp;&amp;ldquo;비슷한&amp;nbsp;청크를&amp;nbsp;묶는다&amp;rdquo;&amp;nbsp;수준이&amp;nbsp;아니라,&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-path-to-node=&quot;5&quot;&gt;청크의 다주제성을 인정하고&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(소프트 클러스터링)&lt;/span&gt;&lt;/li&gt;
&lt;li data-path-to-node=&quot;5&quot;&gt;고차원 임베딩의 비효율을 피하며&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(UMAP)&lt;/span&gt;&lt;/li&gt;
&lt;li data-path-to-node=&quot;5&quot;&gt;전역&amp;rarr;국소 구조를 동시에 잡고&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(계층적 절차)&lt;/span&gt;&lt;/li&gt;
&lt;li data-path-to-node=&quot;5&quot;&gt;클러스터 수를 데이터 기반으로 결정하는&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(BIC+EM)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방식으로,&amp;nbsp;상위&amp;nbsp;요약&amp;nbsp;노드가&amp;nbsp;빈약해지는&amp;nbsp;구조적&amp;nbsp;약점을&amp;nbsp;줄이도록&amp;nbsp;설계되어&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;모델기반 요약&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;언어 모델을 활용한 재귀적 요약 GMM을 통해 노드들이 클러스터링되면, 각 클러스터에 속한 노드들은 언어 모델로 전달되어 요약 과정을 거친다. 이 단계는 방대한 텍스트 청크를 간결하고 일관된 요약문으로 변환하는 핵심 공정이다. 본 논문의 실험에서는 gpt-3.5-turbo를 사용하여 요약을 수행하였으며, 이를 통해 검색된 방대한 정보를 모델이 처리하기 용이한 크기로 압축하였다.&lt;br /&gt;&lt;br /&gt;요약 품질 및 할루시네이션 분석 요약 모델은 전반적으로 신뢰할 만한 결과물을 생성하지만, 정밀 주석 연구 결과 약 4%의 요약본에서 미세한 할루시네이션이 발견되었다. 그러나 이러한 오류는 상위 부모 노드로 전이되지 않았으며, 최종적인 질의응답 태스크의 성능에도 유의미한 영향을 미치지 않는 것으로 확인되었다. 이는 RAPTOR의 계층적 구조가 일부 국소적 오류에 대해 어느 정도의 복원력을 가지고 있음을 시사한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Querying&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제는 이렇게 트리에 저장된 문맥들을 어떻게 꺼내올지도 하나의 문제점이다. RAPTOR 논문에서는 크게 두가지 계념으로 이를 달성한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1356&quot; data-origin-height=&quot;511&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Exrdq/dJMb99SK8kE/pZjJVqfbxyHovDO2IYc4q0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Exrdq/dJMb99SK8kE/pZjJVqfbxyHovDO2IYc4q0/img.png&quot; data-alt=&quot;그림 2: 트리 순회 및 통합 트리 검색 메커니즘의 예시 RAPTOR는 트리 구조를 탐색하여 정보를 추출하는 두 가지 상호 보완적인 메커니즘을 제안한다. 먼저 트리 순회(Tree Traversal)는 트리의 루트 레벨에서 시작하여 질문 벡터와의 코사인 유사도를 기반으로 상위 $k$개(예시에서는 $k=1$)의 노드를 탐색한다. 이후 각 층을 내려가며 이전 레이어에서 선택된 노드의 자식 노드들 중에서만 다시 상위 k개의 노드를 추출하는 방식을 취한다. 반면, 통합 트리(Collapsed Tree) 방식은 계층 구조인 트리를 단일 레이어로 평면화(Collapse)하여 처리한다. 층의 구분 없이 모든 노드를 대상으로 질문 벡터와의 코사인 유사도를 계산하며, 설정된 토큰 임계값(Threshold)에 도달할 때까지 가장 관련성이 높은 노드들을 순차적으로 추출한다. 그림 내 강조된 부분은 각 방식에서 코사인 유사도 검색이 실제로 수행되는 대상 노드들을 나타낸다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Exrdq/dJMb99SK8kE/pZjJVqfbxyHovDO2IYc4q0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FExrdq%2FdJMb99SK8kE%2FpZjJVqfbxyHovDO2IYc4q0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;301&quot; data-origin-width=&quot;1356&quot; data-origin-height=&quot;511&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 2: 트리 순회 및 통합 트리 검색 메커니즘의 예시 RAPTOR는 트리 구조를 탐색하여 정보를 추출하는 두 가지 상호 보완적인 메커니즘을 제안한다. 먼저 트리 순회(Tree Traversal)는 트리의 루트 레벨에서 시작하여 질문 벡터와의 코사인 유사도를 기반으로 상위 $k$개(예시에서는 $k=1$)의 노드를 탐색한다. 이후 각 층을 내려가며 이전 레이어에서 선택된 노드의 자식 노드들 중에서만 다시 상위 k개의 노드를 추출하는 방식을 취한다. 반면, 통합 트리(Collapsed Tree) 방식은 계층 구조인 트리를 단일 레이어로 평면화(Collapse)하여 처리한다. 층의 구분 없이 모든 노드를 대상으로 질문 벡터와의 코사인 유사도를 계산하며, 설정된 토큰 임계값(Threshold)에 도달할 때까지 가장 관련성이 높은 노드들을 순차적으로 추출한다. 그림 내 강조된 부분은 각 방식에서 코사인 유사도 검색이 실제로 수행되는 대상 노드들을 나타낸다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-start-index=&quot;341&quot;&gt;트리 순회&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Tree Traversal)&lt;/span&gt;: 트리의 루트 층부터 시작하여 질문과 가장 유사한 상위 k개 노드를 선택하고, 선택된 노드의 자식 노드들 중에서 다시 상위 k개를 선택하는 과정을 리프 노드까지 반복한다. 이 방식은 처음에는 넓은 관점에서 시작해 점점 세부적인 정보로 초점을 좁혀 나간다.&lt;/li&gt;
&lt;li data-start-index=&quot;341&quot;&gt;접힌 트리&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Collapsed Tree, 원문 chunk 트리를 상위 요약노드로 접어둔 상태)&lt;/span&gt;: 다층 구조의 트리를 단일 층으로 평면화&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Flatten)&lt;/span&gt;하여 모든 층의 노드를 동시에 고려한다. 질문과 모든 노드 간의 코사인 유사도를 계산한 후, 미리 설정된 최대 토큰 수&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(e.g: 2000토큰)&lt;/span&gt;를 초과하지 않는 범위 내에서 상위 노드들을 선택한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 결론&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1326&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Eferw/dJMcagRTn32/2dGx9KKKOoTDmuKknZX8pK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Eferw/dJMcagRTn32/2dGx9KKKOoTDmuKknZX8pK/img.png&quot; data-alt=&quot;그림 4: Querying 프로세스: 신데렐라 이야기와 관련된 두 가지 질문 &amp;amp;ldquo;이 이야기의 중심 주제는 무엇인가?&amp;amp;rdquo;와 &amp;amp;ldquo;신데렐라는 어떻게 행복한 결말을 맞이했는가?&amp;amp;rdquo; 에 대해 RAPTOR가 정보를 검색하는 과정을 보여주는 삽화이다. 강조된 노드들은 RAPTOR가 선택한 정보를 나타내며, 화살표는 DPR(Dense Passage Retrieval)이 선택한 리프 노드(최하위 노드)를 가리킨다. 주목할 점은 RAPTOR가 제공하는 컨텍스트가 DPR이 검색한 정보를 직접적으로 포함하거나, 혹은 상위 레이어의 요약본 형태로 포함하는 경우가 많다는 것이다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Eferw/dJMcagRTn32/2dGx9KKKOoTDmuKknZX8pK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEferw%2FdJMcagRTn32%2F2dGx9KKKOoTDmuKknZX8pK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;362&quot; data-origin-width=&quot;1326&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 4: Querying 프로세스: 신데렐라 이야기와 관련된 두 가지 질문 &amp;ldquo;이 이야기의 중심 주제는 무엇인가?&amp;rdquo;와 &amp;ldquo;신데렐라는 어떻게 행복한 결말을 맞이했는가?&amp;rdquo; 에 대해 RAPTOR가 정보를 검색하는 과정을 보여주는 삽화이다. 강조된 노드들은 RAPTOR가 선택한 정보를 나타내며, 화살표는 DPR(Dense Passage Retrieval)이 선택한 리프 노드(최하위 노드)를 가리킨다. 주목할 점은 RAPTOR가 제공하는 컨텍스트가 DPR이 검색한 정보를 직접적으로 포함하거나, 혹은 상위 레이어의 요약본 형태로 포함하는 경우가 많다는 것이다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 이 그림은 RAPTOR가 단순히 텍스트를 찾는 것을 넘어, 트리 구조를 통해 문서의 담화 구조를 이해하고 활용하고 있음을 보여준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;867&quot; data-origin-height=&quot;266&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7dTyA/dJMcaaKTMuo/rumKpYOV8096eZ7ssAwOf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7dTyA/dJMcaaKTMuo/rumKpYOV8096eZ7ssAwOf0/img.png&quot; data-alt=&quot;표 1: RAPTOR 포함&amp;amp;middot;미포함 시 NarrativeQA 성능, 다양한 검색 방법(SBERT, BM25, DPR)을 NarrativeQA 데이터셋에 적용했을 때, UnifiedQA‑3B 언어 모델을 사용하여 RAPTOR를 포함했을 경우와 포함하지 않았을 경우의 성능을 비교한 표이다. RAPTOR는 각 검색 방법별 기준선보다 우수한 성능을 보여준다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7dTyA/dJMcaaKTMuo/rumKpYOV8096eZ7ssAwOf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7dTyA%2FdJMcaaKTMuo%2FrumKpYOV8096eZ7ssAwOf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;245&quot; data-origin-width=&quot;867&quot; data-origin-height=&quot;266&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 1: RAPTOR 포함&amp;middot;미포함 시 NarrativeQA 성능, 다양한 검색 방법(SBERT, BM25, DPR)을 NarrativeQA 데이터셋에 적용했을 때, UnifiedQA‑3B 언어 모델을 사용하여 RAPTOR를 포함했을 경우와 포함하지 않았을 경우의 성능을 비교한 표이다. RAPTOR는 각 검색 방법별 기준선보다 우수한 성능을 보여준다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;897&quot; data-origin-height=&quot;257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/549Dg/dJMcac2YqyL/6gBxuDPnDftcTklrMqTzR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/549Dg/dJMcac2YqyL/6gBxuDPnDftcTklrMqTzR1/img.png&quot; data-alt=&quot;표 2: RAPTOR 사용 유무에 따른 QuALITY와 QASPER 성능 QuALITY와 QASPER 데이터셋에서 다양한 검색 방법(SBERT, BM25, DPR)을 적용했을 때와 RAPTOR를 적용했을 때의 성능을 비교한 결과이다. 언어 모델로 UnifiedQA‑3B를 사용했으며, 두 데이터셋 모두에서 RAPTOR가 각 검색 방법의 기본선보다 더 높은 성능을 보여준다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/549Dg/dJMcac2YqyL/6gBxuDPnDftcTklrMqTzR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F549Dg%2FdJMcac2YqyL%2F6gBxuDPnDftcTklrMqTzR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;229&quot; data-origin-width=&quot;897&quot; data-origin-height=&quot;257&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 2: RAPTOR 사용 유무에 따른 QuALITY와 QASPER 성능 QuALITY와 QASPER 데이터셋에서 다양한 검색 방법(SBERT, BM25, DPR)을 적용했을 때와 RAPTOR를 적용했을 때의 성능을 비교한 결과이다. 언어 모델로 UnifiedQA‑3B를 사용했으며, 두 데이터셋 모두에서 RAPTOR가 각 검색 방법의 기본선보다 더 높은 성능을 보여준다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;벤치마크 자료를 살펴보자면 RAPTOR의 성능이 '드라마틱' 하지는 않다. 전반적으로 향상점이 있고, 기존 고정 top-k 로 답변하기 힘든 부분에서 보다 개선된다는 점은 있지만, 항상 이론과 현실은 다르듯 그 성능향상이 엄청나지는 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로도 RAPTOR를 간소화해 구현해 보았지만, 그 성능향상이 크게 드라마틱 하지 않다. 특히 대용량 문서에서 '전반적으로 요약' 해달라고 할 때는 큰 이점이 있을 수 있으나, 특정 지엽적인 부분을 고도로 연계하여 질문할때는 이전 방식과 동일한 증상이 여러번 발현되는것을 확인하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 기술을 참고하고, 발전시켜나갈 여지는 분명하지만, 최종적인 해결책으로 사용하기에는 문제점이 많은 기술이라고 판단한다.&lt;/p&gt;</description>
      <category>Artificial Intelligence/Paper Review</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/222</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-RAPTOR-RECURSIVE-ABSTRACTIVE-PROCESSING-FOR-TREE-ORGANIZED-RETRIEVAL#entry222comment</comments>
      <pubDate>Sun, 1 Feb 2026 23:32:22 +0900</pubDate>
    </item>
    <item>
      <title>MDP, TD, MC를 이해해보자</title>
      <link>https://cypsw.tistory.com/entry/MDP-TD-MC%EB%A5%BC-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EC%9D%B4%ED%95%B4%ED%95%B4%EB%B3%B4%EC%9E%90</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강화학습&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(RL)&lt;/span&gt;을 공부하다 보면 반드시 마주치는 세 가지 개념이 있다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MDP&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Markov Decision Process)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;MC&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Monte Carlo)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;TD&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Temporal&amp;nbsp;Difference)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 포스팅&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(&lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://cypsw.tistory.com/entry/%EB%A7%88%EB%A5%B4%EC%BD%94%ED%94%84-%EA%B2%B0%EC%A0%95-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4Markov-Decision-Process&quot;&gt;#MDP&lt;/a&gt;, &lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://cypsw.tistory.com/entry/%EB%B2%A8%EB%A7%8C-%EB%B0%A9%EC%A0%95%EC%8B%9DBellman-Equation&quot;&gt;#BE&lt;/a&gt;)&lt;/span&gt;에서도 일부 다뤘지만, 최근 책을 읽으며 다시 정리할 필요를 느껴 흐름 중심으로 새 포스팅을 작성한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;왜 강화학습은 MDP를 전제로 하나?&lt;/li&gt;
&lt;li&gt;TD와 MC는 무엇이 다른가?&lt;/li&gt;
&lt;li&gt;왜 현실에서는 TD가 더 많이 쓰이나?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. MDP: 강화학습의 전제 조건&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강화학습의 대부분의 알고리즘은 &lt;b&gt;MDP&lt;/b&gt;라는 가정 위에서 만들어진다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;MDP의 핵심 가정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수식으로 표현하면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$P(S_{t+1}, R_{t+1}\mid S_t, A_t) = P(S_{t+1}, R_{t+1}\mid H_t, A_t)$$&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;여기서 $H_t$는 시간 $t$까지의 전체 히스토리다. &lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 상태 $S_t$&lt;/li&gt;
&lt;li&gt;현재 행동 $A_t$&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 두 가지만 알면 다음 상태와 보상의 확률 분포가 결정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 따라서 과거 정보는 이미 &lt;b&gt;현재 상태에 요약되어 있어야 한다.&lt;/b&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(현재상태만 알면, 그 이전 과거를 볼 필요가 없다)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;가정이&amp;nbsp;중요한&amp;nbsp;이유는,&amp;nbsp;상태&amp;nbsp;$S_t$만으로&amp;nbsp;미래의&amp;nbsp;전이/보상&amp;nbsp;분포를&amp;nbsp;결정할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;만들기&amp;nbsp;위해서다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 요약이 가능해야 벨만 방정식과 TD 계열 알고리즘이 성립한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(이것이 마르코프성이다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 상태 가치 함수란 무엇인가?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MDP 위에서 정의되는 핵심 개념이 바로 &lt;b&gt;가치 함수&lt;/b&gt;다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$V^\pi(s) = \mathbb{E}_\pi [G_t \mid S_t = s]$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의미는 &lt;span style=&quot;color: #f89009;&quot;&gt;상태 $s$에서 시작했을 때, 앞으로 얼마나 좋은 결과를 얻게 될까?&lt;/span&gt; 로 &lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;/span&gt;리턴 $G_t$는 다음과 같이 정의된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$G_t = R_{t+1} + \gamma R_{t+2} + \gamma^2 R_{t+3} + \cdots$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 핵심 질문은 이 기댓값&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($\mathbb{E}[G_t]$)&lt;/span&gt;을 어떻게 계산할 것인가? 인데, 이 질문에 대한 답이 바로 MC&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Monte Carlo)&lt;/span&gt;와 TD&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Temporal Difference&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;)&lt;/span&gt;&lt;/b&gt;다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. Monte Carlo (MC): 정의를 그대로 추정하는 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Monte Carlo 방법은 매우 정직한 접근을 택한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;가치&amp;nbsp;함수의&amp;nbsp;정의를&amp;nbsp;그대로&amp;nbsp;샘플링으로&amp;nbsp;계산하자&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;상태 $s$에서 시작한 에피소드를 여러 번 수행하고&lt;/li&gt;
&lt;li&gt;실제로 얻은 리턴 $G_t$를 기록한 뒤&lt;/li&gt;
&lt;li&gt;그 평균을 가치로 사용한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$V(s) \approx \frac{1}{N} \sum_{i=1}^{N} G_t^{(i)}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Monte Carlo의 핵심 특징&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다음 상태 $s'$의 가치를 &lt;b&gt;추측하지 않음&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;오직 &lt;b&gt;실제로 관측된 보상&lt;/b&gt;만 사용&lt;/li&gt;
&lt;li&gt;부트스트랩&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(bootstrap)&lt;/span&gt;을 하지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, MC는 이렇게 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&amp;ldquo;미래를&amp;nbsp;요약하지&amp;nbsp;말고,&lt;br /&gt;실제로&amp;nbsp;끝까지&amp;nbsp;가서&amp;nbsp;결과를&amp;nbsp;보자&amp;rdquo;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Monte Carlo의 단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;에피소드가 끝나야 학습 가능&lt;/li&gt;
&lt;li&gt;분산이 매우 큼&lt;/li&gt;
&lt;li&gt;온라인 / 실시간 학습에 부적합&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 한 가지 장점은 분명하다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;추정값을 재사용(부트스트랩)하지 않기 때문에 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;부트스트랩에서 오는 편향을 만들지 않는다(대신 분산이 크다).&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. Temporal Difference &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(TD)&lt;/span&gt;: 미래를 한 단계로 당겨오기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TD는 다른 선택을 한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;끝까지 기다리기엔 너무 느리다&lt;br /&gt;다음 한 스텝 정보를 활용하자&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TD의 기본 업데이트 식은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$V(s) \leftarrow V(s) + \alpha \big( r + \gamma V(s') - V(s) \big)$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 핵심은 &lt;b&gt;TD Error&lt;/b&gt;다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\delta = r + \gamma V(s') - V(s)$$&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;지금 예측한 값 $V(s)$&lt;/li&gt;
&lt;li&gt;한 스텝 뒤 정보로 만든 예측 $r + \gamma V(s')$&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 &lt;b&gt;시간이 다른 두 예측의 차이&lt;/b&gt;를 이용해 학습한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 이름이 &lt;b&gt;Temporal Difference&lt;/b&gt;다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. TD의 특징과 한계&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;TD의 장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&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;h3 data-ke-size=&quot;size23&quot;&gt;TD의 단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$V(s')$라는 &lt;b&gt;추정값을 재사용&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;부트스트랩으로 인한 편향 가능&lt;/li&gt;
&lt;li&gt;상태가 마르코프하지 않으면 오차가 누적됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, TD는 이렇게 말한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;다음 상태가 미래를 대표할 수 있다고 믿자&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 믿음은 &lt;b&gt;MDP 가정&lt;/b&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(현재 상태 $s$ 만으로 과거의 필요한 정보를 충분히 요약한다.)&lt;/span&gt;이 깨질수록 위험해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. MC vs TD: 철학의 차이&lt;/h2&gt;
&lt;center&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;구분&lt;/th&gt;
&lt;th&gt;Monte Carlo&lt;/th&gt;
&lt;th&gt;TD&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&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;X&lt;/td&gt;
&lt;td&gt;O&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;큼&lt;/td&gt;
&lt;td&gt;작음&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;제한적&lt;/td&gt;
&lt;td&gt;매우 높음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/center&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;중요한 관찰&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;MC는 느리지만 정직&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;TD는 빠르지만 가정을 많이 함&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 현실에서는:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상태가 잘 정의된 문제 &amp;rarr; TD&lt;/li&gt;
&lt;li&gt;POMDP&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Partially&amp;nbsp;Observable&amp;nbsp;MDP)&lt;/span&gt;에 가까운 문제 &amp;rarr; TD가 불안정해질 수 있고, MC는 부트스트랩 오차 증폭이 없어서 상대적으로 덜 망가지는 경향이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. 마무리: 왜 이 셋을 함께 이해해야 하는가&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;MDP&lt;/b&gt;는 강화학습이 성립하기 위한 세계관&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(현재 상태는, 과거 모든상태를 요약한다.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;MC&lt;/b&gt;는 정의를 그대로 추정하는 가장 순수한 방법&lt;/li&gt;
&lt;li&gt;&lt;b&gt;TD&lt;/b&gt;는 현실적인 속도를 얻기 위한 타협&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(TD는&amp;nbsp;MC처럼&amp;nbsp;경험(샘플)로&amp;nbsp;학습하면서도,&amp;nbsp;DP처럼&amp;nbsp;부트스트랩(벨만&amp;nbsp;재귀)을&amp;nbsp;사용하는&amp;nbsp;타협안이다.)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 강화학습 알고리즘들은 대부분&lt;br /&gt;이 둘을 섞은 형태로 발전해왔다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;TD&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($\lambda$)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Eligibility Trace&lt;/li&gt;
&lt;li&gt;Actor-Critic&lt;/li&gt;
&lt;li&gt;DQN&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이들을 제대로 이해하려면, 결국 다시 &lt;b&gt;MDP&amp;ndash;MC&amp;ndash;TD&lt;/b&gt;로 돌아오게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하면, TD는 '다음 상태가 미래를 대표한다'는 가정 위에서 빠르게 학습하지만, 그 가정이 약해질수록 불안정해진다. 반대로 MC는 느리지만 추정값 재사용을 하지 않기 때문에 이런 상황에서 상대적으로 덜 망가진다. 따라서 실전에서는 상태를 마르코프하게 만들기가 TD 성능의 핵심이 된다.&lt;/p&gt;</description>
      <category>Artificial Intelligence/Insights</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/221</guid>
      <comments>https://cypsw.tistory.com/entry/MDP-TD-MC%EB%A5%BC-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EC%9D%B4%ED%95%B4%ED%95%B4%EB%B3%B4%EC%9E%90#entry221comment</comments>
      <pubDate>Tue, 27 Jan 2026 19:44:47 +0900</pubDate>
    </item>
    <item>
      <title>강화학습, 지도학습의 차이점</title>
      <link>https://cypsw.tistory.com/entry/%EA%B0%95%ED%99%94%ED%95%99%EC%8A%B5-%EC%A7%80%EB%8F%84%ED%95%99%EC%8A%B5%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90</link>
      <description>&lt;script data-mce-fragment=&quot;1&quot;&gt; MathJax = { tex: {inlineMath: [['$', '$']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot; data-mce-fragment=&quot;1&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 Richard S. Sutton 교수의 저서 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;『단단한 강화학습』&lt;/b&gt;&lt;/span&gt; 을 읽고 있는데, 초반부에 강화학습과 지도학습의 차이에 관해 상당히 많은 지면을 할애하고 있다. 처음엔 별 생각 없이 책을 읽어 나갔지만, 읽을수록 이 둘의 차이점이 모호하게 느껴지고 Sutton 교수가 지적하는 것처럼 착각하기 쉽다는 느낌이 들어 정리하기 위한 포스팅을 작성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Sutton 교수는 다른 많은 연구자들이 지도학습을 연구하면서도 자신이 강화학습을 연구한다고 믿었던 경험담을 언급한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&quot;예를&amp;nbsp;들어&amp;nbsp;로젠블렛(Rosenblatt,&amp;nbsp;1962),&amp;nbsp;위드로와&amp;nbsp;호프(Widrow&amp;nbsp;and&amp;nbsp;Hoff,&amp;nbsp;1960)&amp;nbsp;같은&amp;nbsp;연구자들은&amp;nbsp;강화학습의&amp;nbsp;개념에&amp;nbsp;동기를&amp;nbsp;부여받았으나,&amp;nbsp;실제로는&amp;nbsp;지도학습&amp;nbsp;시스템을&amp;nbsp;연구하고&amp;nbsp;있었다.&quot;&lt;br /&gt;&amp;mdash;&amp;nbsp;『단단한&amp;nbsp;강화학습』&amp;nbsp;21p&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;'시행착오' 의 진정한 의미&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강화학습은 &amp;lsquo;시행착오&amp;rsquo; 과정을 거친다. 이때 &amp;lsquo;시행착오&amp;rsquo;라는 용어 때문에 혼동을 겪기도 한다. 많은 딥러닝 서적들이 모델의 가중치를 업데이트하여 Loss 값을 최적화하는 과정 자체를 &amp;lsquo;시행착오&amp;rsquo;로 설명하기 때문이다. 넓은 의미에서 이는 틀린 말이 아니지만, Sutton 교수는 강화학습에서 말하는 &amp;lsquo;시행착오&amp;rsquo;가 이와는 완전히 다른 결을 가지고 있음을 분명히 한다.&lt;br /&gt;&lt;br /&gt;Sutton&amp;nbsp;교수에&amp;nbsp;따르면,&amp;nbsp;기존의&amp;nbsp;신경망&amp;nbsp;학습&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(지도학습)&lt;/span&gt;은 올바른 행동이 무엇인지 알려주는 &amp;lsquo;주어진 정보&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Instructed Information)&lt;/span&gt;&amp;rsquo;에 의존한다. 반면, 강화학습은 정답을 모르는 상태에서 평가적인 피드백&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(보상, Reward)&lt;/span&gt;에 기반하여 행동을 결정하고 수정해 나가는, 본질적인 의미의 시행착오 학습이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; 명확한 비교: CNN 손글씨 인식 vs CartPole&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 차이는 대표적인 지도학습 예제인 'CNN 손글씨 인식'과 강화학습 예제인 'CartPole'을 비교해보면 명확해진다.&lt;br /&gt;&lt;br /&gt;1. 지도학습 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(CNN 손글씨 인식)&lt;/span&gt;&lt;br /&gt;CNN 모델에는 각 입력 $x$마다 명확한 정답&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Label)&lt;/span&gt; $y$가 존재한다. 예를 들어, 숫자 '7' 이미지에는 '이것은 7이다' 라는 정답이 함께 주어진다. 모델의 목표는 이 정답 $y$와의 오차를 줄이는 것이다. 즉, &lt;span style=&quot;color: #f89009;&quot;&gt;학습 과정이 정답을 맞히는 것에 집중&lt;/span&gt;되어 있다.&lt;br /&gt;&lt;br /&gt;2. 강화학습 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(CartPole)&lt;/span&gt;&lt;br /&gt;CartPole&amp;nbsp;역시&amp;nbsp;&amp;lsquo;오랫동안&amp;nbsp;막대를&amp;nbsp;쓰러뜨리지&amp;nbsp;않고&amp;nbsp;생존하기&amp;rsquo;라는&amp;nbsp;명확한&amp;nbsp;목표가&amp;nbsp;있기에&amp;nbsp;언뜻&amp;nbsp;보면&amp;nbsp;지도학습과&amp;nbsp;비슷해&amp;nbsp;보인다.&amp;nbsp;하지만&amp;nbsp;결정적인&amp;nbsp;차이가&amp;nbsp;있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;지시&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Instruction)&lt;/span&gt;가 아닌 평가&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Evaluation)&lt;br /&gt;&lt;/span&gt;환경은 에이전트에게 '지금 오른쪽으로 움직였어야 해'라는 정답 행동&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Label)&lt;/span&gt;을 알려주지 않는다. 대신 '+1점' 이라는 보상&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Reward)&lt;/span&gt;을 통해 '방금 행동은 나쁘지 않았어'라고 평가할 뿐이다. &lt;span style=&quot;color: #f89009;&quot;&gt;에이전트는 이 점수만 보고 스스로 무엇이 최적의 행동인지 찾아내야 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;데이터의 상호작용&lt;br /&gt;지도학습은 고정된 데이터셋을 사용하지만, 강화학습에서는 나의 현재 행동 $A_t$가 미래의 상태 $S_{t+1}$를 변화시킨다. 내가 잘하면 계속 중심을 잡는 데이터를 보겠지만, 못하면 넘어지는 데이터만 보게 된다. 즉, &lt;span style=&quot;color: #f89009;&quot;&gt;학습 주체가 스스로 학습할 데이터를 만들어가는 상호작용 과정이라는 점이 지도학습과는 명확히 다르다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;결론: 지침&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Instruct)&lt;/span&gt; vs 평가&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Evaluate)&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 이 둘의 차이는 피드백의 성격으로 요약할 수 있다. &lt;span style=&quot;color: #f89009;&quot;&gt;지도학습은 올바른 행동을 직접 알려주는 &lt;b&gt;&amp;lsquo;지침(Instruct)&amp;rsquo;&lt;/b&gt; 기반의 학습&lt;/span&gt;이고, &lt;span style=&quot;color: #f89009;&quot;&gt;강화학습은 행동의 좋고 나쁨만을 점수로 알려주는 &lt;b&gt;&amp;lsquo;평가(Evaluate)&amp;rsquo;&lt;/b&gt; 기반의 학습&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNN 손글씨 인식에서는 '이 이미지에는 7을 출력하라'는 명확한 지침이 있다. 반면, CartPole을 훈련하는 에이전트는 보상&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Reward)&lt;/span&gt;의 총합을 최대화해야 한다는 과제만 받는다. 이 보상을 최대화하기 위해 &lt;b&gt;탐욕적인&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Exploitation, 이미 알고 있는 좋은 방법)&lt;/span&gt;&lt;/b&gt; 행동을 할지, 아니면 더 나은 보상을 찾기 위해 &lt;b&gt;탐색적인&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Exploration, 새로운 방법)&lt;/span&gt;&lt;/b&gt; 시도를 해볼지는 에이전트가 자신의 정책, 가치함수, 그리고 환경 모델에 근거하여 스스로 판단해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것이 Sutton 교수가 강조하는 강화학습과 지도학습의 차이점이다.&lt;/p&gt;</description>
      <category>Artificial Intelligence/Insights</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/220</guid>
      <comments>https://cypsw.tistory.com/entry/%EA%B0%95%ED%99%94%ED%95%99%EC%8A%B5-%EC%A7%80%EB%8F%84%ED%95%99%EC%8A%B5%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90#entry220comment</comments>
      <pubDate>Wed, 7 Jan 2026 23:02:11 +0900</pubDate>
    </item>
    <item>
      <title>강화학습, 월드모델의 차이점</title>
      <link>https://cypsw.tistory.com/entry/%EA%B0%95%ED%99%94%ED%95%99%EC%8A%B5-%EC%9B%94%EB%93%9C%EB%AA%A8%EB%8D%B8%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 생성형 AI와 로보틱스 분야에서 월드 모델&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(World Model)&lt;/span&gt;이라는 키워드가 자주 등장한다. 이 개념을 공부하다 보면 자연스럽게 이런 의문이 든다. 어차피 둘 다 에이전트가 환경에서 상호작용하며 배우는 것 같은데, 월드 모델이랑 강화학습은 대체 뭐가 다른가? &lt;a href=&quot;https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-World-Models&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전에 리뷰&lt;/a&gt;한 World Models&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(2018)&lt;/span&gt; 논문을 보면, 월드 모델이 실제 게임을 하는것 처럼 보이기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비슷해 보이지만, 두 모델은 목표와 역할이 분명히 다르다. 이 글에서는 월드 모델과 강화학습의 개념적 차이를 간단히 설명한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;월드 모델&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(World Model)&lt;/span&gt;: 환경 동역학을 학습하고 미래 상태를 예측한다. 즉 &quot;이 행동을 하면 세상이 어떻게 변하는가?&quot;에 관심이 있으며, 예측 정확도로 평가받는다.&lt;/li&gt;
&lt;li&gt;강화학습&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Reinforcement Learning)&lt;/span&gt;: 환경과 상호작용하며 보상을 최대화하는 정책을 학습한다. 즉 &quot;어떻게 행동해야 보상을 가장 많이 받는가?&quot;에 관심이 있으며, 누적 보상으로 평가받는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 월드 모델은 점수에는 관심이 없고, &lt;span style=&quot;color: #f89009;&quot;&gt;세상이 어떻게 변하는지를 잘 맞히는 것만 신경 쓴다&lt;/span&gt;.&amp;nbsp;반면&amp;nbsp;강화학습은&amp;nbsp;세부&amp;nbsp;물리가&amp;nbsp;어떻든&amp;nbsp;&lt;span style=&quot;color: #f89009;&quot;&gt;점수만&amp;nbsp;잘&amp;nbsp;나오면&amp;nbsp;된다는&amp;nbsp;입장&lt;/span&gt;이다. 환경 그 자체와 환경에서 활동하는 Agent로 그 차이를 말할 수 있는것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;근거&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나를 포함해 많은 사람들이 헷갈리는 지점은 바로 유명한 &lt;a href=&quot;https://arxiv.org/abs/1803.10122&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;World Models&lt;/a&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(2018)&lt;/span&gt; 논문 때문이다. 이 논문을 대충 보면, 월드 모델이 마치 스스로 게임을 풀고, 꿈도 꾸고, 에이전트처럼 행동하는 것처럼 보인다. 그러나 자세히 읽어보면, 저자들은 에이전트를 세 가지 모듈로 명확히 분리해 두었고, &lt;span style=&quot;color: #f89009;&quot;&gt;이 세가지 모듈은 크게 두가지 개념&lt;/span&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(월드모델, 강화학습)&lt;/span&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;으로 분리&lt;/span&gt;된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2387&quot; data-origin-height=&quot;1582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMoU80/dJMcahXfBl8/9affsKf4vLGKUpUZk1842K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMoU80/dJMcahXfBl8/9affsKf4vLGKUpUZk1842K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMoU80/dJMcahXfBl8/9affsKf4vLGKUpUZk1842K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMoU80%2FdJMcahXfBl8%2F9affsKf4vLGKUpUZk1842K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;530&quot; data-origin-width=&quot;2387&quot; data-origin-height=&quot;1582&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$V$&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Vision, 시각 인코더)&lt;/span&gt;: 입력 이미지&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(픽셀)&lt;/span&gt;를 받아서 저차원 잠재 벡터 $z$로 압축하는 VAE이다. 지금 화면이 어떤 상황인지를 요약하는 역할을 한다.&lt;/li&gt;
&lt;li&gt;$M$&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Memory, 시계열 예측기)&lt;/span&gt;: RNN 기반 MDN-RNN으로, 현재의 $z$, 과거의 히든 상태 $h$, 그리고 행동 $a$를 받아 다음 잠재 상태와 같은 미래를 예측한다. 즉, 지금 이렇게 움직이면 다음에는 어떤 장면이 나올까? 를 예측하는 순수한 동역학 모델이다.&lt;/li&gt;
&lt;li&gt;$C$&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Controller, 제어기/정책)&lt;/span&gt;: $z$와 $h$를 입력으로 받아 실제 행동 $a$를 출력하는 매우 작은 선형 정책 모듈이다. 이 모듈만이 보상&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(reward)&lt;/span&gt;에 접근하며, 누적 보상을 최대화하도록 최적화된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문에서 저자들은 직접 다음과 같이 밝힌다. &lt;i&gt;&quot;실험에서 우리는 의도적으로 $C$를 가능한 한 단순하고 작게 만들고, $V$와 $M$과는 분리해서 훈련함으로써, 에이전트의 복잡성 대부분이 &lt;span style=&quot;color: #ee2323;&quot;&gt;월드 모델&lt;/span&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(V와 M)&lt;/span&gt;에 머무르도록 했다&quot;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한&amp;nbsp;CarRacing&amp;nbsp;실험을&amp;nbsp;설명하는&amp;nbsp;부분에서는,&amp;nbsp;이&amp;nbsp;실험에서&amp;nbsp;월드&amp;nbsp;모델&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(V와&amp;nbsp;M)&lt;/span&gt;은&amp;nbsp;환경의&amp;nbsp;실제&amp;nbsp;보상&amp;nbsp;신호에&amp;nbsp;대한&amp;nbsp;정보를&amp;nbsp;전혀&amp;nbsp;가지지&amp;nbsp;않으며,&amp;nbsp;단지&amp;nbsp;프레임&amp;nbsp;시퀀스를&amp;nbsp;압축하고&amp;nbsp;예측하는&amp;nbsp;역할만&amp;nbsp;한다.&amp;nbsp;보상&amp;nbsp;정보에&amp;nbsp;접근하는&amp;nbsp;것은&amp;nbsp;오직&amp;nbsp;컨트롤러&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(C)&lt;/span&gt;뿐이라고 명시한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 논문에서 월드 모델이라고 부르는 것은 엄밀히 $V + M$이고, $C$는 그 위에 얹힌, 월드모델과는 별개의 모듈임을 저자가 직접 못 박는 셈이다.&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;논문 World Models 인용&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&quot;In&amp;nbsp;our&amp;nbsp;experiments,&amp;nbsp;we&amp;nbsp;deliberately&amp;nbsp;make&amp;nbsp;C&amp;nbsp;as&amp;nbsp;simple&amp;nbsp;and&amp;nbsp;small&amp;nbsp;as&amp;nbsp;possible,&amp;nbsp;and&amp;nbsp;trained&amp;nbsp;separately&amp;nbsp;from&amp;nbsp;V&amp;nbsp;and&amp;nbsp;M,&amp;nbsp;so&amp;nbsp;that&amp;nbsp;most&amp;nbsp;of&amp;nbsp;our&amp;nbsp;agent's&amp;nbsp;complexity&amp;nbsp;resides&amp;nbsp;in&amp;nbsp;the&amp;nbsp;world&amp;nbsp;model&amp;nbsp;(V&amp;nbsp;and&amp;nbsp;M).&quot;&lt;br /&gt;&amp;rarr; &quot;우리의 실험에서, 우리는 의도적으로 C를 가능한 한 단순하고 작게 만들었으며 V와 M과는 분리하여 훈련시켰습니다. 그리하여 우리 에이전트의 복잡성 대부분이 월드 모델(V와 M)에 머무르도록 했습니다.&quot;&lt;br /&gt;&lt;br /&gt;&quot;In this experiment,&amp;nbsp;the world model (V and M)&amp;nbsp;has no knowledge about the actual reward signals from the environment. Its task is simply to compress and predict the sequence of image frames observed.&amp;nbsp;Only the Controller (C) Model has access to the reward information&amp;nbsp;from the environment.&quot;&lt;br /&gt;&amp;rarr; &quot;이 실험에서 월드 모델(V와 M)은 환경으로부터의 실제 보상 신호에 대한 어떠한 정보도 가지고 있지 않습니다. 그것의 임무는 단순히 관찰된 이미지 프레임 시퀀스를 압축하고 예측하는 것입니다. 오직 컨트롤러(C) 모델만이 환경으로부터의 보상 정보에 접근할 수 있습니다.&quot;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.nvidia.com/en-us/glossary/world-models/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Nvidia의 글&lt;/a&gt;을 보면 이를 확실히 할 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;월드 모델은 물리와 공간적 특성을 포함한 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;실제 세계의 동역학을 이해하는 신경망&lt;/b&gt;&lt;/span&gt;이다. 텍스트, 이미지, 비디오, 움직임 등의 입력 데이터를 활용해 현실적인 물리 환경을 시뮬레이션하는 영상을 생성할 수 있다. 피지컬 AI 개발자들은 로봇과 자율주행 차량을 학습시키기 위해 맞춤형 합성 데이터나 후속 AI 모델을 생성하는 용도로 월드 모델을 활용한다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;월드 모델과 강화학습을 엄밀히 구분하길 바란다. 어떤 이들은 &lt;span style=&quot;color: #f89009;&quot;&gt;월드모델을 마치 에이전트처럼 구축할수도 있지 않느냐고 반문하겠지만, 이미 그런 단계에 진입한 순간 월드모델이 아니다&lt;/span&gt;. &lt;a href=&quot;https://brunch.co.kr/@synabreu/59&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Dreamer V3&lt;/a&gt; 같은 글의 포스팅을 보면 &quot;월드 모델을 통해 최초로 마인크래프트에서 다이아몬드를 채굴하는데 성공했다&quot; 라고 선전하지만, 이는 World Model을 활용해 강화학습 에이전트를 학습시켜 다이아몬드를 채굴하는데 성공한것이지, 월드모델이 다이아몬드를 채굴한게 아니라는 것을 명확히 할 필요가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;월드모델은 세계의 동역학을 이해하는 신경망으로서, 다른 후속 AI모델을 생성하는 용도로 주로 사용됨을 명심하라.&lt;/p&gt;</description>
      <category>Artificial Intelligence/Insights</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/219</guid>
      <comments>https://cypsw.tistory.com/entry/%EA%B0%95%ED%99%94%ED%95%99%EC%8A%B5-%EC%9B%94%EB%93%9C%EB%AA%A8%EB%8D%B8%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90#entry219comment</comments>
      <pubDate>Sun, 14 Dec 2025 20:32:45 +0900</pubDate>
    </item>
    <item>
      <title>LLM 서빙 최적화의 함정: Chunked Prefill과 Disaggregation의  한계</title>
      <link>https://cypsw.tistory.com/entry/LLM-%EC%84%9C%EB%B9%99-%EC%B5%9C%EC%A0%81%ED%99%94%EC%9D%98-%ED%95%A8%EC%A0%95-Chunked-Prefill%EA%B3%BC-Disaggregation%EC%9D%98-%ED%95%9C%EA%B3%84</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1710&quot; data-origin-height=&quot;648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cc5NXv/dJMcacH9hYM/VlKAd5lrVkeiI8EdJXZZZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cc5NXv/dJMcacH9hYM/VlKAd5lrVkeiI8EdJXZZZ1/img.png&quot; data-alt=&quot;LLM의 기본 동작 원리: Prefill - Decode&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cc5NXv/dJMcacH9hYM/VlKAd5lrVkeiI8EdJXZZZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcc5NXv%2FdJMcacH9hYM%2FVlKAd5lrVkeiI8EdJXZZZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;303&quot; data-origin-width=&quot;1710&quot; data-origin-height=&quot;648&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;LLM의 기본 동작 원리: Prefill - Decode&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM은 내부적으로 &lt;span data-token-index=&quot;1&quot;&gt;Prefill&lt;/span&gt;과 &lt;span data-token-index=&quot;3&quot;&gt;Decode&lt;/span&gt; 단계로 동작한다. 동시 접속자가 1명일 때는 두 과정이 순차적으로 문제없이 진행되지만, 동시 접속자가 여러 명일 때는 Decode 속도가 완만하게 저하되는 것이아니라, 급격히 버벅이는 증상을 느낄 수 있다. 이는 두 단계가 GPU 자원을 놓고 경쟁하기 때문이며, 이들 간의 간섭을 최소화하는 것이 인공지능 서빙 분야의 주요 과제 중 하나다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 현상을 이해하려면 먼저 &lt;b&gt;Prefill&lt;/b&gt;이&lt;b&gt; compute-bound &lt;/b&gt;작업이라는 점을 알아야 한다. Prefill은 입력된 전체 프롬프트를 처리하여 KV cache를 생성하는 과정이다. 모든 입력 토큰이 이미 주어져 있기 때문에, self-attention 연산을 대규모 행렬 곱셈으로 병렬 처리할 수 있다. 따라서 GPU의 연산 자원을 거의 100%에 가깝게 활용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 &lt;b&gt;Decode&lt;/b&gt;는&lt;b&gt; memory-bound &lt;/b&gt;작업이다. Decode는 이전에 생성된 토큰들을 참조하여 다음 토큰을 하나씩 생성하는 autoregressive 과정이다. 각 단계마다 KV cache 전체를 메모리에서 읽어와야 하지만, 실제 연산량은 상대적으로 적다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;420&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3pKsM/dJMcacuB9IV/SItdAMe6K2MQSVK1tEiGt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3pKsM/dJMcacuB9IV/SItdAMe6K2MQSVK1tEiGt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3pKsM/dJMcacuB9IV/SItdAMe6K2MQSVK1tEiGt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3pKsM%2FdJMcacuB9IV%2FSItdAMe6K2MQSVK1tEiGt1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;224&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;420&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 이러한 Prefill - Decode 과정은 위 이미지에서도 볼 수 있듯, '순차적으로' 이뤄진다. 따라서 단일 사용자 환경에서 이 둘은 서로에게 간섭을 일으키지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1295&quot; data-origin-height=&quot;293&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccYSaX/dJMcabbo38J/fjqxhVTEFhtDddJ3KKYvpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccYSaX/dJMcabbo38J/fjqxhVTEFhtDddJ3KKYvpK/img.png&quot; data-alt=&quot;좌: decode 우선, 우: prefill 우선&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccYSaX/dJMcabbo38J/fjqxhVTEFhtDddJ3KKYvpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccYSaX%2FdJMcabbo38J%2FfjqxhVTEFhtDddJ3KKYvpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;181&quot; data-origin-width=&quot;1295&quot; data-origin-height=&quot;293&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;좌: decode 우선, 우: prefill 우선&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 &lt;b&gt;다중 사용자 환경에서는&lt;/b&gt; Prefill 요청이 들어오면 GPU 자원을 집중적으로 사용하면서 진행 중인 Decode 요청들을 대기시키거나, 아예 Prefill을 대기시키면서 사용자에게 긴 대기시간을 요구하게 된다. 즉 좌측의 경우 모든 Decode 요청이 끝나기 전까지는 새로운 Prefill 요청을 받지 못하고. 우측의 경우는 Prefill 중에는 Decode 가 중단되는 문제가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Chunked Prefill&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;858&quot; data-origin-height=&quot;151&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxoJm5/dJMcafEScDZ/7oRL0HBGipbRukqGbMuSuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxoJm5/dJMcafEScDZ/7oRL0HBGipbRukqGbMuSuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxoJm5/dJMcafEScDZ/7oRL0HBGipbRukqGbMuSuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxoJm5%2FdJMcafEScDZ%2F7oRL0HBGipbRukqGbMuSuk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;141&quot; data-origin-width=&quot;858&quot; data-origin-height=&quot;151&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대표적인 LLM Serving 프레임워크인 &lt;a href=&quot;https://github.com/sgl-project/sglang&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;SGLang&lt;/a&gt;, &lt;a href=&quot;https://github.com/vllm-project/vllm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;vLLM&lt;/a&gt;에서는 이러한 증상을 완화시키기 위해 `Chunked Prefill` 이라는 옵션을 제공한다. 이름만큼 직관적인 녀석인데, 기존에는 한번에 모든 토큰을 처리하던 방식을 벗어나 Chunked 된 토큰을 잘게 나눠 처리하는것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;690&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Zvblb/dJMcaj8lqz3/ywSrIYeH6KZAjGOcVVRYJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Zvblb/dJMcaj8lqz3/ywSrIYeH6KZAjGOcVVRYJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Zvblb/dJMcaj8lqz3/ywSrIYeH6KZAjGOcVVRYJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZvblb%2FdJMcaj8lqz3%2FywSrIYeH6KZAjGOcVVRYJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;307&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;690&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 옵션 덕분에 Decode 중인 사용자 A, Prefill 중인 사용자 B가 동시에 llm 엔진을 구동한다고 해서 토큰생성&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Decode)&lt;/span&gt;이 완전히 멈추거나, Prefill 완료를 위해 Decode 중지까지 기다리는일은 없어졌으나, `Chunked Prefill` 을 사용해도 기존 토큰Decode 속도가 100 token/s 라면, 이것이 Prefill 과 겹친다면 5 token/s 까지 내려가는 불쾌한 경험을 할 수 밖에 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다고 Decode 사용자를 위한답시고 `Chunked Prefill` 값을 극단적으로 256 정도로 낮춰버리면, 결국 Prefill 처리에 온전히 GPU를 사용하지 못하게 되기에, 전체 처리량에서 더 나쁜 처리량을 갖게 된다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(vLLM 에선 최선의 처리량을 위해 Chunked Prefill 8193 이상을 &lt;a href=&quot;https://docs.vllm.ai/en/latest/configuration/optimization.html#performance-tuning-with-chunked-prefill&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;권장&lt;/a&gt;한다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Disaggregation&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 다른 옵션으로 `&lt;b&gt;Disaggregation`&lt;/b&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(분리, 분해)&lt;/span&gt;&amp;nbsp;가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 모드는 GPU를 분리하여, 특정 GPU는 Prefill을 처리하고, 또다른 특정 GPU는 Decode 를 전용으로 처리하도록 하는 옵션이다. SGLang 에서는 &lt;a href=&quot;https://docs.sglang.ai/advanced_features/pd_disaggregation.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;PD Disaggregation&lt;/a&gt; 이라고 지칭하며, vLLM 에서는 &lt;a href=&quot;https://docs.vllm.ai/en/stable/features/disagg_prefill.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;disaggregation-mode&lt;/a&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(experimental)&lt;/span&gt; 라 지칭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wR0Yh/dJMcabCtoq0/Yv4BuEiSjDMlhsJAT1eNNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wR0Yh/dJMcabCtoq0/Yv4BuEiSjDMlhsJAT1eNNK/img.png&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;521&quot; data-is-animation=&quot;false&quot; width=&quot;650&quot; height=&quot;498&quot; style=&quot;width: 51.1156%; margin-right: 10px;&quot; data-widthpercent=&quot;51.72&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wR0Yh/dJMcabCtoq0/Yv4BuEiSjDMlhsJAT1eNNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwR0Yh%2FdJMcabCtoq0%2FYv4BuEiSjDMlhsJAT1eNNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;680&quot; height=&quot;521&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjYbY9/dJMcain3Yvh/pRUu0kuCMoLF8VLihTG51K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjYbY9/dJMcain3Yvh/pRUu0kuCMoLF8VLihTG51K/img.png&quot; data-origin-width=&quot;1316&quot; data-origin-height=&quot;1080&quot; data-is-animation=&quot;false&quot; style=&quot;width: 47.7216%;&quot; data-widthpercent=&quot;48.28&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjYbY9/dJMcain3Yvh/pRUu0kuCMoLF8VLihTG51K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjYbY9%2FdJMcain3Yvh%2FpRUu0kuCMoLF8VLihTG51K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1316&quot; height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;Disaggregation 설계: SGLang / vLLM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 잘 생각해 보면 이런 방식도 Prefill-Decode 지연 문제를 완벽히 해결한것은 아니다. 물론, 이미 Decode 중인 사용자는 다른 사용자의 Prefill 이 많이 들어온다 할지라도 그대로 Decode 될 것이다. 하지만 반대로 Prefill 요청이 여러 사용자로부터 동시에 들어온다면 Decode용 GPU는 놀고있는데, Prefill GPU만 과부하되어 전체적인 처리량을 오히려 떨어뜨리는 문제가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 이러한 `Disaggregation` 옵션은 절대로 전체 처리량은 증가시키지 않으며, 제한적인 상황에서만 사용자들의 만족도를 끌어올린다. 오히려 거의 모든 상황에서 전체적인 처리량을 감소시키는 문제가 있다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Decode를 위해서는 모든 KV 캐쉬를 Prefill GPU로부터 무조건 가져와야 하는 등...)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자원이 무제한이라면 서빙에 대해 걱정할 필요가 없다. 무제한의 GPU중, 비어있는 GPU들을 사용하도록 할당하면 되니까. 하지만 전세계 어떤 회사에서도 자원이 무제한인 곳은 없다. OpenAI의 ChatGPT 조차&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(클라우드를 사용해 배포한다 해도) &lt;/span&gt;간헐적으로 서비스가 터지니 말이다. 때문에 엔지니어는 사용자 만족도 개선을 위해서 여러 방법들을 고려해야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 개인적으로 생각하기에 `Disaggregation` 기법은 상당히 조심히 사용해야 한다. 특정한 상황이 주어지지 않는한, 항상 전체 처리량에서 손해를 보기 때문이다. 결국 그 손해보는 처리량보다 사용자 만족도를 크게 올릴 수 있다는 확신이 없는이상 도입을 조심해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vLLM 측에서도 `Disaggregation`에 대해 experiment 로 박아두고, 최우선 과제로 삼지 않는 이유중 이러한 단점이 지대한 비중을 차지하고 있다고 생각한다.&lt;/p&gt;</description>
      <category>Artificial Intelligence/Insights</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/218</guid>
      <comments>https://cypsw.tistory.com/entry/LLM-%EC%84%9C%EB%B9%99-%EC%B5%9C%EC%A0%81%ED%99%94%EC%9D%98-%ED%95%A8%EC%A0%95-Chunked-Prefill%EA%B3%BC-Disaggregation%EC%9D%98-%ED%95%9C%EA%B3%84#entry218comment</comments>
      <pubDate>Sat, 1 Nov 2025 13:17:10 +0900</pubDate>
    </item>
    <item>
      <title>[리뷰] ROFORMER: ENHANCED TRANSFORMER WITH ROTARY POSITION EMBEDDING</title>
      <link>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-ROFORMER-ENHANCED-TRANSFORMER-WITH-ROTARY-POSITION-EMBEDDING</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 Alibaba 의 LLM 모델인 Qwen3 시리즈에서는 계속해서 RoPE 기술을 적용하고 있다. 이걸 적용하는 이유는 매우 긴 컨텍스트&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(1M)&lt;/span&gt; 가용을 가능하게 해 주기에 그런데... 사실 적용해 봐도 어지간한 GPU 환경에서는 Prefill 이 너무 늘어지기에 실시간 채팅 용도로 1M 수준의 컨텍스트를 가용하기는 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 이전에는 성능문제로 가용이 불가능했던, 큰 컨텍스트를 RoPE를 통해 가용 가능하게 된 점이 신기해서 논문을 리뷰해본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 서론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜스포머 기반 사전학습 언어모델은 self-attention 메커니즘을 사용하여 문맥을 학습하지만, self-attention 자체는 위치 정보를 인식하지 못한다. 때문에 다들 알다시피 Positional Encoding 을 임베딩에 더해 처리하곤 했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;910&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qcfT6/btsQ5VfMh92/Sc9YA3L77r7P23PgIvZ4K0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qcfT6/btsQ5VfMh92/Sc9YA3L77r7P23PgIvZ4K0/img.png&quot; data-alt=&quot;All you need attention 논문에서 발췌.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qcfT6/btsQ5VfMh92/Sc9YA3L77r7P23PgIvZ4K0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqcfT6%2FbtsQ5VfMh92%2FSc9YA3L77r7P23PgIvZ4K0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;741&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;910&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;All you need attention 논문에서 발췌.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이러한 방식은 self-attention 아키텍처와 비호환적인 경향이 있다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(논문에서는 기존 방식을 '덧셈 기반' 방식 사용을 호환 문제로 언급한다).&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RoPE는 이러한 문제를 통합하여, 곱셈기반&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(multiplicative)&lt;/span&gt; 접근방식을 제안한다. 이는 회전 행렬을 컨텍스트 표현에 곱함으로서 상대 위치 정보를 통합하는 방식이다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(즉, 이전의 덧셈 방식에서는 그냥 따로 노는형태로 위치 정보를 추가했다는 점을 추측할 수 있다, 당연히 이럴 경우 효율적으로 계산하기 어려운 구조가 형성된다는 점 역시 추측할 수 있다. 마치 네트워크 패킷의 특정부분은 단어 임베딩(1~4 byte), 특정부분은 위치 임베딩(5~8 byte)... 처럼 따로 모델이 구분해서 처리했기에 비 효율적이였던 것이다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 방식을 통해서 RoPE는 시퀀스 길이에 대한 유연성을 제공하고. 이는 모델이 학습 시 사용된 최대 길이 이상의 긴 시퀀스에 대해 잘 일반화 될 수 있도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Rotary position embedding&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m2Tgj/btsQ5CVmUCL/G3n4JBPi1F3bIi6Kx3elMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m2Tgj/btsQ5CVmUCL/G3n4JBPi1F3bIi6Kx3elMK/img.png&quot; data-alt=&quot;Figure 1: Implementation of Rotary Position Embedding(RoPE).&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m2Tgj/btsQ5CVmUCL/G3n4JBPi1F3bIi6Kx3elMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm2Tgj%2FbtsQ5CVmUCL%2FG3n4JBPi1F3bIi6Kx3elMK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;340&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 1: Implementation of Rotary Position Embedding(RoPE).&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RoPE는 회전&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Rotation)&lt;/span&gt;을 통해서 이러한 목표를 달성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RoPE는 위치 임베딩을 통합하는것이 affine-transformed 된 word embedding 벡터를 해당 위치 인덱스의 각도 배수만큼, 단순히 회전시키는것으로 해석할 수 있으며, &lt;span style=&quot;color: #ee2323;&quot;&gt;이것이 곧 Rotary Position Embedding 의 직관이자 전부&lt;/span&gt;다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상세하게 설명하자면 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-start-index=&quot;338&quot;&gt;인코딩된 쿼리&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($q_m$)&lt;/span&gt;와 키&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($k_n$)&lt;/span&gt;의 내적&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(inner product)&lt;/span&gt;이 &lt;/span&gt;오직 단어 임베딩&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($x_m, x_n$)&lt;/span&gt;과 상대 위치&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($m-n$)&lt;/span&gt;에만 의존&lt;span data-start-index=&quot;451&quot;&gt;하도록 만드는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2-1. A 2D case&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이해를 돕기 위한 부분이고, 실제 Transformer 에서 사용되지 않았다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(실제 사용된것은 General form 부분)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RoPE의 직관은 2차원&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($d=2$)&lt;/span&gt; 평면에서 벡터의 기하학적 속성을 이용하여 도출되었다. 위치 $m$에 있는 쿼리 벡터 $q_m$에 위치 정보를 통합하는 함수 $f_q$는 복소수 형식으로 다음과 같이 표현될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2D 위치 인코딩 함수 수식&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Equation 33)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&lt;br /&gt;\begin{array}{l}&lt;br /&gt;f_q(x_m,&amp;nbsp;m)&amp;nbsp;=&amp;nbsp;(W_q&amp;nbsp;x_m)e^{im\theta},&amp;nbsp;\\&lt;br /&gt;f_k(x_n,&amp;nbsp;n)&amp;nbsp;=&amp;nbsp;(W_k&amp;nbsp;x_n)e^{in\theta}.&lt;br /&gt;\end{array}&lt;br /&gt;\quad&amp;nbsp;(33)&lt;br /&gt;$$&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여기서 $W_q x_m$과 $W_k x_n$은 위치 정보가 없는 affine-transformed된 단어 임베딩 벡터이다&lt;/li&gt;
&lt;li&gt;$e^{im\theta}$는 위치 인덱스 $m$에 비례하는 각도&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($m\theta$)&lt;/span&gt;만큼의 회전을 복소수 평면에서 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 방식으로 위치 인코딩된 쿼리 $q_m$과 키 $k_n$을 내적할 경우, 복소수 성질에 의해 위치 정보 항이 상대 위치&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($m-n$)&lt;/span&gt;로만 남게 되며, 이 내적을 실수부로 나타낸 것이 RoPE의 2D 내적 수식&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Equation 12)&lt;/span&gt; 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&lt;br /&gt;g(x_m,&amp;nbsp;x_n,&amp;nbsp;m&amp;nbsp;-&amp;nbsp;n)&amp;nbsp;=&amp;nbsp;\text{Re}[(W^q&amp;nbsp;x_m)(W^k&amp;nbsp;x_n)^*&amp;nbsp;e^{i(m-n)\theta}]&lt;br /&gt;\quad&amp;nbsp;(12)&lt;br /&gt;$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;수식은&amp;nbsp;위치&amp;nbsp;인코딩이&amp;nbsp;곧&amp;nbsp;벡터를&amp;nbsp;위치&amp;nbsp;인덱스의&amp;nbsp;각도&amp;nbsp;배수만큼&amp;nbsp;단순&amp;nbsp;회전시키는&amp;nbsp;것이라는&amp;nbsp;RoPE의&amp;nbsp;직관을&amp;nbsp;뒷받침한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-start-index=&quot;1313&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span data-start-index=&quot;1313&quot;&gt;2-2. General&amp;nbsp;form&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;div data-start-index=&quot;1338&quot;&gt;&lt;span data-start-index=&quot;1338&quot;&gt;실제 트랜스포머 모델에서 사용되는 $d$ 차원&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(짝수)&lt;/span&gt;의 벡터에 RoPE를 적용하기 위해, 2차원 회전의 개념을 일반화하여 로터리 행렬을 도입한다.&lt;/span&gt;&lt;/div&gt;
&lt;div data-start-index=&quot;1444&quot;&gt;일반적인 위치 인코딩 함수&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Equation 14)&lt;/span&gt;&lt;b data-start-index=&quot;1444&quot;&gt;:&lt;/b&gt;&lt;span data-start-index=&quot;1473&quot;&gt; &lt;/span&gt;&lt;span data-start-index=&quot;1473&quot;&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div data-start-index=&quot;1444&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&lt;br /&gt;f_{\{q,k\}}(x_m, m) = R_{\Theta, m}^d W_{\{q,k\}} x_m&lt;br /&gt;\quad&amp;nbsp;(14)&lt;br /&gt;$$&lt;/p&gt;
&lt;/div&gt;
&lt;div data-start-index=&quot;1528&quot;&gt;&lt;span data-start-index=&quot;1528&quot;&gt;여기서 $R_{\Theta, m}^d$은 $d/2$개의 2차원 회전 블록을 대각선으로 배치하여 구성한 로터리 행렬 이다.&lt;/span&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-start-index=&quot;1600&quot;&gt;로터리 행렬의 구조&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Equation 15)&lt;/span&gt;:&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&lt;br /&gt;\mathbf{R}_{\Theta,m}^d&amp;nbsp;=&amp;nbsp;\begin{pmatrix}&lt;br /&gt;\cos&amp;nbsp;m\theta_1&amp;nbsp;&amp;amp;&amp;nbsp;-\sin&amp;nbsp;m\theta_1&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;nbsp;\cdots&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;\\&lt;br /&gt;\sin&amp;nbsp;m\theta_1&amp;nbsp;&amp;amp;&amp;nbsp;\cos&amp;nbsp;m\theta_1&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;nbsp;\cdots&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;\\&lt;br /&gt;0&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;nbsp;\cos&amp;nbsp;m\theta_2&amp;nbsp;&amp;amp;&amp;nbsp;-\sin&amp;nbsp;m\theta_2&amp;nbsp;&amp;amp;&amp;nbsp;\cdots&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;\\&lt;br /&gt;0&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;nbsp;\sin&amp;nbsp;m\theta_2&amp;nbsp;&amp;amp;&amp;nbsp;\cos&amp;nbsp;m\theta_2&amp;nbsp;&amp;amp;&amp;nbsp;\cdots&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;\\&lt;br /&gt;\vdots&amp;nbsp;&amp;amp;&amp;nbsp;\vdots&amp;nbsp;&amp;amp;&amp;nbsp;\vdots&amp;nbsp;&amp;amp;&amp;nbsp;\vdots&amp;nbsp;&amp;amp;&amp;nbsp;\ddots&amp;nbsp;&amp;amp;&amp;nbsp;\vdots&amp;nbsp;&amp;amp;&amp;nbsp;\vdots&amp;nbsp;\\&lt;br /&gt;0&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;nbsp;\cdots&amp;nbsp;&amp;amp;&amp;nbsp;\cos&amp;nbsp;m\theta_{d/2}&amp;nbsp;&amp;amp;&amp;nbsp;-\sin&amp;nbsp;m\theta_{d/2}&amp;nbsp;\\&lt;br /&gt;0&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;nbsp;\cdots&amp;nbsp;&amp;amp;&amp;nbsp;\sin&amp;nbsp;m\theta_{d/2}&amp;nbsp;&amp;amp;&amp;nbsp;\cos&amp;nbsp;m\theta_{d/2}&lt;br /&gt;\end{pmatrix}&lt;br /&gt;\quad&amp;nbsp;(15)&lt;br /&gt;$$&lt;/p&gt;
&lt;div data-start-index=&quot;1984&quot;&gt;&lt;span data-start-index=&quot;1984&quot;&gt;이 로터리 행렬을 사용하여 쿼리&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($q_m$)&lt;/span&gt;와 키&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($k_n$)&lt;/span&gt;를 인코딩한 후, 이들의 내적은 다음과 같이 &lt;/span&gt;상대 위치에 의존하는 최종 형태&lt;span data-start-index=&quot;2060&quot;&gt;를 얻게된다.&lt;/span&gt;&lt;/div&gt;
&lt;div data-start-index=&quot;2069&quot;&gt;Self-Attention 내적 수식 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Equation 16)&lt;/span&gt;&lt;b data-start-index=&quot;2069&quot;&gt;:&lt;/b&gt;&lt;span data-start-index=&quot;2104&quot;&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div data-start-index=&quot;2069&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&lt;br /&gt;q_m^{\top} k_n = (R_{\Theta, m}^d W_q x_m)^{\top}(R_{\Theta, n}^d W_k x_n) = x^{\top} W_q \mathbf{R}_{\Theta, n-m}^d W_k x_n&lt;br /&gt;\quad&amp;nbsp;(16)&lt;br /&gt;$$&lt;/p&gt;
&lt;/div&gt;
&lt;div data-start-index=&quot;2069&quot;&gt;&lt;span data-start-index=&quot;2104&quot;&gt;&lt;/span&gt;&lt;span data-start-index=&quot;2239&quot;&gt;이 최종 수식에서 $\mathbf{R_{\Theta, n-m}^d} = (R_{\Theta, m}^d)^{\top}R_{\Theta, n}^d$은 &lt;/span&gt;상대 위치 차이 $n-m$에만 의존하는 회전 행렬&lt;span data-start-index=&quot;2351&quot;&gt;이며, RoPE가 위치 정보를 덧셈이 아닌 곱셈&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($R_{\Theta, m}^d \cdot W_{{q,k}}x_m$)&lt;/span&gt;을 통해 통합함을 명확히 보여준다.&lt;/span&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-start-index=&quot;2439&quot;&gt;이로써 RoPE는 위치 인코딩이 내적 계산에 근본적으로 통합되면서 상대 위치 의존성을 확보하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 소감&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엄밀히 말해 논문은 &lt;i&gt;&quot;Positional Encoding 을 한번 효율적으로 재구성 해보자!&quot;&lt;/i&gt; 라고 아무 근거없이 시도해본격에 가깝다. 그러자 긴 컨텍스트에 대한 처리 능력이 크게 향상된것이다. 저자들이 처음 논문을 쓸 때 부터 이런 효과가 명백히 발생할것이라고 추정한것은 아니라고 생각된다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(논문을 다시 살펴보니 이 점을 언급하고 있다.)&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Although we have proved that our model has favourable property of long-term decay for intern-token products, Section (3.3), which is similar to the existing position encoding mechanisms, our model shows superior performance on long texts than peer models, we have not come up with a faithful explanation. &lt;br /&gt;&lt;br /&gt;우리는 우리 모델이 기존의 위치 인코딩 메커니즘과 유사한 내부 토큰 제품에 대한 장기적 감소의 유리한 특성을 가지고 있음을 증명했지만(3.3절), 우리 모델은 피어 모델보다 긴 텍스트에서 더 우수한 성능을 보여주지만, 우리는 정확한 설명을 내놓지 못했습니다.&lt;/blockquote&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;u&gt;즉, 이 리뷰를 보며 그 상관관계를 이해하지 못한게 정상이다.&lt;/u&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어찌되었든 이는 굉장한 발견이며, 그 효과가 강력하기에 현대 LLM 에서 RoPE는 메이저하게 사용되고 있다. 하지만 이러한 RoPE가 Prefill 시의 GPU 과부하 문제를 해결한것은 아니여서 어마어마한 GPU 동시 부하를 유발하는것은 여전하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, Deep Research를 표방한 매우 많은 리소스를 소모가 허용된 작업에서는 RoPE를 적용하여 `웹검색 + 문서검색 + 사용자 컨텍스트` 등을 모두 합한 뒤 전체 컨텍스트로 모델에 전달하여 처리하고 있을 것이라고 추정한다.&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Artificial Intelligence/Paper Review</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/217</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-ROFORMER-ENHANCED-TRANSFORMER-WITH-ROTARY-POSITION-EMBEDDING#entry217comment</comments>
      <pubDate>Sun, 12 Oct 2025 00:43:10 +0900</pubDate>
    </item>
    <item>
      <title>KV Caching</title>
      <link>https://cypsw.tistory.com/entry/KV-Caching</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글을 통해 많은 사람이 KV Caching을 쉽게 이해할 수 있기를 바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Transformer(Q, K, D)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;906&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cR2kRE/btsQffeF4uq/6aB3DiSSi9Ah0C1lHbx3I1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cR2kRE/btsQffeF4uq/6aB3DiSSi9Ah0C1lHbx3I1/img.png&quot; data-alt=&quot;https://www.researchgate.net/figure/Diagram-of-the-query-key-value-and-self-attention-mechanism-The-input-vectors-x-is_fig4_391696986&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cR2kRE/btsQffeF4uq/6aB3DiSSi9Ah0C1lHbx3I1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcR2kRE%2FbtsQffeF4uq%2F6aB3DiSSi9Ah0C1lHbx3I1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;853&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;906&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://www.researchgate.net/figure/Diagram-of-the-query-key-value-and-self-attention-mechanism-The-input-vectors-x-is_fig4_391696986&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은점만 명심하고 넘어가자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$Q, K ,D$에 곱해지는 입력 $X$ 값은 &lt;span style=&quot;color: #f89009;&quot;&gt;실제로 모두 같은 값&lt;/span&gt;이다.&lt;/li&gt;
&lt;li&gt;$W^Q, W^K, W^V$의 초기값은 &lt;span style=&quot;color: #ee2323;&quot;&gt;'랜덤' 값이다. 특정한 의미를 가지고 있지 않다.&lt;/span&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(다만 학습을 통해 점점 업데이트됨.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;$Q$ 와 $K^T$를 통해 유사도를 계산.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Q: 내가 찾는 정보, K: 제공할 수 있는 정보 = 즉 둘간의 매칭정보)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;$\sqrt{d_k}$로 값이 너무 커지는것을 방지&lt;/li&gt;
&lt;li&gt;$softmax$로 각 토큰에 대한 가중치를 확률분포로 변환.&lt;/li&gt;
&lt;li&gt;$V$와 곱셈하여 최종 출력 생성.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(V: 그래서 뭘 전달할건데? 전달할 실제 정보)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;$Z$는 문맥정보가 통합된 최종 출력 벡터값&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외에도 Transformer 에는 여러가지 레이어들이 같이 들어있기에 엄밀히 말해 위 Attention 구조만으로 Transformer를 모두 설명한다고 볼 수는 없다. 하지만 KV Caching에 대해 이해하기 위해선 위 부분만이 필수적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Transformer의 문제점&lt;/h2&gt;
&lt;p&gt;&lt;video controls=&quot;controls&quot; width=&quot;850&quot; height=&quot;478&quot;&gt;
  &lt;source src=&quot;https://cdn-uploads.huggingface.co/production/uploads/6527e89a8808d80ccff88b7a/PWI-EwqizVLInztmiI7Eo.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Transformer를 기반으로 하는 모델들은 텍스트를 생성할 때 이전 토큰을 모두 검토하여 다음 토큰을 예측한다. 때문에 '이미 알고 있는' 값을 다시 계산하기 위해서 동일한 계산을 반복적으로 수행하게 되고, 이것은 곧 엄청난 리소스 낭비로 직결된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 동영상에서 '!' 라는 값을 출력하기 위해선, Hello의 $Z$값이 필요하기에, 이를 다시 계산 하는 모습을 확인할 수 있다. 하지만 이는 이미 계산해 뒀던 값이고, 저 Hello의 $Z$ 값은 변하지 않는다. 그럼에도 저장해둔 값이 없으니&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(KV Cache)&lt;/span&gt; 이를 다시 계산해야 하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 시간 복잡도를 $O(n^2)$에서 $O(n)$으로 감소 수준으로 감소시킬 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;video controls=&quot;controls&quot; width=&quot;850&quot; height=&quot;478&quot;&gt;
  &lt;source src=&quot;https://cdn-uploads.huggingface.co/production/uploads/6527e89a8808d80ccff88b7a/HnzDhoJdAbJhSassYjzEy.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Deepseek 의 KV Caching 은 뭐가 다른가?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 &lt;a href=&quot;https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-DeepSeek-V3-Technical-Report#2-1.%20Multi-head%20Latent%20Attention-1-2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Deepseek 논문 리뷰&lt;/a&gt;를 참조하면 좋다.&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Artificial Intelligence/Fundamentals</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/216</guid>
      <comments>https://cypsw.tistory.com/entry/KV-Caching#entry216comment</comments>
      <pubDate>Sun, 31 Aug 2025 21:28:36 +0900</pubDate>
    </item>
    <item>
      <title>[리뷰] Ring Attention with Blockwise Transformers for Near-Infinite Context</title>
      <link>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-Ring-Attention-with-Blockwise-Transformers-for-Near-Infinite-Context</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2310.01889&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Ring Attention&lt;/a&gt; 논문에서는 기존 Transformer가 훌륭하지만, 설계적인 문제로 인해 &lt;span style=&quot;color: #ee2323;&quot;&gt;긴 시퀀스 처리 능력이 제한&lt;/span&gt;된다는 사실을 지적한다. 때문에 논문에서는 Blockwise&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(블럭단위)&lt;/span&gt; 연산을 활용하여 긴 시퀀스를 여러 장치에 분산시키는 동시에, &lt;span style=&quot;color: #f89009;&quot;&gt;키-값 블록의 통신을 블록 단위 어텐션 연산과 완전히 중첩시키는 새로운 접근법인 '블록 단위 트랜스포머를 사용한 링 어텐션' 을 제안&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 접근방법은 절대로 근사치 계산에 의존하거나, &lt;span style=&quot;color: #f89009;&quot;&gt;추가적인 통신 및 연산 오버헤드를 발생시키지 않으며, 기존의 memory-efficient Transformers로 달성할 수 있었던 것보다 최대 &lt;/span&gt;'&lt;span style=&quot;color: #f89009;&quot;&gt;장치 수&lt;/span&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(장치를 추가하면 추가할수록 더 긴 시퀀스 처리 가능)&lt;/span&gt;' &lt;span style=&quot;color: #f89009;&quot;&gt;만큼 더 긴 시퀀스의 학습과 추론을 가능&lt;/span&gt;하게 한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;즉, AI 가속기를 여러개 운용할 때 가용할 수 있는 시퀀스의 길이를 크게 증가시키는 기법, Ring Attention을 제안한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Introduce&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 트랜스포머의 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;가장 큰 문제&lt;/b&gt;&lt;/span&gt;는 &lt;span style=&quot;color: #ee2323;&quot;&gt;시퀀스 길이 $^2$&lt;/span&gt; 비례로 메모리 비용을 발생시켜, 더 긴 입력 시퀀스를 활용하기 어렵게 만든다. 즉, 이러한 트랜스포머의 설계적 한계로 인해, 매우 많은 텍스트를 가진 책, 고해상도의 이미지, 긴 비디오, 복잡한 코드 분석등을 현실적으로 '불가능하게' 만들고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 문제를 해결하기 위해 메모리 비용을 줄이기 위한 연구 관심이 급증하고 있다. 한 연구에서는 Self-Attention의 Softmax 행렬을 전체 행렬을 메모리에 직접 생성하지 않고도 계산할 수 있다는 관찰을 활용하여, 근사치 계산 없이 Self-Attention과 FF의 블록 단위 연산을 개발하는 것으로 이어졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 메모리가 줄었음에도 불구하고, 각 계층의 출력을 저장해야 한다는 중대한 문제가 여전히 남아있다. 이는 모든 요소 간의 상호작용&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(n 대 n 상호작용)&lt;/span&gt;을 포함하는 Self-Attention의 고유한 특성 때문이다. 다음 계층의 Self-Attention은 이전 계층의 모든 출력에 접근해야만 한다. 만약 그렇게 하지 못하면 각 시퀀스 요소마다 모든 출력을 다시 계산해야 하므로 계산 비용이 세제곱으로 증가하여 긴 시퀀스에서는 비현실적이 되기 때문이다.&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;기존 Transformer 의 경우 Q, K, V 행렬을 사용한다. 여기서 Q $\times$ K를 통해 어텐션 스코어 행렬을 제작하는데, 만약 입력 시퀀스 크기가 N이라면 스코어 행렬의 크기는 N $\times$ N 이 된다. 따라서 만약 시퀀스 길이가 100,000 이라면 $100,000^{2}$ 이 되는 구조적인 문제가 발생한다. 이는 &lt;a href=&quot;https://techblog-history-younghunjo1.tistory.com/497&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;앎의 공간님의 Attention 포스팅&lt;/a&gt;을 보면 잘 나와있다.&lt;br /&gt;&lt;br /&gt;또한 레이어를 거칠 때 마다, 메모리를 아끼기 위해 출력값을 저장하지 않고 필요할 때마다 다시 계산한다면, 총 계산량이 $O(N^3)$ 이 되는 문제가 발생한다.(그렇다고 다시 저장한다면, 레이어 수 만큼의 추가 저장 메모리가 필요한 것이다.)&lt;br /&gt;&lt;br /&gt;위와같은 딜레마(저장하자니, VRAM 소모량이 급증하고, 저장 안하고 재연산하자니, 시간복잡도가 크게 늘어지는 현상)를 개선하고자 Ring-Attention 을 제안한다.(참고로, Back-propagation은 학습시에만 필요하나, 그냥 KV 만으로도 입력 시퀀스 길이가 수백만에 이르면 VRAM 점유율이 계속 선형적으로 증가한다. 즉 학습, 추론시 모두 문제이다.)&lt;br /&gt;&lt;br /&gt;이러한 문제를 직관적으로 이해하기위해 예시를 들자면, 현재 실제로 ChatGPT 기준 이미지 25장, Gemini 기준 이미지 10장을 초과하여 첨부할 수 없다. 현재로서는 제아무리 비싼 돈을 주더라도 4K 사진 1만장을 단일 임베딩 입력으로 던져주고 '내가 찾는 인물과 동일 인물이 있나?' 라는 질문을 할 수 없다.(물론, LLM 내부적으로 이미지를 분할, 프롬프트를 반복하여 이를 달성할 수 있을지는 모르나, 이는 진정으로 '단일' 임베딩 입력이 아니다.)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1335&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFkCKu/btsO9HjOt2Q/weopmtBsIzYl2oOmb5JOAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFkCKu/btsO9HjOt2Q/weopmtBsIzYl2oOmb5JOAK/img.png&quot; data-alt=&quot;Figure 1: Maximum context length under end- to-end large-scale training on TPUv4-1024. Base- lines are vanilla transformers [37], memory effi- cient transformers [30], and memory efficient at- tention and feedforward (blockwise parallel trans- formers) [23]. Our proposed approach Ring Atten- tion allows training up to device count times longer sequence than baselines and enables the training of sequences that exceed millions in length without making approximations nor adding any overheads to communication and computation.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFkCKu/btsO9HjOt2Q/weopmtBsIzYl2oOmb5JOAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFkCKu%2FbtsO9HjOt2Q%2FweopmtBsIzYl2oOmb5JOAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;454&quot; data-origin-width=&quot;1335&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 1: Maximum context length under end- to-end large-scale training on TPUv4-1024. Base- lines are vanilla transformers [37], memory effi- cient transformers [30], and memory efficient at- tention and feedforward (blockwise parallel trans- formers) [23]. Our proposed approach Ring Atten- tion allows training up to device count times longer sequence than baselines and enables the training of sequences that exceed millions in length without making approximations nor adding any overheads to communication and computation.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 Figure 1은 바닐라 트랜스포머, 메모리 효율적 트랜스포머, 메모리 효율적 어텐션 및 피드포워드&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(&lt;a href=&quot;https://ostin.tistory.com/264&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;블록 단위 병렬 트랜스포머&lt;/a&gt;)&lt;/span&gt; 이다. 저자들이 제안하는 Ring Attention은 '최대 장치 수' 만큼 더 긴 시퀀스의 학습을 가능하게 한다고 주장하고 있으며 그래프 수치가 압도적인 것을 확인해 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 저자들은 실험결과, Ring Attention 을 통해 트랜스포머의 고질적 메모리 요구량을 줄여, 기존의 메모리 효율화 기술보다 500배 이상 더 긴 시퀀스의 학습을 가능하게 했다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(다시한번 강조하지만 이는 '근사치' 등을 통해서 정밀도를 떨어뜨린것이 아니다)&lt;/span&gt; 이를 통해서 길이가 100,000,000을 초과하는 시퀀스의 학습을 가능하게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 이 논문의 핵심적인 내용을 정리하자면 아래와같이 두 가지로 정리할 수 있겠다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;성능을 유지하면서 컨텍스트 길이가 장치 수에 따라 선형적으로 확장되도록 하여, 개별 장치로 인한 메모리 병목 현상을 제거하는 메모리 효율적인 트랜스포머 아키텍처를 제안한것&lt;/li&gt;
&lt;li&gt;위 제안사항의 효과성을 광범위한 실험을 통해 &lt;b&gt;'입증'&lt;/b&gt; 한것.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Large Context Memory Constraint&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 섹션에서는 구체적으로 트랜스포머 모델이 '왜' 긴 시퀀스&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(large context)&lt;/span&gt;를 처리할 때 메모리 문제가 발생하는지 설명한다. 요약하자면 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ \text{Attention} (Q, K, V) = \text{softmax}({QK^T \over \sqrt{d}}) V, $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역시 내 글보다는 &lt;a href=&quot;https://techblog-history-younghunjo1.tistory.com/497&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;앎의 공간&lt;/a&gt;님의 블로그나, &lt;a href=&quot;https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-Attention-Is-All-You-Need&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;내가 쓴 이전 글&lt;/a&gt;들을 참조하는것이 더 좋겠지만, 페이지 이동을 최소화 하기 위해 아주 간단히 요약하면 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Q&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Query)&lt;/span&gt;: 질문 벡터&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(다른 단어들과 Q는 얼마나 관련이 있을까)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;K&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Key)&lt;/span&gt;: 문장 내 모든 단어의 '키' 벡터로서, 각 단어의 특징을 나타내며 Q의 질문에 대답할 준비가 된 값들.&lt;/li&gt;
&lt;li&gt;V&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Value)&lt;/span&gt;: 문장 내 모든 단어의 '값' 벡터로서, 각 단어가 가진 실제 의미나 정보를 담고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 아래와 같은 연산을 진행한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$QK^T$&lt;/span&gt;&lt;/b&gt;: Q와 K를 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;행렬곱&lt;/b&gt;&lt;/span&gt;하여, 현재단어(Q)가 문장 내 다른 모든 단어(K) 들과 얼마나 유사한지 점수를 매긴다.&lt;/li&gt;
&lt;li&gt;$\sqrt{d}$: 계산된 연관도 점수를 특정 값&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($d$, 벡터의 차원)&lt;/span&gt;의 제곱근으로 나누어준다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(그냥 너무 큰 값 넣으면 불안정해 지기에 산정된 약간의 휴리스틱적 방법이다.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;softmax: 다들 아는 softmax 함수이다.&lt;/li&gt;
&lt;li&gt;V: 계산된 어텐션 가중치를 V 행렬과 곱한다. 이를 통해 연관성이 높다고 계산된 단어의 V값은 더 큰 비중으로, 연관성이 낮은 단어의 V 값은 더 낮은 비중으로 반영된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로 이해하면 되겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 Transformer 블록과 ReLU 사이에는 아래와 같은 Feed Forward Network&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(FFN)&lt;/span&gt; 이 삽입된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$FFN(x) = max(0, xW_1 + b_1) W_2 + b_2)$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른거 다 제쳐 두더라도&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;$QK^T$&lt;/span&gt; 부분이 핵심이다. 트랜스포머 성능의 근원이자, 메모리와 계산량중 택일을 강요하는 핵심 요소이다. 이점만 이해해 두면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;종합적으로, 논문에서는 블록 단위 병렬 트랜스포머를 통해서 피드포워드 네트워크의 최대 활성화 크기를 8bsh 에서 2bsh로 4배 줄였지만, 그럼에도 각 레이어의 출력값을 저장해야 하기 때문에 컨텍스트 길이를 확장하는 데에는 여전히 큰 어려움이 따른다고 말한다. 이는 위에서 설명한 n 대 n의 상호작용&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($QK^T$)&lt;/span&gt;을 수행하여야 하는 self-attention 의 본질적인 특성 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 저장된 출력값이 없다면 다음 레이어의 셀프 어텐션은 각 시퀀스 요소에 대해 재계산을 해야 한다. 간단히 예제를 들자면&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;배치크기: 1&lt;/li&gt;
&lt;li&gt;토큰: 100,000,000&lt;/li&gt;
&lt;li&gt;hidden size: 1024&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(참고로 &lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://huggingface.co/docs/transformers/model_doc/qwen3#transformers.Qwen3Config.hidden_size&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;Qwen3 같은 현대적인 Transformer의 경우 기본값이 4096 이다&lt;/span&gt;&lt;/a&gt;. 1024는 매우 보수적인 값이다.)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 경우 1,000GB 이상의 메모리를 필요로 한다. 매우 어마어마한 값이나 &lt;a href=&quot;https://www.nvidia.com/ko-kr/data-center/dgx-b200/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;NVIDIA의 B200&lt;/a&gt;이나, &lt;a href=&quot;https://www.amd.com/ko/products/accelerators/instinct/mi350.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;AMD의 MI350X&lt;/a&gt; 같은 GPU들을 병렬로 연결할 경우 충분히 학습/운용이 가능하지만.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;문서파일 수십개를 추가해서 2억 토큰을 만들면 어떤가?&lt;/li&gt;
&lt;li&gt;아니면 hidden size를 현실적으로 4096 값으로 바꾸면 어떨까?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 한계점이 존재함을 명확히 이해하고 넘어가자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. Ring Attention with Blockwise Parallel Transformers&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Ring-Attention의 기본 아이디어는 위에서 잠깐 언급한 '블록 단위 병렬 트랜스포머&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Blockwise Parallel Transformers, BPT)&lt;/span&gt;를 개선하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 BPT는 Self-Attention, FFN 계산을 블록단위로 수행하여 메모리 사용량을 줄이는 기법인데, Ring-Attention은 여기서 더 나아가 시퀀스 차원을 여러 장치&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(device)&lt;/span&gt;에 분산시켜 연산과 통신을 동시에 처리한다는게 핵심적인 논리이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1477&quot; data-origin-height=&quot;1489&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/edKB5I/btsO9rau0OG/lb2WMrU2jREGYzjwxaS51K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/edKB5I/btsO9rau0OG/lb2WMrU2jREGYzjwxaS51K/img.png&quot; data-alt=&quot;Figure 2: Top (a): We use the same model architecture as the original Transformer but reorganize the compute. In the diagram, we explain this by showing that in a ring of hosts, each host holds one query block, and key-value blocks traverse through a ring of hosts for attention and feedforward computations in a block-by-block fashion. As we compute attention, each host sends key-value blocks to the next host while receives key-value blocks from the preceding host. The communication is overlapped with the computation of blockwise attention and feedforward. Bottom (b): We compute the original Transformer block-by-block. Each host is responsible for one iteration of the query&amp;amp;rsquo;s outer loop, while the key-value blocks rotate among the hosts. As visualized, a device starts with the first query block on the left; then we iterate over the key-value blocks sequence positioned horizontally. The query block, combined with the key-value blocks, are used to compute self-attention (yellow box), whose output is pass to feedforward network (cyan box).&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/edKB5I/btsO9rau0OG/lb2WMrU2jREGYzjwxaS51K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FedKB5I%2FbtsO9rau0OG%2Flb2WMrU2jREGYzjwxaS51K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;806&quot; data-origin-width=&quot;1477&quot; data-origin-height=&quot;1489&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 2: Top (a): We use the same model architecture as the original Transformer but reorganize the compute. In the diagram, we explain this by showing that in a ring of hosts, each host holds one query block, and key-value blocks traverse through a ring of hosts for attention and feedforward computations in a block-by-block fashion. As we compute attention, each host sends key-value blocks to the next host while receives key-value blocks from the preceding host. The communication is overlapped with the computation of blockwise attention and feedforward. Bottom (b): We compute the original Transformer block-by-block. Each host is responsible for one iteration of the query&amp;rsquo;s outer loop, while the key-value blocks rotate among the hosts. As visualized, a device starts with the first query block on the left; then we iterate over the key-value blocks sequence positioned horizontally. The query block, combined with the key-value blocks, are used to compute self-attention (yellow box), whose output is pass to feedforward network (cyan box).&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;번역하자면 설명은 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;(a): 우리는 기존 트랜스포머와 동일한 모델 아키텍처를 사용하지만, 연산 과정을 재구성한다. 이 다이어그램에서는 여러 호스트&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(device)&lt;/span&gt;가 링&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(ring)&lt;/span&gt; 구조를 이루고, 각 호스트는 하나의 쿼리&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(query)&lt;/span&gt; 블록을 가진다. 그리고 키-값&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(key-value)&lt;/span&gt; 블록들이 블록 단위 어텐션 및 피드포워드 연산을 위해 이 링을 순회하는 방식으로 설명한다. 어텐션을 계산하는 동안, 각 호스트는 자신의 키-값 블록을 다음 호스트로 보내는 동시에 이전 호스트로부터 키-값 블록을 받는다. 이 통신 과정은 블록 단위 어텐션 및 피드포워드 연산과 중첩되어 수행된다.&lt;/li&gt;
&lt;li&gt;(b): 우리는 기존 트랜스포머를 블록 단위로 계산한다. 각 호스트는 쿼리의 외부 루프&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(outer loop)&lt;/span&gt; 중 한 번의 반복을 책임지며, 키-값 블록들은 호스트들 사이를 순환한다. 그림에서 볼 수 있듯이, 한 장치는 왼쪽의 첫 번째 쿼리 블록으로 시작하여, 수평으로 배열된 키-값 블록 시퀀스를 순차적으로 처리한다. 이 쿼리 블록과 키-값 블록들은 셀프 어텐션&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(노란색 상자)&lt;/span&gt;을 계산하는 데 사용되며, 그 출력은 피드포워드 네트워크&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(청록색 상자)&lt;/span&gt;로 전달된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는&amp;nbsp;저&amp;nbsp;방식을&amp;nbsp;사용함으로써&amp;nbsp;왜&amp;nbsp;더&amp;nbsp;효율적이&amp;nbsp;되는건지&amp;nbsp;이해하지&amp;nbsp;어려웠다.&amp;nbsp;이를&amp;nbsp;이해하기&amp;nbsp;위해서는&amp;nbsp;기존&amp;nbsp;다중&amp;nbsp;GPU&amp;nbsp;활용&amp;nbsp;방식의&amp;nbsp;한계를&amp;nbsp;이해해야&amp;nbsp;한다.&lt;br /&gt;&lt;br /&gt;기존에는&amp;nbsp;모든&amp;nbsp;모델을&amp;nbsp;GPU에&amp;nbsp;각각&amp;nbsp;복제하고,&amp;nbsp;훈련&amp;nbsp;데이터를&amp;nbsp;나눠서&amp;nbsp;각&amp;nbsp;GPU에&amp;nbsp;할당한&amp;nbsp;뒤,&amp;nbsp;각&amp;nbsp;GPU는&amp;nbsp;자신에게&amp;nbsp;할당된&amp;nbsp;데이터로&amp;nbsp;모델을&amp;nbsp;학습시키고&amp;nbsp;이를&amp;nbsp;통해&amp;nbsp;발생된&amp;nbsp;기울기만&amp;nbsp;서로&amp;nbsp;공유하고&amp;nbsp;평균을&amp;nbsp;내어&amp;nbsp;모든&amp;nbsp;GPU의&amp;nbsp;모델을&amp;nbsp;동일하게&amp;nbsp;업데이트하는&amp;nbsp;'단순&amp;nbsp;무식한'&amp;nbsp;방법을&amp;nbsp;사용했다.&lt;br /&gt;&lt;br /&gt;즉&amp;nbsp;모델을&amp;nbsp;GPU마다&amp;nbsp;복제해서&amp;nbsp;학습하는&amp;nbsp;무식한&amp;nbsp;방법을&amp;nbsp;사용했기에&amp;nbsp;'시간단축'은&amp;nbsp;$\frac{1}{N}$이&amp;nbsp;되어도&amp;nbsp;활성화&amp;nbsp;값으로&amp;nbsp;인한&amp;nbsp;메모리&amp;nbsp;문제는&amp;nbsp;폭발적으로&amp;nbsp;증가한다.&amp;nbsp;또한,&amp;nbsp;GPU를&amp;nbsp;수백만개&amp;nbsp;때려박아도&amp;nbsp;근본적으로&amp;nbsp;단일&amp;nbsp;GPU의&amp;nbsp;메모리&amp;nbsp;용량이&amp;nbsp;처리할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;시퀀스의&amp;nbsp;길이&amp;nbsp;한계를&amp;nbsp;뛰어넘을&amp;nbsp;수&amp;nbsp;없다는&amp;nbsp;치명적인&amp;nbsp;한계를&amp;nbsp;지니고&amp;nbsp;있다는&amp;nbsp;것이다.&lt;br /&gt;&lt;br /&gt;Ring&amp;nbsp;Attention은&amp;nbsp;이&amp;nbsp;점을&amp;nbsp;개선했다.&amp;nbsp;기존에는&amp;nbsp;$N&amp;nbsp;\times&amp;nbsp;N$&amp;nbsp;크기의&amp;nbsp;전체&amp;nbsp;어텐션&amp;nbsp;행렬을&amp;nbsp;계산해야&amp;nbsp;했다면,&amp;nbsp;Ring&amp;nbsp;Attention에서는&amp;nbsp;어떤&amp;nbsp;GPU도&amp;nbsp;전체&amp;nbsp;행렬을&amp;nbsp;한&amp;nbsp;번에&amp;nbsp;계산하지&amp;nbsp;않는다.&amp;nbsp;각&amp;nbsp;GPU는&amp;nbsp;자신이&amp;nbsp;맡은&amp;nbsp;'Q'&amp;nbsp;블록과&amp;nbsp;링을&amp;nbsp;따라&amp;nbsp;순회하며&amp;nbsp;들어오는&amp;nbsp;KV&amp;nbsp;블록&amp;nbsp;사이의&amp;nbsp;작은&amp;nbsp;Attention&amp;nbsp;조각만을&amp;nbsp;계산한다.&lt;br /&gt;&lt;br /&gt;다만&lt;span style=&quot;color: #f89009;&quot;&gt; Ring Attention도 모델 가중치는 여전히 모든 GPU에 복제되므로, 모델 가중치 관련 메모리는 절약되지 않는다.&lt;/span&gt;&amp;nbsp;Ring&amp;nbsp;Attention이&amp;nbsp;절약하는&amp;nbsp;것은&amp;nbsp;시퀀스&amp;nbsp;길이에&amp;nbsp;제곱으로&amp;nbsp;비례하여&amp;nbsp;증가하는&amp;nbsp;활성화&amp;nbsp;값&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(중간&amp;nbsp;계산&amp;nbsp;결과물)&amp;nbsp;&lt;/span&gt;메모리이다.&amp;nbsp;논문에&amp;nbsp;따르면,&amp;nbsp;각&amp;nbsp;GPU의&amp;nbsp;메모리&amp;nbsp;사용량이&amp;nbsp;전체&amp;nbsp;시퀀스&amp;nbsp;길이&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(s)&lt;/span&gt;에&amp;nbsp;의존하지&amp;nbsp;않고&amp;nbsp;고정된&amp;nbsp;블록&amp;nbsp;크기&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(c)&lt;/span&gt;에만&amp;nbsp;비례하게&amp;nbsp;되어,&amp;nbsp;처리&amp;nbsp;가능한&amp;nbsp;컨텍스트&amp;nbsp;길이가&amp;nbsp;장치&amp;nbsp;수에&amp;nbsp;비례하여&amp;nbsp;선형적으로&amp;nbsp;확장된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;또 이 부분을 보고 '엥? 그래봤자 바닐라 트랜스포머가 더 GPU 자원을 잘 쓸거 같은데?' 라고 생각할수도 있겠다.&lt;br /&gt;&lt;br /&gt;하지만 기존 바닐라 트랜스포머는 각 GPU가 자신의 데이터로 학습을 마친 뒤, 다음 단계로 넘어가기 전에 반드시 모든 GPU가 작업을 멈추고, 계산된 기울기(gradient)를 서로 주고받아 평균을 낸 뒤, 모델을 똑같이 업데이트한다.&lt;br /&gt;&lt;br /&gt;이 '기울기 공유' 단계에서는 모든 GPU가 연산을 멈추고 통신이 끝날 때까지 기다려야 한다. 가장 느린 GPU가 통신을 마칠 때까지 나머지 빠른 GPU들은 아무 일도 하지 못하고 대기하게 되는 것이다. GPU 수가 많아질수록 이 통신 시간과 대기 시간(유휴 시간)은 기하급수적으로 늘어나 전체적인 효율을 떨어뜨린다.&lt;br /&gt;&lt;br /&gt;Ring-Attention은 연산 부분과 통신 부분을 '중첩' 시켜 이러한 오버헤드를 극단적으로 감소시킨다. 블록을 연산하는 데 걸리는 시간이 통신하는 데 걸리는 시간보다 길기만 하다면, 통신으로 인한 지연은 사실상 '0'이 된다. GPU는 통신이 끝나기를 기다리며 노는 것이 아니라, 통신이 이루어지는 동안에도 계속해서 다음 연산을 처리하고 있기 때문이다.&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;또한 위 부분을 보고 '엥? KV를 이전 GPU로부터 전달받아야 되잖아. 그럼 이전 GPU의 연산작용으로 인해서 대기하는 기간은 그대로 다음 GPU의 유휴시간으로 직결되어, 까딱 잘못하단 연쇄적인 지연, 혹은 Deadlock이 걸릴수도 있는 위험한 구조인거 같은데... 지연이 '0' 이 되는건 너무 비약적인 해석 아닌가?' 라고 오해할수도 있겠다.&lt;br /&gt;&lt;br /&gt;하지만 위에서 저자들이 수차례 '오버헤드를 추가하지 않으면서...' 라고 언급한 점을 생각해보자, 심지어 우리가 이런 의문을 가질걸 생각해서 논문에서는 이 점 역시 명시하고 있다.&lt;br /&gt;&lt;br /&gt;'... 그러나 내부 루프에서는 다른 호스트로부터 블록을 가져와야 하는 키-값 블록 상호작용을 포함하는 도전 과제가 발생합니다. 호스트(장치)는 단 하나의 키-값(key-value) 블록만 가지고 있기 때문에, 다른 호스트로부터 블록을 가져오는 순진한(단순한) 접근 방식은 두 가지 심각한 문제를 야기합니다. 첫째, 시스템이 필요한 키-값 블록을 수신하기 위해 기다려야 하므로 계산 지연을 유발합니다. 둘째, 키-값 블록이 계속 누적되면 메모리 사용량이 증가하게 되는데, 이는 메모리 비용을 절감하려는 원래의 목적을 무효로 만든다.)'&lt;br /&gt;&lt;br /&gt;이 의문에 대한 해답은 아래 본문에서 살펴보자.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Ring-Based&amp;nbsp;Blockwise&amp;nbsp;Attention.&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 의문점&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(계산 지연 및 메모리 누적)&lt;/span&gt;을 해결하기 위해, 저자들은 내부 루프&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(inner loop)&lt;/span&gt;의 KV 블록 연산이 갖는 순열 불변성&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(permutation invariance)&lt;/span&gt; 속성을 활용한다. 이 속성은, 각 블록의 통계치가 재조정&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(rescaling)&lt;/span&gt;을 위해 올바르게 결합되기만 한다면, 하나의 Q 블록과 여러 KV 블록 그룹 간의 Self-Attention은 어떤 순서로든 계산될 수 있다는 사실에서 비롯된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자들은 이 속성을 모든 호스트&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(device)&lt;/span&gt;가 호스트-1, 호스트-2, ..., 호스트-N의 링 구조를 형성하는 것으로 개념화하여 활용한다. 블록 단위 어텐션과 피드포워드를 계산할 때, 각 호스트는 어텐션 계산에 사용 중인 키-값 블록을 다음 호스트로 보내는 동시에 이전 호스트로부터 키-값 블록을 받으며 효율적으로 협력하고, 이를 통해 블록 전송과 블록 단위 계산을 효과적으로 중첩시킨다. 구체적으로, 임의의 호스트-i는 자신의 Q블록과 KV블록 간의 어텐션을 계산하는 동안, 동시에 다음 호스트-(i+1)로 KV 블록을 보내고 이전 호스트-(i-1)로부터 KV 블록을 받는다. &lt;span style=&quot;color: #f89009;&quot;&gt;만약 계산 시간이 KV 블록을 전송하는 데 필요한 시간을 초과한다면, 이는 추가적인 통신 비용이 없음을 의미&lt;/span&gt;한다. 이러한 중첩 메커니즘은 순전파&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(forward pass)&lt;/span&gt;와 역전파&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(backward pass)&lt;/span&gt; 모두에 적용될 수 있는데, 동일한 연산과 기술이 사용될 수 있기 때문이다. 이전 연구에서도 통신 비용 절감을 목표로 링 토폴로지를 활용하여 셀프 어텐션을 계산하는 방법이 제안된 바 있지만, 저자들의 연구는 &lt;span style=&quot;color: #f89009;&quot;&gt;블록 단위 병렬 트랜스포머를 활용하여 메모리 비용을 대폭 절감한다는 점&lt;/span&gt;에서 차이가 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;또한, 왜 Q는 개별 GPU에 고정시키고, KV만 순회하면서 Ring Attention을 구성하는지 의구심이 들 수 있다.&lt;br /&gt;&lt;br /&gt;Q의 경우 '질의하는 주체' 이고 KV는 '참조되는 대상' 이라는 차이점이 존재한다.&lt;br /&gt;Q는 고정된 위치에서 모든 KV쌍을 참조해야 하고, 최종 출력결과가 저장될 목적지 호스트를 결정해야한다.&lt;br /&gt;KV는 어떤 Query와 결합되더라도 동일한 정보를 제공하며, 때문에 순서와 상관없이 재사용이 가능하다.&lt;br /&gt;&lt;br /&gt;각 호스트가 자신이 출력하는 출력 구간에 대한 책임을 지는 구조이며, 이 때 Q를 이동시키면 출력결과 역시 함께 이동해야 하기 때문에 비효율적으로 구성될 수 밖에 없다. 이런 구조로 인해 Q를 고정시켜서 각 호스트 디바이스에 위치시키는 것이다. 반면 KV의 경우 모든 Query 위치에서 전체 시퀀스 정보에 접근해야 할 수 있어야 하는 점으로 인해 순환하여 배치시키는 방식을 사용하는 것이다.&lt;br /&gt;&lt;br /&gt;이러한 방식은 위에서 말한 'KV블록 연산이 갖는 불변성' 으로 인해 발생한다. (즉 KV 블록의 순서를 바꾸어도 최종 결과가 동일하기에 이런짓이 가능하다)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Arithmetic&amp;nbsp;Intensity&amp;nbsp;Between&amp;nbsp;Hosts.&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 DeadLock 관련되어 위험성을 언급했는데, 저자들의 계산에 따르면 아래 식이 성립할 때 사실상 오버헤드는 제로가 된다고 주장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ \text{계산 시간} \geq \text{통신 시간} $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것을 계산하기 위해서는 아래와 같은 식을 이해해야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Q-K 곱셈: $2dc^2$ FLOPs&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Q블록 $d \times c$와 K블록 $d \times c$의 행렬곱셈$)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Attention-V 곱셈: $2dc^2$ FLOPs&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Attention 가중치 $c \times c$와 V블록 $d \times c$의 곱셈)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;총 계산량: $4dc^2$ FLOPs&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ {4dc&amp;sup2; \over F} \geq {4cd \over B} $$&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$F$: FLOPs&lt;/li&gt;
&lt;li&gt;$B$: Bandwidth&lt;/li&gt;
&lt;li&gt;높은 ${F \over B}$: 계산 대비 통신 대역폭이낮다. &amp;rarr; 따라서 더 큰 블록이 필요하다&lt;/li&gt;
&lt;li&gt;낮은 ${F \over B}$: 통신이 빠르다 &amp;rarr; 작은 블록으로도 중첩이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 내용을 통해 Deadlock 의문점에 대해서 해소할 수 있다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(하지만 만약 학습중 특정 GPU가 죽어버리면 deadlock 이 발생할것으로 추측된다. 물론 바닐라에서도 똑같겠지만...)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 위 원리를 통해 구현된 Ring Attention 과 다른 기법들의 메모리 소모량을 비교하자면 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1063&quot; data-origin-height=&quot;317&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4NQTT/btsPf3Up4Yq/0zMbin5nAKCDyZohhCotl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4NQTT/btsPf3Up4Yq/0zMbin5nAKCDyZohhCotl0/img.png&quot; data-alt=&quot;Table 1: Comparison of maximum activation sizes among different Transformer architectures. Here, b is batch size, h is hidden dimension, n is number of head, s is sequence length, c is block size, the block size (c) is independent of the input sequence length (s). The comparison is between vanilla Transformer [37], memory efficient attention [30], memory efficient attention and feedforward [23], and our proposed approach Ring Attention. Numbers are shown in bytes per layer, assuming bfloat16 precision.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4NQTT/btsPf3Up4Yq/0zMbin5nAKCDyZohhCotl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4NQTT%2FbtsPf3Up4Yq%2F0zMbin5nAKCDyZohhCotl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;239&quot; data-origin-width=&quot;1063&quot; data-origin-height=&quot;317&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Table 1: Comparison of maximum activation sizes among different Transformer architectures. Here, b is batch size, h is hidden dimension, n is number of head, s is sequence length, c is block size, the block size (c) is independent of the input sequence length (s). The comparison is between vanilla Transformer [37], memory efficient attention [30], memory efficient attention and feedforward [23], and our proposed approach Ring Attention. Numbers are shown in bytes per layer, assuming bfloat16 precision.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$b$: 배치 크기&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(batch size)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;$h$: 히든 차원&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(hidden dimension)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;$s$: 시퀀스 길이&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(sequence length)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;$c$: 블록 크기&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(block size)&lt;/span&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vanilla 의 경우 $s^2$ 이라는 무시무시한 메모리 소모량을 보여주며, Memori effcient attention 의 경우 정직하게 $s$를 반영하는 모습을 보여준다. 반면 Ring Attention 식은 $s$가 $c$로 대체되어 있다. 때문에 시퀀스 길이에서 자유롭다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. Results&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;661&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/etKE95/btsPfgmDfXD/n6MfHMznFYlvdixe44Dqmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/etKE95/btsPfgmDfXD/n6MfHMznFYlvdixe44Dqmk/img.png&quot; data-alt=&quot;Table 3: The maximum context length supported in end-to-end training using fully sharded data parallelism and various transformers architectures. We show different model sizes and accelerators. Baselines are vanilla transformer, transformer with memory efficient attention, and trans- former with memory efficient attention and feedforward. The context size is reported in tokens (1e3). Our Ring Attention substantially outperforms baselines and enables training sequences that are up to device count times longer than prior state-of-the-arts.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/etKE95/btsPfgmDfXD/n6MfHMznFYlvdixe44Dqmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FetKE95%2FbtsPfgmDfXD%2Fn6MfHMznFYlvdixe44Dqmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;624&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;661&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Table 3: The maximum context length supported in end-to-end training using fully sharded data parallelism and various transformers architectures. We show different model sizes and accelerators. Baselines are vanilla transformer, transformer with memory efficient attention, and trans- former with memory efficient attention and feedforward. The context size is reported in tokens (1e3). Our Ring Attention substantially outperforms baselines and enables training sequences that are up to device count times longer than prior state-of-the-arts.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 구성된 Ring-Attention 은 이전 Memory Efficient들 보다도 압도적인 수치의 context를 운용할 수 있으며, 장비가 늘어날수록 그 수치는 더 크게 증가함을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rYVJe/btsPfjDFqcH/plx3KCjpUGrHlVAd6ClPtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rYVJe/btsPfjDFqcH/plx3KCjpUGrHlVAd6ClPtK/img.png&quot; data-alt=&quot;Table 4: Model flops utilization (MFU) with different training configurations: model sizes, compute, and context lengths. Ring Attention enables training large models (7B-65B) on large input context sizes (over 4M) with negligible overheads.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rYVJe/btsPfjDFqcH/plx3KCjpUGrHlVAd6ClPtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrYVJe%2FbtsPfjDFqcH%2Fplx3KCjpUGrHlVAd6ClPtK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;501&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Table 4: Model flops utilization (MFU) with different training configurations: model sizes, compute, and context lengths. Ring Attention enables training large models (7B-65B) on large input context sizes (over 4M) with negligible overheads.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MFU란 GPU나 TPU 등의 AI 가속기가 얼마나 효율적으로 활용되고 있는지를 백분율로 나타내는 지표다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(처음 보는 단어라서 찾아봤다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 오버헤드 수치를 파악할 수 있는것인데, 저자들이 호언장담한 것 처럼 '완벽히' 오버헤드가 없는 수준은 아니다. 하지만 미미한 수준으로서 단점보다 장점이 압도적으로 크므로 이 점을 알고 넘어가면 되겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 의의.&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 돈만 때려박으면 매우 큰 컨텍스트 운영이 가능해졌다. 예로 정보기관에서 테러위협을 막기 위해 전세계 1년치 SNS 데이터를 입력값으로 잠재적인 위험을 파악하거나. 80세 할아버지가 가진 100만장의 사진중에서 특정 이미지를 LLM을 통해 찾아낼 수 있게 된 것이다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(물론, LLM의 경우 컨텍스트가 길어지면 답변저하 문제가 따르기에. 완전한 일반화가 될 수는 없다)&lt;/span&gt;.&lt;/p&gt;</description>
      <category>Artificial Intelligence/Paper Review</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/215</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-Ring-Attention-with-Blockwise-Transformers-for-Near-Infinite-Context#entry215comment</comments>
      <pubDate>Sat, 12 Jul 2025 21:15:43 +0900</pubDate>
    </item>
    <item>
      <title>[리뷰] World Models</title>
      <link>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-World-Models</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문 &lt;a href=&quot;https://arxiv.org/abs/1803.10122&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;World Models&lt;/a&gt;은 현재 기준으로 7년이 지나 AI 업계에서는 꽤나 오래된 논문이지만, Transformer 이후 AGI로 나아가야될 방향을 제시하고 있는 논문이기에 리뷰한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;David Ha와 J&amp;uuml;rgen Schmidhuber가 제시한 강화학습 분야의 혁신적인 연구로, &lt;span style=&quot;color: #f89009;&quot;&gt;인간의 정신 모델과 유사한 방식으로 환경을 이해하고 행동하는 AI 에이전트를 구축하는 방법을 제시&lt;/span&gt;한다. 이 논문은 환경의 압축된 시공간 표현을 학습하는 생성 신경망 모델을 통해 복잡한 강화학습 문제를 해결하는 새로운 패러다임을 제안하는 논문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Introduce&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인간은&amp;nbsp;제한된&amp;nbsp;감각으로&amp;nbsp;인지할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;것을&amp;nbsp;바탕으로&amp;nbsp;세상에&amp;nbsp;대한&amp;nbsp;정신&amp;nbsp;모델&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(mental&amp;nbsp;model)&lt;/span&gt;을 발달시켰다. 우리가 내리는 결정과 행동은 이 내적 모델에 기반한다. 시스템 동역학&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(system dynamics)&lt;/span&gt;의 아버지인 제이 라이트 포레스터&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Jay Wright Forrester)&lt;/span&gt;는 정신 모델을 아래와 설명했다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;우리 머릿속에 가지고 다니는 우리 주변 세계의 이미지는 단지 모델일 뿐이다. 누구도 머릿속으로 전 세계, 정부, 또는 국가 전체를 상상하지 않는다. 그는 단지 선택된 개념들과 그들 사이의 관계만을 가지고 있으며, 이를 실제 시스템을 표현하는 데 사용한다. (Forrester, 1971)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 인간이라도 모든 내용을 기억하고 있지 않으며, 선택된 일부의 개념과 관계를 통해서 현실을 표현한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;373&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VrTqB/btsOG13PXzE/48t896wHSnLbh8UXJftMfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VrTqB/btsOG13PXzE/48t896wHSnLbh8UXJftMfk/img.png&quot; data-alt=&quot;Figure 1. A World Model, from Scott McCloud&amp;amp;rsquo;s Understanding Comics. (McCloud, 1993; E, 2012)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VrTqB/btsOG13PXzE/48t896wHSnLbh8UXJftMfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVrTqB%2FbtsOG13PXzE%2F48t896wHSnLbh8UXJftMfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;373&quot; height=&quot;288&quot; data-origin-width=&quot;373&quot; data-origin-height=&quot;288&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 1. A World Model, from Scott McCloud&amp;rsquo;s Understanding Comics. (McCloud, 1993; E, 2012)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문에서는 '야구'를 예로 들어서 이러한 과정에 부연설명을 덧댄다.&amp;nbsp;타자는 배트를 어떻게 휘둘러야 할지 밀리초&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(milliseconds)&lt;/span&gt; 단위로 결정해야 하는데, 이는 시각 신호가 뇌에 도달하는 시간보다 짧다. 우리가 시속 100마일의 강속구를 칠 수 있는 이유는 &lt;span style=&quot;color: #f89009;&quot;&gt;공이 언제 어디로 갈지 본능적으로 예측하는 능력 덕분&lt;/span&gt;이다. 프로 선수의 경우 이 모든 것이 잠재의식적으로 일어난다. 그들의 근육은 내적 모델의 예측에 따라 적절한 시간과 위치에서 반사적으로 배트를 휘두른다. 그들은 가능한 미래 시나리오를 의식적으로 펼쳐보며 계획을 세울 필요 없이, 미래에 대한 예측에 따라 신속하게 행동할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 강화학습&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Reinforcement Learning, RL)&lt;/span&gt; 문제에서, 인공 에이전트 또한 과거와 &lt;span style=&quot;color: #f89009;&quot;&gt;현재 상태에 대한 좋은 표현과 미래에 대한 좋은 예측 모델을 가질 때 이점을 얻는다.&lt;/span&gt; 특히 순환 신경망&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Recurrent Neural Network, RNN)&lt;/span&gt;과 같은 범용 컴퓨터에 구현된 강력한 예측 모델이 선호된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더불어, 시기가 시기인 만큼 RNN 모델을 사용하고자 함을 명시하고 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;이상적으로는, 우리는 대규모 RNN 기반 에이전트를 효율적으로 훈련시키고 싶다. 역전파 알고리즘(backpropagation algorithm)은 대규모 신경망을 효율적으로 훈련시키는 데 사용될 수 있다. 본 연구에서는 에이전트를 대규모 월드 모델(world model)과 소규모 제어기 모델(controller model)로 분리하여 RL 작업을 해결하기 위해 대규모 신경망을 훈련시키는 방법을 살펴본다. 먼저 대규모 신경망을 비지도(unsupervised) 방식으로 훈련하여 에이전트 세계의 모델을 학습시킨 다음, 이 월드 모델을 사용하여 작업을 수행하도록 더 작은 제어기 모델을 훈련한다. 작은 제어기는 훈련 알고리즘이 작은 탐색 공간에서 신용 할당 문제에 집중할 수 있게 해주며, 동시에 더 큰 월드 모델을 통해 용량과 표현력을 희생하지 않도록 한다. 우리는 에이전트를 월드 모델의 렌즈를 통해 훈련함으로써, 작업을 수행하기 위한 매우 압축된 정책을 학습할 수 있음을 보여준다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 논문의 목표는 &lt;span style=&quot;color: #f89009;&quot;&gt;RNN 기반 월드 모델과 제어기의 조합에 대한 1990년부터 2015년까지의 일련의 논문들에서 나온 여러 핵심 개념을 추출하는 것&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Agent Model&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;584&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wcIIR/btsOGUqa7aB/koQx6xj9W7aOQetKe3pXt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wcIIR/btsOGUqa7aB/koQx6xj9W7aOQetKe3pXt0/img.png&quot; data-alt=&quot;Figure 4. Our agent consists of three components that work closely together: Vision (V), Memory (M), and Controller (C)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wcIIR/btsOGUqa7aB/koQx6xj9W7aOQetKe3pXt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwcIIR%2FbtsOGUqa7aB%2FkoQx6xj9W7aOQetKe3pXt0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;523&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;584&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 4. Our agent consists of three components that work closely together: Vision (V), Memory (M), and Controller (C)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;World 모델의 핵심을 위 그림이 나타내고 있다. Vision, Memory, Controller로 구성되어 있는데, 간단히 설명하자면 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;V&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Vision)&lt;/span&gt;: 압축&lt;br /&gt;Agent가 보는 복잡하고 용량이 큰 시각 정보&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(e.g: 게임 화면)&lt;/span&gt;를 VAE&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Variational Autoencoder)&lt;/span&gt;라는 기술을 사용해 저차원의 핵심 데이터&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(latent vector z)&lt;/span&gt;로 압축한다. 즉, 현실의 모든 디테일이 아닌, 중요한 특징만 추출하는 역할을 한다.&lt;/li&gt;
&lt;li&gt;M&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Memory)&lt;/span&gt;: 예측 &lt;br /&gt;압축된 현재 상태&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(z)&lt;/span&gt;와 에이전트가 하려는 행동&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(action)&lt;/span&gt;을 입력받아, 그 결과로 나타날 다음 상태를 예측한다 . 이 모델은 RNN을 사용하여 시간의 흐름에 따른 변화를 학습한다. 이것이 바로 AI의 '상상력' 또는 '내부 시뮬레이션'에 해당하는 부분이다.&lt;/li&gt;
&lt;li&gt;C&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Controller)&lt;/span&gt;: 결정&lt;br /&gt;Memory 가 상상해낸 여러 미래 예측 결과를 보고, 가장 좋은 보상을 얻을 수 있는 최적의 행동을 결정하는 아주 작고 단순한 제어 장치이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문에서는 각 부분을 섹션으로 나눠 설명하고 있지만... AI를 공부하고 있다면 Vision, RNN, Controller 모두 익히 알고 있을것이므로 아래에서 개별 요소에 대해 간단하게 짚고 넘어간다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-1 Vision&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1131&quot; data-origin-height=&quot;386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cefK2w/btsOGM0bUDb/PC9JsKc6IZyrJm5uKtSDqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cefK2w/btsOGM0bUDb/PC9JsKc6IZyrJm5uKtSDqk/img.png&quot; data-alt=&quot;Figure 5. Flow diagram of a Variational Autoencoder (VAE).&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cefK2w/btsOGM0bUDb/PC9JsKc6IZyrJm5uKtSDqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcefK2w%2FbtsOGM0bUDb%2FPC9JsKc6IZyrJm5uKtSDqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;273&quot; data-origin-width=&quot;1131&quot; data-origin-height=&quot;386&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 5. Flow diagram of a Variational Autoencoder (VAE).&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;다들 익히 아는 구조로서, 부연설명이 필요하지 않다고 사료된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-2 &amp;nbsp;MDN-RNN Model&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;591&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fp3qv/btsOHcjHj9L/kAcbQdIuZwstHBOm0TMgJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fp3qv/btsOHcjHj9L/kAcbQdIuZwstHBOm0TMgJk/img.png&quot; data-alt=&quot;Figure 6. RNN with a Mixture Density Network output layer. The MDN outputs the parameters of a mixture of Gaussian distribution used to sample a prediction of the next latent vector z.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fp3qv/btsOHcjHj9L/kAcbQdIuZwstHBOm0TMgJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFp3qv%2FbtsOHcjHj9L%2FkAcbQdIuZwstHBOm0TMgJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;504&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;591&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 6. RNN with a Mixture Density Network output layer. The MDN outputs the parameters of a mixture of Gaussian distribution used to sample a prediction of the next latent vector z.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;M 모델은 V모델이 생성할 것으로 예상되는 미래 z 벡터의 예측 모델 역할을 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다만 일반적인 RNN과는 다르게 MDN&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Mixture Density Network)&lt;/span&gt; 라는 단어가 눈에 띄이는데, 일반적인 RNN의 경우 명확히 다음 상태가 어떤 것이다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(예로 apple 이라는 단어)&lt;/span&gt; 라고 추측한다면, MDN-RNN의 경우 '여러 가능한 다음 상태의 확률적 묶음'을 예측한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;2.3. Controller Model&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Controller&lt;span&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(C)&lt;/span&gt; 모델은 에이전트의 예상 누적 보상을 최대화하기 위해 취해야 할 행동의 방향을 결정하는 역할을 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;논문에선 간단한 수식으로 C의 역할을 설명하고 있다. $C$는 $z_t$와 $h_t$를 각 시간 단계에서 행동으로 매핑하는 간단한 단층 선형 모델이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;$$a_t = W_c[z_t \; h_t] + b_c$$&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 선형 모델에서 $W_c$와 $b_c$는 연결된 입력 벡터 $[z_t \; h_t]$를 출력 동작 벡터로 매핑하는 가중치 행렬과 바이어스 벡터이다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(다들 익히 알고있는 퍼셉트론 '그' 수식의 확장판 이다.)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;추가적인 설명은 필요하지 않으리라 생각한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;2.4.&amp;nbsp;Putting&amp;nbsp;V,&amp;nbsp;M,&amp;nbsp;and&amp;nbsp;C&amp;nbsp;Together&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;해당 논문에서 가장 중요한 부분이 2.4 라고 생각한다.&amp;nbsp;&lt;/span&gt;&lt;span&gt;2.4 부분은 위의 간단한 V, M, C가 어떻게 상호작동하는지 알려준다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;469&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pZaF7/btsOMSkyJMB/kJDOdveepNjxKZbgMKN741/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pZaF7/btsOMSkyJMB/kJDOdveepNjxKZbgMKN741/img.png&quot; data-alt=&quot;Figure 8. Flow diagram of our Agent model. The raw observation is first processed by V at each time step t to produce $z_t$. The input into C is this latent vector $z_t$ concatenated with M's hidden state $h_t$ at each time step. C will then output an action vector $a_t$ for motor control, and will affect the environment. M will then take the current $z_t$ and action $a_t$ as an input to update its own hidden state to produce $h_{t+1}$ to be used at time t + 1.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pZaF7/btsOMSkyJMB/kJDOdveepNjxKZbgMKN741/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpZaF7%2FbtsOMSkyJMB%2FkJDOdveepNjxKZbgMKN741%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;407&quot; data-origin-width=&quot;469&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 8. Flow diagram of our Agent model. The raw observation is first processed by V at each time step t to produce $z_t$. The input into C is this latent vector $z_t$ concatenated with M's hidden state $h_t$ at each time step. C will then output an action vector $a_t$ for motor control, and will affect the environment. M will then take the current $z_t$ and action $a_t$ as an input to update its own hidden state to produce $h_{t+1}$ to be used at time t + 1.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Figure 8 내용을 번역하면 아래와 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;에이전트 모델의 순서도이다. 원본 관측값은 매 타임스텝 $t$마다 V에 의해 먼저 처리되어 $z_t$를 생성한다. C의 입력은 이 잠재 벡터 $z_t$와 M의 은닉 상태 $h_t$를 각 타임스텝에서 연결(concatenate)한 것이다. 그러면 C는 모터 제어를 위한 행동 벡터 $a_t$를 출력하고, 이는 환경에 영향을 미친다. 그런 다음 M은 현재의 $z_t$와 행동 $a_t$를 입력으로 받아 자신의 은닉 상태를 업데이트하여 타임스텝 $t$+1에서 사용될 $h_t+1$을 생성한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림과 설명은 World Model이 어떻게 동작하는지 잘 설명되어 있다. 아마 대부분 직관적으로 이해하기 어렵지 않을것이라 생각된다. 간단하게 설명하자면 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;VAE: 이미지 압축 역할만 수행하며 추가적인 학습을 진행하지 않는다&lt;/li&gt;
&lt;li&gt;MDN-RNN: $z_t$ 벡터들을 통해 MDN-RNN을 학습시킨다. 이 때 $c$로 다음 예측값 $h_t$를 전달하고, $c$로부터 행동값을 다시 입력받아 또다시 다음 $h_{t+1}$을 전달하는 방식으로 학습한다.&lt;/li&gt;
&lt;li&gt;C: $z$와 $h$를 통해 학습한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1750510550137&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def rollout(controller):
    &amp;rsquo;&amp;rsquo;&amp;rsquo; env, rnn, vae are &amp;rsquo;&amp;rsquo;&amp;rsquo;
    &amp;rsquo;&amp;rsquo;&amp;rsquo; global variables &amp;rsquo;&amp;rsquo;&amp;rsquo;
    obs = env.reset()
    h = rnn.initial_state()
    done = False
    cumulative_reward = 0
    while not done:
        z = vae.encode(obs) # 인코더를 거쳐 나온 z
        a = controller.action([z, h]) # z 와 h를 통해 a 값 도출
        obs, reward, done = env.step(a) # a 결과에 따라 환경값, 보상값을 업데이트
        cumulative_reward += reward # 보상값 갱신
        h = rnn.forward([a, z, h]) # RNN-MDN 추론
    return cumulative_reward # 반복함수 종료시 계산된 보상값 리턴&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 테스트&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6UCf8/btsOMme97Ga/Lmc8Pcrt7NwgsD3KbZK1Vk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6UCf8/btsOMme97Ga/Lmc8Pcrt7NwgsD3KbZK1Vk/img.png&quot; data-alt=&quot;Figure 9. Our agent learning to navigate in CarRacing-v0.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6UCf8/btsOMme97Ga/Lmc8Pcrt7NwgsD3KbZK1Vk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6UCf8%2FbtsOMme97Ga%2FLmc8Pcrt7NwgsD3KbZK1Vk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;528&quot; height=&quot;384&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 9. Our agent learning to navigate in CarRacing-v0.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문에서는 간단한 카레이싱 테스트를 통해 이러한 모델을 테스트하려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vQpIa/btsOMnFb88H/UloDbLlHKpkIEU5A5nL681/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vQpIa/btsOMnFb88H/UloDbLlHKpkIEU5A5nL681/img.png&quot; data-alt=&quot;파라미터 수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vQpIa/btsOMnFb88H/UloDbLlHKpkIEU5A5nL681/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvQpIa%2FbtsOMnFb88H%2FUloDbLlHKpkIEU5A5nL681%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;452&quot; height=&quot;160&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;160&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;파라미터 수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파라미터 수를 보면 VAE모델이 이미지 처리를 위해 압도적으로 많은 파라미터 수를 차지하고 있다. 현재 Transformer 모델 LLM들의 파라미터수를 보면 MDN-RNN의 파라미터는 정말 귀여운 수준이다. 또한 Controller는 수행해야 하는 역할이 왼쪽/오른쪽 조향, 가속, 브레이크의 동작 4가지이므로 매우 적은 파라미터를 보유하고 있음을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-origin-width=&quot;528&quot; data-origin-height=&quot;384&quot; data-is-animation=&quot;false&quot; data-ke-size=&quot;size16&quot;&gt;그 이후, 논문에서는 VAE 부분에 대해 짚고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;348&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWPpvr/btsOLhzg978/KQOrvTKraA3hlqMSlgA1S1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWPpvr/btsOLhzg978/KQOrvTKraA3hlqMSlgA1S1/img.png&quot; data-alt=&quot;Figure 10. Despite losing details during this lossy compression process, latent vector z captures the essence of each image frame.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWPpvr/btsOLhzg978/KQOrvTKraA3hlqMSlgA1S1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWPpvr%2FbtsOLhzg978%2FKQOrvTKraA3hlqMSlgA1S1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;348&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;348&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 10. Despite losing details during this lossy compression process, latent vector z captures the essence of each image frame.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VAE로 압축하며 세부적인 부분이 손실되나, latent vector $z$는 이미지 프레임의 본질을 포착하기에, 사용하는데 전혀 지장이 없음을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 &lt;a href=&quot;https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-World-Models#2.4.%C2%A0Putting%C2%A0V%2C%C2%A0M%2C%C2%A0and%C2%A0C%C2%A0Together-1-5&quot;&gt;Figure 8&lt;/a&gt; 부분을 보면 사실 해당 구조에서 RNN 부분을 제외하고 VAE 와 Controller 만 유지하더라도 '돌아는 간다' 라는 점을 알 수 있다. 때문에 연구진들은 실제로 RNN을 제외하여 테스트를 수행해 봤다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;470&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bk5Tuh/btsOLjDSc3m/LCn0y9TEkCTYeWaEAxZAKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bk5Tuh/btsOLjDSc3m/LCn0y9TEkCTYeWaEAxZAKk/img.png&quot; data-alt=&quot;Figure 11. Limiting our controller to see only $z_t$, but not $h_t$ results in wobbly and unstable driving behaviours&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bk5Tuh/btsOLjDSc3m/LCn0y9TEkCTYeWaEAxZAKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbk5Tuh%2FbtsOLjDSc3m%2FLCn0y9TEkCTYeWaEAxZAKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;434&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;470&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 11. Limiting our controller to see only $z_t$, but not $h_t$ results in wobbly and unstable driving behaviours&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 결과 위처럼 흔들림과 불안정한 주행동작이 발생한다. 미래를 예측하는 능력을 삭제하고, 현재를 기준으로 컨트롤만 진행하게 하니 안정성이 크게 저하된것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;465&quot; data-origin-height=&quot;334&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ebKe8d/btsOKzHb07p/in2UwQtJPWTDW4T9G7Rla0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ebKe8d/btsOKzHb07p/in2UwQtJPWTDW4T9G7Rla0/img.png&quot; data-alt=&quot;Figure 12. Driving is more stable if we give our controller access to both $z_t$ and $h_t$.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ebKe8d/btsOKzHb07p/in2UwQtJPWTDW4T9G7Rla0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FebKe8d%2FbtsOKzHb07p%2Fin2UwQtJPWTDW4T9G7Rla0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;431&quot; data-origin-width=&quot;465&quot; data-origin-height=&quot;334&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 12. Driving is more stable if we give our controller access to both $z_t$ and $h_t$.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 M, RNN 모델을 투입시켜 미래예측을 가능하게 함으로서 $h_t$ 값을 Controller 에게 전달하니 그 주행능력이 비약적으로 상승하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 결론&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;539&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4LIg8/btsONbYxbgp/0gA4CKhLoUFjC8KEr16Go1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4LIg8/btsONbYxbgp/0gA4CKhLoUFjC8KEr16Go1/img.png&quot; data-alt=&quot;able 1. CarRacing-v0 scores achieved using various methods.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4LIg8/btsONbYxbgp/0gA4CKhLoUFjC8KEr16Go1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4LIg8%2FbtsONbYxbgp%2F0gA4CKhLoUFjC8KEr16Go1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;539&quot; height=&quot;216&quot; data-origin-width=&quot;539&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;able 1. CarRacing-v0 scores achieved using various methods.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 표를 살펴보면 V Model 만 사용하는것 보다 RNN 모델을 결합하여 World 모델을 완성하여 작동시킴이 가장 높은 성능을 낼 수 있다는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외에도 논문에서는 Doom을 World 모델로 구동시키는 등 여러가지 테스트를 수행하므로, 관심있게 분석하고 싶다면 원본 논문을 보는것이 좋겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 의의&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 World Model 과 Reinforcement Model 의 가장 큰 차이점이라고 한다면, 강화학습은 '해당 시간' 에 어떤 행동을 취해야 최대의 보상값을 획득할 수 있는지 학습하는것이라면, World 모델의 경우 '인공지능이 상상을 통해 내 행동으로 인해 세상&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(환경)&lt;/span&gt;이 어떻게 변화하고, 그 변화한 세상에서 내가 어떤 행동을 취해야 지속적으로 높은 보상을 취득할 수 있지?' 를 학습하는 모델이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 등장한 모델인 만큼 과거에는 RNN을 사용하였지만, 현재는 Transformer를 사용하는 것으로 들었다. 아마 후속 논문들의 경우는 RNN에 비해 매우 빠르고 높은 가용량의 파라미터를 운용할 수 있을것으로 추정되지만, 그 근본이 RNN 모델과 크게 다르지 않은 구조이므로, 개인적으로 공부는 진행해도 추가 포스팅을 쓰진 않을것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더불어, 아래와 같은 모델들이 World 모델의 자식들이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;OpenAI의 SORA&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Google의 Genie 2&lt;/li&gt;
&lt;li&gt;Tesla의 자율주행&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 테스트한 부분을 보면 알겠지만, World 모델의 학습은 &lt;span style=&quot;color: #f89009;&quot;&gt;가상 환경속에서 무제한의 학습이 가능&lt;/span&gt;하다. 실제 테슬라도 이러한 방법을 &lt;a href=&quot;https://contents.premium.naver.com/banya/banyacompany/contents/230711154906605gh&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;사용&lt;/a&gt;하고 있는것으로 확인된다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(물론, 가상환경에서의 학습 결과를 실제 현실세계로 온전히 반영하는것은 꽤나 어려울 것으로 추정된다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로, 꽤나 흥미로운 로직을 지니고 있다. 현재 LLM들이 긍정편향, 할루시네이션 등등 많은 문제들을 보여주며 정체되어 가고 있는 분위기인데, World 모델이 돌파구가 될 수 있다고 생각한다.&lt;/p&gt;</description>
      <category>Artificial Intelligence/Paper Review</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/214</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-World-Models#entry214comment</comments>
      <pubDate>Sat, 21 Jun 2025 22:40:59 +0900</pubDate>
    </item>
    <item>
      <title>BPFDoor의 원리와 구현</title>
      <link>https://cypsw.tistory.com/entry/BPFDoor%EC%9D%98-%EC%9B%90%EB%A6%AC%EC%99%80-%EA%B5%AC%ED%98%84</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;BPFDoor는 Attacker에게 패킷을 받아, Target 시스템 내부를 공격 할 수 있는 방법이다. 하지만 미리 Target 시스템에 Door 역할을 수행할 프로그램을 심어두는 사전 조건이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법을 통해서 Port listen을 숨길 수 있으며, OSI 3-4계층에서 작동하는 방화벽을 무시할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SKT 해킹사태가 바로 BPFDoor로 야기된 사건으로서, 이번 포스팅에서 BPFDoor의 원리와 구현 방식에 대해서 설명한다.&lt;/p&gt;
&lt;figure id=&quot;og_1745726443898&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;SKT 해킹에 中해커 주특기 백도어 악성코드&amp;hellip;&amp;quot;주체 단정 어려워&amp;quot; | 연합뉴스&quot; data-og-description=&quot;(서울=연합뉴스) 조성미 기자 = SK텔레콤[017670]의 가입자 유심(USIM) 정보를 탈취한 사이버 공격에서 중국 해커 그룹이 주로 사용하...&quot; data-og-host=&quot;www.yna.co.kr&quot; data-og-source-url=&quot;https://www.yna.co.kr/view/AKR20250424055300017&quot; data-og-url=&quot;https://www.yna.co.kr/view/AKR20250424055300017&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bIssDk/hyYMR9MeuQ/ZWS4G7b8nxajs3S6zRcFN1/img.jpg?width=680&amp;amp;height=434&amp;amp;face=0_0_680_434,https://scrap.kakaocdn.net/dn/du8gnR/hyYMgB4vQj/g0w5XKf3BFDZAlSX1IM711/img.jpg?width=680&amp;amp;height=434&amp;amp;face=0_0_680_434,https://scrap.kakaocdn.net/dn/zPYga/hyYFEq9xEm/AxogYT8YWV1L4igtnX6kt0/img.jpg?width=680&amp;amp;height=434&amp;amp;face=0_0_680_434&quot;&gt;&lt;a href=&quot;https://www.yna.co.kr/view/AKR20250424055300017&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.yna.co.kr/view/AKR20250424055300017&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bIssDk/hyYMR9MeuQ/ZWS4G7b8nxajs3S6zRcFN1/img.jpg?width=680&amp;amp;height=434&amp;amp;face=0_0_680_434,https://scrap.kakaocdn.net/dn/du8gnR/hyYMgB4vQj/g0w5XKf3BFDZAlSX1IM711/img.jpg?width=680&amp;amp;height=434&amp;amp;face=0_0_680_434,https://scrap.kakaocdn.net/dn/zPYga/hyYFEq9xEm/AxogYT8YWV1L4igtnX6kt0/img.jpg?width=680&amp;amp;height=434&amp;amp;face=0_0_680_434');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;SKT 해킹에 中해커 주특기 백도어 악성코드&amp;hellip;&quot;주체 단정 어려워&quot; | 연합뉴스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;(서울=연합뉴스) 조성미 기자 = SK텔레콤[017670]의 가입자 유심(USIM) 정보를 탈취한 사이버 공격에서 중국 해커 그룹이 주로 사용하...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.yna.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실습과정을 위해서 아래와 같은 준비 과정이 필요하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Target&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(아래 중 택1)&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Scapy&lt;/li&gt;
&lt;li&gt;C++ Build&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Attacker&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(단일 옵션)&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Python Build + Scapy&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Debian 계열 OS에서 실험했으며, Target 옵션중 어떤것을 사용해도 무방하지만 굳이 C++을 추가한 이유는 내부적으로 어떻게 동작하는지 이해를 돕기 위함이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실습&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Target System&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://scapy.net/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Scapy&lt;/a&gt;는 &lt;span&gt;사용자가 패킷을 전송하고 스니핑 하고 분석하고 조작할 수 있게 해주는 &lt;/span&gt;&lt;span&gt;파이썬 프로그램으로서 &lt;a href=&quot;https://scapy.readthedocs.io/en/latest/usage.html#filters&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;BPF 필터&lt;/a&gt;를 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;text-align: right;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;Scapy&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1745763741416&quot; class=&quot;python&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;sniff(filter=&quot;tcp and port 9090&quot;, prn=lambda x: print(f&quot;{x[IP].src}:{x[TCP].sport} -&amp;gt; {x[IP].dst}:{x[TCP].dport}  {x[TCP].flags} : {x.getlayer(Raw).load if x.haslayer(Raw) else ''}&quot;))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C++을 통해 실제 Socket을 열고 2계층에서 데이터를 수신받아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 본래 BPFDoor는 커널단에서 동작하므로 프로세스에 감지되지 않는지만, 해당 실습에서 구축한 BPF Door는 프로세스단에서 감지된다는 차이점이 있다.&lt;/p&gt;
&lt;h4 style=&quot;text-align: right;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;C++ Build&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1745755764436&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;cstring&amp;gt;       // For memcpy, memset
#include &amp;lt;csignal&amp;gt;       // For signal handling (Ctrl+C)
#include &amp;lt;iomanip&amp;gt;       // For std::hex, std::setw, std::setfill

// Linux/POSIX Headers
#include &amp;lt;unistd.h&amp;gt;      // For close()
#include &amp;lt;sys/socket.h&amp;gt;  // For socket(), recvfrom()
#include &amp;lt;netinet/in.h&amp;gt;  // For IPPROTO_TCP, IPPROTO_UDP, etc., sockaddr_in
#include &amp;lt;netinet/ip.h&amp;gt;  // For struct iphdr (use iphdr instead of ip)
#include &amp;lt;netinet/tcp.h&amp;gt; // For struct tcphdr
#include &amp;lt;netinet/udp.h&amp;gt; // For struct udphdr
#include &amp;lt;netinet/if_ether.h&amp;gt; // For ETH_P_IP, struct ethhdr
#include &amp;lt;arpa/inet.h&amp;gt;   // For inet_ntoa(), htons(), ntohs()

// Global flag for signal handling (graceful shutdown)
volatile sig_atomic_t stop_capture = 0;

void signalHandler(int signum) {
    (void)signum; // Unused parameter
    std::cout &amp;lt;&amp;lt; &quot;\nInterrupt signal received. Stopping capture...&quot; &amp;lt;&amp;lt; std::endl;
    stop_capture = 1;
}

// Helper function to print payload data in hex and ASCII
void printPayload(const unsigned char* payload, int len) {
    if (len &amp;lt;= 0) {
        std::cout &amp;lt;&amp;lt; &quot; [No Payload Data]&quot; &amp;lt;&amp;lt; std::endl;
        return;
    }

    std::cout &amp;lt;&amp;lt; &quot; [Payload Data (&quot; &amp;lt;&amp;lt; len &amp;lt;&amp;lt; &quot; bytes)]:&quot; &amp;lt;&amp;lt; std::endl;
    const int bytes_per_line = 16;

    for (int i = 0; i &amp;lt; len; i += bytes_per_line) {
        // Print Hex offset
        std::cout &amp;lt;&amp;lt; &quot;  0x&quot; &amp;lt;&amp;lt; std::hex &amp;lt;&amp;lt; std::setw(4) &amp;lt;&amp;lt; std::setfill('0') &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &quot;: &quot;;

        // Print Hex bytes
        for (int j = 0; j &amp;lt; bytes_per_line; ++j) {
            if (i + j &amp;lt; len) {
                std::cout &amp;lt;&amp;lt; std::hex &amp;lt;&amp;lt; std::setw(2) &amp;lt;&amp;lt; std::setfill('0') &amp;lt;&amp;lt; static_cast&amp;lt;int&amp;gt;(payload[i + j]) &amp;lt;&amp;lt; &quot; &quot;;
            } else {
                std::cout &amp;lt;&amp;lt; &quot;   &quot;; // Pad if line is short
            }
        }
        std::cout &amp;lt;&amp;lt; &quot; &quot;;

        // Print ASCII representation
        for (int j = 0; j &amp;lt; bytes_per_line; ++j) {
            if (i + j &amp;lt; len) {
                char c = payload[i + j];
                if (isprint(c)) {
                    std::cout &amp;lt;&amp;lt; c;
                } else {
                    std::cout &amp;lt;&amp;lt; &quot;.&quot;; // Print dot for non-printable characters
                }
            }
        }
        std::cout &amp;lt;&amp;lt; std::endl;
    }
     std::cout &amp;lt;&amp;lt; std::dec; // Reset base to decimal for other output
}

int capturePackets() {
    // --- Configuration ---
    bool show_tcp = true;
    bool show_udp = true;
    bool show_icmp = true;
    bool show_others = false; // Usually less interesting unless debugging
    bool filter_loopback = true; // Option to ignore 127.0.0.1 traffic

    // --- Socket Creation ---
    // AF_PACKET: Low-level packet interface
    // SOCK_RAW: Raw network protocol access
    // htons(ETH_P_ALL): Capture all Ethernet protocols (we'll filter IP later)
    int sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (sockfd &amp;lt; 0) {
        perror(&quot;ERROR: Socket creation failed&quot;);
        return 1;
    }
    std::cout &amp;lt;&amp;lt; &quot;Raw socket created successfully.&quot; &amp;lt;&amp;lt; std::endl;

    // --- Buffer for incoming data ---
    // Max possible Ethernet frame size is typically around 1518,
    // but jumbo frames exist. 65536 is common for packet capture.
    std::vector&amp;lt;unsigned char&amp;gt; buffer(65536);

    std::cout &amp;lt;&amp;lt; &quot;Starting packet capture... (Press Ctrl+C to stop)&quot; &amp;lt;&amp;lt; std::endl;

    // --- Main Capture Loop ---
    while (!stop_capture) {
        struct sockaddr saddr; // Generic socket address structure
        socklen_t saddr_len = sizeof(saddr);

        // Receive a packet
        ssize_t data_size = recvfrom(sockfd, buffer.data(), buffer.size(), 0, &amp;amp;saddr, &amp;amp;saddr_len);
        if (data_size &amp;lt; 0) {
            // Check if the error was due to interruption (Ctrl+C)
            if (errno == EINTR &amp;amp;&amp;amp; stop_capture) {
                break; // Exit loop gracefully
            }
            perror(&quot;ERROR: Packet recvfrom failed&quot;);
            continue; // Try receiving next packet
        }

        // --- 1. Ethernet Header Parsing ---
        if (data_size &amp;lt; sizeof(struct ethhdr)) {
            // std::cerr &amp;lt;&amp;lt; &quot;WARN: Received packet smaller than Ethernet header&quot; &amp;lt;&amp;lt; std::endl;
            continue; // Packet too small
        }
        struct ethhdr* eth_header = (struct ethhdr*)buffer.data();

        // Check if it's an IP packet (EtherType 0x0800)
        if (ntohs(eth_header-&amp;gt;h_proto) != ETH_P_IP) {
            continue; // Skip non-IP packets
        }

        // --- 2. IP Header Parsing ---
        size_t ip_header_offset = sizeof(struct ethhdr);
        if (data_size &amp;lt; ip_header_offset + sizeof(struct iphdr)) {
            // std::cerr &amp;lt;&amp;lt; &quot;WARN: Received packet smaller than Ethernet + minimal IP header&quot; &amp;lt;&amp;lt; std::endl;
            continue; // Packet too small
        }
        struct iphdr* ip_header = (struct iphdr*)(buffer.data() + ip_header_offset);

        // Calculate IP header length (ihl field is in 4-byte words)
        unsigned int ip_header_len = ip_header-&amp;gt;ihl * 4;
        if (ip_header_len &amp;lt; sizeof(struct iphdr)) { // Minimum IP header size check
             // std::cerr &amp;lt;&amp;lt; &quot;WARN: Invalid IP header length: &quot; &amp;lt;&amp;lt; ip_header_len &amp;lt;&amp;lt; &quot; bytes&quot; &amp;lt;&amp;lt; std::endl;
            continue;
        }

        // Check if received data size is sufficient for the declared IP header length
        if (data_size &amp;lt; ip_header_offset + ip_header_len) {
            // std::cerr &amp;lt;&amp;lt; &quot;WARN: Received data size (&quot; &amp;lt;&amp;lt; data_size &amp;lt;&amp;lt; &quot;) smaller than required for IP header (&quot; &amp;lt;&amp;lt; ip_header_offset + ip_header_len &amp;lt;&amp;lt; &quot;)&quot; &amp;lt;&amp;lt; std::endl;
            continue;
        }

        // --- Filtering ---
        int protocol = ip_header-&amp;gt;protocol;
        bool show_packet = false;

        // Loopback filtering
        struct in_addr src_ip = { ip_header-&amp;gt;saddr };
        struct in_addr dst_ip = { ip_header-&amp;gt;daddr };
        if (filter_loopback &amp;amp;&amp;amp; strcmp(inet_ntoa(src_ip), &quot;127.0.0.1&quot;) == 0 &amp;amp;&amp;amp; strcmp(inet_ntoa(dst_ip), &quot;127.0.0.1&quot;) == 0) {
            continue;
        }

        switch (protocol) {
            case IPPROTO_TCP:  show_packet = show_tcp; break;
            case IPPROTO_UDP:  show_packet = show_udp; break;
            case IPPROTO_ICMP: show_packet = show_icmp; break;
            default:           show_packet = show_others; break;
        }

        if (!show_packet) {
            continue; // Skip packet based on filter settings
        }

        // --- Print Basic Packet Info ---
        std::cout &amp;lt;&amp;lt; &quot;----------------------------------------&quot; &amp;lt;&amp;lt; std::endl;
        std::cout &amp;lt;&amp;lt; &quot;Packet (&quot; &amp;lt;&amp;lt; data_size &amp;lt;&amp;lt; &quot; bytes): &quot;;
        std::cout &amp;lt;&amp;lt; inet_ntoa(src_ip) &amp;lt;&amp;lt; &quot; -&amp;gt; &quot; &amp;lt;&amp;lt; inet_ntoa(dst_ip);
        std::cout &amp;lt;&amp;lt; &quot;, Proto: &quot;;

        // --- 3. Transport Layer Header Parsing &amp;amp; Payload ---
        size_t transport_header_offset = ip_header_offset + ip_header_len;
        unsigned char* payload_data = buffer.data() + transport_header_offset; // Initial payload pointer
        int payload_len = data_size - transport_header_offset; // Initial payload length

        // Protocol-specific handling
        if (protocol == IPPROTO_TCP) {
            std::cout &amp;lt;&amp;lt; &quot;TCP&quot;;
            if (data_size &amp;lt; transport_header_offset + sizeof(struct tcphdr)) {
                std::cout &amp;lt;&amp;lt; &quot; [WARN: Packet too small for TCP header]&quot; &amp;lt;&amp;lt; std::endl;
                continue;
            }
            struct tcphdr* tcp_header = (struct tcphdr*)(buffer.data() + transport_header_offset);
            unsigned int tcp_header_len = tcp_header-&amp;gt;doff * 4;
            if (tcp_header_len &amp;lt; sizeof(struct tcphdr)) {
                 std::cout &amp;lt;&amp;lt; &quot; [WARN: Invalid TCP header length: &quot; &amp;lt;&amp;lt; tcp_header_len &amp;lt;&amp;lt; &quot; bytes]&quot; &amp;lt;&amp;lt; std::endl;
                 continue;
            }
             if (data_size &amp;lt; transport_header_offset + tcp_header_len) {
                 std::cout &amp;lt;&amp;lt; &quot; [WARN: Packet too small for full TCP header]&quot; &amp;lt;&amp;lt; std::endl;
                 continue;
             }

            std::cout &amp;lt;&amp;lt; &quot;, Port: &quot; &amp;lt;&amp;lt; ntohs(tcp_header-&amp;gt;source) &amp;lt;&amp;lt; &quot; -&amp;gt; &quot; &amp;lt;&amp;lt; ntohs(tcp_header-&amp;gt;dest);
            payload_data = buffer.data() + transport_header_offset + tcp_header_len;
            payload_len = data_size - (transport_header_offset + tcp_header_len);
            printPayload(payload_data, payload_len);

        } else if (protocol == IPPROTO_UDP) {
            std::cout &amp;lt;&amp;lt; &quot;UDP&quot;;
            if (data_size &amp;lt; transport_header_offset + sizeof(struct udphdr)) {
                std::cout &amp;lt;&amp;lt; &quot; [WARN: Packet too small for UDP header]&quot; &amp;lt;&amp;lt; std::endl;
                continue;
            }
            struct udphdr* udp_header = (struct udphdr*)(buffer.data() + transport_header_offset);
            std::cout &amp;lt;&amp;lt; &quot;, Port: &quot; &amp;lt;&amp;lt; ntohs(udp_header-&amp;gt;source) &amp;lt;&amp;lt; &quot; -&amp;gt; &quot; &amp;lt;&amp;lt; ntohs(udp_header-&amp;gt;dest);

            // UDP header length field includes header (8 bytes) + data
            int udp_total_len = ntohs(udp_header-&amp;gt;len);
            payload_data = buffer.data() + transport_header_offset + sizeof(struct udphdr);
            payload_len = udp_total_len - sizeof(struct udphdr);

            // Sanity check: ensure calculated payload doesn't exceed received data
            if (payload_len &amp;lt; 0 || (transport_header_offset + sizeof(struct udphdr) + payload_len) &amp;gt; data_size) {
                 std::cout &amp;lt;&amp;lt; &quot; [WARN: UDP length mismatch or exceeds packet size]&quot;;
                 // Adjust payload_len based on actual received data if there's a discrepancy
                 payload_len = data_size - (transport_header_offset + sizeof(struct udphdr));
                 if (payload_len &amp;lt; 0) payload_len = 0;
            }

            printPayload(payload_data, payload_len);

        } else if (protocol == IPPROTO_ICMP) {
            std::cout &amp;lt;&amp;lt; &quot;ICMP&quot;;
            // Could add ICMP header parsing here (type, code) if needed
            std::cout &amp;lt;&amp;lt; std::endl; // No ports for ICMP typically shown this way
            // Payload for ICMP often starts right after the basic ICMP header (usually 8 bytes)
            // You might want to parse type/code before printing payload
            printPayload(payload_data, payload_len);


        } else {
            std::cout &amp;lt;&amp;lt; &quot;Other (&quot; &amp;lt;&amp;lt; protocol &amp;lt;&amp;lt; &quot;)&quot; &amp;lt;&amp;lt; std::endl;
             printPayload(payload_data, payload_len);
        }

    } // End while loop

    // --- Cleanup ---
    std::cout &amp;lt;&amp;lt; &quot;Closing socket.&quot; &amp;lt;&amp;lt; std::endl;
    close(sockfd);
    return 0;
}

int main() {
    // Register signal handler for SIGINT (Ctrl+C)
    signal(SIGINT, signalHandler);

    // Note: Running this program requires root privileges (or CAP_NET_RAW capability)
    //       to create a raw socket.
    if (geteuid() != 0) {
         std::cerr &amp;lt;&amp;lt; &quot;ERROR: This program must be run as root or with CAP_NET_RAW capability.&quot; &amp;lt;&amp;lt; std::endl;
         return 1;
    }


    return capturePackets();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;BPF에 대해 상세하게 확인하길 원한다면 해당 문서(&lt;a href=&quot;https://asec.ahnlab.com/ko/83742/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;#1&lt;/a&gt;,&lt;/span&gt; &lt;a href=&quot;https://docs.kernel.org/networking/filter.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;#2&lt;/a&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;,&lt;/span&gt; &lt;a href=&quot;https://github.com/libbpf/libbpf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;#3&lt;/a&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;, &lt;/span&gt;&lt;a href=&quot;https://ebpf.io/what-is-ebpf/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;#4&lt;/a&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;)를 참조하길 바란다.&lt;/span&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 Target에서 작동하는 코드로, 파싱을 위한 출력 로직이 복잡할 뿐이지 실질적으로 복잡한 부분은 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 TCP연결의 경우 아래와 같은 과정을 따르게 되는데, BPFDoor 공격은 이러한 bind, listen 등 TCP, UDP 프로토콜단의 모든 행위를 수행하지 않는다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;530&quot; data-origin-height=&quot;444&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ue8mN/btsNAWvYmZj/RkVDIJsh9H9brqzsh0BC71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ue8mN/btsNAWvYmZj/RkVDIJsh9H9brqzsh0BC71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ue8mN/btsNAWvYmZj/RkVDIJsh9H9brqzsh0BC71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fue8mN%2FbtsNAWvYmZj%2FRkVDIJsh9H9brqzsh0BC71%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;530&quot; height=&quot;444&quot; data-origin-width=&quot;530&quot; data-origin-height=&quot;444&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 Target 코드 부분을 살펴보면 아래와 같이 간단하게 작성되어 있는데,&lt;/p&gt;
&lt;pre id=&quot;code_1745729964540&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// open socket
int sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

// just recvfrom
ssize_t data_size = recvfrom(sockfd, buffer.data(), buffer.size(), 0, &amp;amp;saddr, &amp;amp;saddr_len);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저 코드로 인해 Target 프로그램은 data link 계층에서 frame 단위로 IP, Port를 무시한 채 모든 데이터를 수신받을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;467&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXyHND/btsNz5Av1rx/EVZCQqABtAXqnYn6GVL1QK/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXyHND/btsNz5Av1rx/EVZCQqABtAXqnYn6GVL1QK/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXyHND/btsNz5Av1rx/EVZCQqABtAXqnYn6GVL1QK/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXyHND%2FbtsNz5Av1rx%2FEVZCQqABtAXqnYn6GVL1QK%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;404&quot; height=&quot;467&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;467&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 개념을 전제로 &lt;a href=&quot;https://scapy.net/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Scapy&lt;/a&gt;를 사용해 Attacker용 코드를 작성하여 Target 내부에서 패킷이 수신되는지 실습해 보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;Attacker System&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 Attacker&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Sender)&lt;/span&gt; 역할을 할 python 코드이며 Scapy가 사전에 설치되어 있어야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;Python&lt;/b&gt; &lt;b&gt;Build&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745730381710&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import socket
from scapy.all import *
import time
import sys

def sendUDP(target_ip=&quot;172.17.0.2&quot;, target_port=9090):
    &quot;&quot;&quot;Send a simple UDP message to the specified IP and port.&quot;&quot;&quot;
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

        message = &quot;this is UDP test!!!&quot;
        sock.sendto(message.encode('utf-8'), (target_ip, target_port))
        print(f&quot;[UDP Sent] Sent '{message}' to {target_ip}:{target_port}&quot;)

    except socket.error as e:
        print(f&quot;[UDP Error] Socket error: {e}&quot;)
    except Exception as e:
        print(f&quot;[UDP Error] Unexpected error: {e}&quot;)
    finally:
        if 'sock' in locals() and sock:
            sock.close()

def sendTCP_scapy(target_ip=&quot;172.17.0.2&quot;, target_port=9090):
    &quot;&quot;&quot;
    Send a raw TCP packet (PSH+ACK) without TCP handshake using Scapy.
    Useful for testing packet sniffers at L2/L3 level.
    &quot;&quot;&quot;
    try:
        message = &quot;TCP BPF Test!!!&quot;
        packet = IP(dst=target_ip)/TCP(dport=target_port, flags=&quot;PA&quot;)/Raw(load=message.encode('utf-8'))

        send(packet, verbose=0)
        print(f&quot;[TCP Scapy Sent] Sent raw PSH+ACK packet with payload '{message}' to {target_ip}:{target_port}&quot;)
        print(f&quot;                 (Source Port: {packet[TCP].sport})&quot;)

    except Exception as e:
        print(f&quot;[TCP Scapy Error] Unexpected error: {e}&quot;)

if __name__ == &quot;__main__&quot;:
    target_ip_address = sys.argv[1] if len(sys.argv) &amp;gt; 1 else &quot;172.17.0.2&quot;
    udp_port = 9090
    tcp_port = 9090

    print(f&quot;Target IP: {target_ip_address}&quot;)

    print(&quot;Sending UDP packet...&quot;)
    sendUDP(target_ip_address, udp_port)

    time.sleep(1)

    print(&quot;\nSending TCP packet using Scapy (PSH+ACK)...&quot;)
    sendTCP_scapy(target_ip_address, tcp_port)

    print(&quot;\nScript finished.&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실습 결과&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Target 코드중 하나를 선택해서 실행하고, Attacker 코드를 실행하면 아래와 같은 결과를 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1449&quot; data-origin-height=&quot;107&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bi9wrp/btsNBBrsMn6/YsXDEduKdXapWY2Vmmrzj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bi9wrp/btsNBBrsMn6/YsXDEduKdXapWY2Vmmrzj0/img.png&quot; data-alt=&quot;Scapy로 Target에서 Attacker의 메세지를 받아본 결과물&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bi9wrp/btsNBBrsMn6/YsXDEduKdXapWY2Vmmrzj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbi9wrp%2FbtsNBBrsMn6%2FYsXDEduKdXapWY2Vmmrzj0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;59&quot; data-origin-width=&quot;1449&quot; data-origin-height=&quot;107&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Scapy로 Target에서 Attacker의 메세지를 받아본 결과물&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2558&quot; data-origin-height=&quot;1301&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjbJdv/btsNAa9I2U3/9fAonrYveZGiJ6JtqGoo2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjbJdv/btsNAa9I2U3/9fAonrYveZGiJ6JtqGoo2K/img.png&quot; data-alt=&quot;C++을 사용한 결과물, 좌측: Target, 우측: Attacker&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjbJdv/btsNAa9I2U3/9fAonrYveZGiJ6JtqGoo2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjbJdv%2FbtsNAa9I2U3%2F9fAonrYveZGiJ6JtqGoo2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;407&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2558&quot; data-origin-height=&quot;1301&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;C++을 사용한 결과물, 좌측: Target, 우측: Attacker&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;UDP, TCP 패킷이 모두 잘 송신되고, 수신되는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Ignore Port&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BPFDoor는 2계층에서 수행되는 공격으로, listen() 함수를 수행하지 않으므로 포트가 열리지 않은 상태로 수신된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;Target 에서 port open 없이 수신되는 메세지&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745730869874&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Raw socket created successfully.
Starting packet capture... (Press Ctrl+C to stop)
----------------------------------------
Packet (61 bytes): 172.17.0.1 -&amp;gt; 172.17.0.2, Proto: UDP, Port: 44825 -&amp;gt; 9090 [Payload Data (19 bytes)]:
  0x0000: 74 68 69 73 20 69 73 20 55 44 50 20 74 65 73 74  this is UDP test
  0x0010: 21 21 21                                         !!!
----------------------------------------
Packet (89 bytes): 172.17.0.2 -&amp;gt; 172.17.0.1, Proto: ICMP
 [Payload Data (55 bytes)]:
  0x0000: 03 03 91 2e 00 00 00 00 45 00 00 2f eb 1c 40 00  ........E../..@.
  0x0010: 40 11 f7 7b ac 11 00 01 ac 11 00 02 af 19 23 82  @..{..........#.
  0x0020: 00 1b 58 52 74 68 69 73 20 69 73 20 55 44 50 20  ..XRthis is UDP 
  0x0030: 74 65 73 74 21 21 21                             test!!!
----------------------------------------
Packet (69 bytes): 172.17.0.1 -&amp;gt; 172.17.0.2, Proto: TCP, Port: 20 -&amp;gt; 9090 [Payload Data (15 bytes)]:
  0x0000: 54 43 50 20 42 50 46 20 54 65 73 74 21 21 21     TCP BPF Test!!!&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 받은 UDP 패킷의 반환으로 전달되는 ICMP 패킷 속 `03 03` 은 아래와 같은 의미를 지닌다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1329&quot; data-origin-height=&quot;814&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4kywQ/btsNBvERVM1/X4pQIWK5nLI2Fy9CtFITZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4kywQ/btsNBvERVM1/X4pQIWK5nLI2Fy9CtFITZ1/img.png&quot; data-alt=&quot;https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4kywQ/btsNBvERVM1/X4pQIWK5nLI2Fy9CtFITZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4kywQ%2FbtsNBvERVM1%2FX4pQIWK5nLI2Fy9CtFITZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;490&quot; data-origin-width=&quot;1329&quot; data-origin-height=&quot;814&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 도착하지 않았고, 그 이유가 포트에 문제가 있음을 나타내고 있다. 하지만 BPFDoor를 사용할 때 이딴건 전혀 상관없다. 중요한건 우리가 Attacker 코드에서 보낸 명령 메세지를 모두 받아볼 수 있고, 그렇게 받은 명령 메세지로 공격 행위를 수행할 수 있다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP 프로토콜 역시 아주 잘 받아지는 모습을 확인할 수 있으며, `ss -a | grep 9090` 명령어로 확인해 봐도 열린 포트는 존재하지 않다는 사실을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1393&quot; data-origin-height=&quot;1028&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lt10M/btsNBz1kffm/IsPB7wkoH0sDOJKU5QEPrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lt10M/btsNBz1kffm/IsPB7wkoH0sDOJKU5QEPrK/img.png&quot; data-alt=&quot;실제로 프로그램 실행중에 9090 포트와 관련된 Listen, Established는 존재하지 않는다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lt10M/btsNBz1kffm/IsPB7wkoH0sDOJKU5QEPrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flt10M%2FbtsNBz1kffm%2FIsPB7wkoH0sDOJKU5QEPrK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;590&quot; data-origin-width=&quot;1393&quot; data-origin-height=&quot;1028&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실제로 프로그램 실행중에 9090 포트와 관련된 Listen, Established는 존재하지 않는다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Ignore Firewall&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 우리가 작성한 코드는 &lt;b&gt;2계층&lt;/b&gt;에서 공격명령을 받아 수행하기에 3~4계층을 막는 iptables, UFW 로는 공격을 막을 수 없다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;835&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqjvKu/btsNCb62LyI/IMIxkjSMeivdF3tPrbJ2dk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqjvKu/btsNCb62LyI/IMIxkjSMeivdF3tPrbJ2dk/img.png&quot; data-alt=&quot;https://help.ubuntu.com/community/UFW&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqjvKu/btsNCb62LyI/IMIxkjSMeivdF3tPrbJ2dk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqjvKu%2FbtsNCb62LyI%2FIMIxkjSMeivdF3tPrbJ2dk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;311&quot; data-origin-width=&quot;835&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://help.ubuntu.com/community/UFW&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 아래와 같이 UFW를 통해서 9090 포트를 막았음에도&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;596&quot; data-origin-height=&quot;85&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLFjkJ/btsNBb0O49G/KxMKkFJndeGUFYTuMax1i0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLFjkJ/btsNBb0O49G/KxMKkFJndeGUFYTuMax1i0/img.png&quot; data-alt=&quot;Ubuntu 의 UFW 방화벽 Rule로 9090 포트 Deny&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLFjkJ/btsNBb0O49G/KxMKkFJndeGUFYTuMax1i0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLFjkJ%2FbtsNBb0O49G%2FKxMKkFJndeGUFYTuMax1i0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;596&quot; height=&quot;85&quot; data-origin-width=&quot;596&quot; data-origin-height=&quot;85&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Ubuntu 의 UFW 방화벽 Rule로 9090 포트 Deny&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여전히 2계층에서 데이터를 수신받아 명령어를 처리할 수 있음을 알 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1282&quot; data-origin-height=&quot;469&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ss7RS/btsNAhAO5TG/v5jWxxQiWLqB7PNGFOj3m0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ss7RS/btsNAhAO5TG/v5jWxxQiWLqB7PNGFOj3m0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ss7RS/btsNAhAO5TG/v5jWxxQiWLqB7PNGFOj3m0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSs7RS%2FbtsNAhAO5TG%2Fv5jWxxQiWLqB7PNGFOj3m0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;293&quot; data-origin-width=&quot;1282&quot; data-origin-height=&quot;469&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로, 작은 프로그램 하나&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(BPFDoor)&lt;/span&gt;를 물리적으로 시스템에 접근하여 관리자 권한 + 부팅시 자동 실행으로 삽입해 둔다면 시스템 내의 모든 데이터를 휘저으며 내 시스템인것 마냥 돌아다닐 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 해당 예제에서는 작업관리자를 통해 BPFDoor가 작동하는것을 확인할 수 있지만, 사실 해커들이 운용하는 BPFDoor는 Kernel단에서 움직이기에 Process 작업관리자 따위로는 감지할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 아래와 같은 사항을 명심하길 바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;시스템을 점검할 때 Port Listen, Established 여부와&lt;br /&gt;방화벽 설정만으로 안전하다고 생각해서는 안된다.&lt;br /&gt;&lt;br /&gt;해커는 항상 기상천외한 방법을 사용하여 침투한다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 SKT에서 해킹당한 방법이 바로 이와 같은 BPFDoor 해킹 기법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사건이 터진지 1주일이 지난 현재까지도 '피해 범위'를 파악하고 있지 못한데, 동작 원리를 보면 알 수 있듯. 내부 데이터가 암호화되어 있지 않고, Target 프로그램이 정교하게 작성되어 있다면 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;사실상 전부 털린것&lt;/span&gt;&lt;/b&gt;과 마찬가지이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 설명했듯 반드시 프로그램을 내장시켜야 하기에 어떻게 해당 프로그램이 침투했는지 밝히는것도 난제이다. 내부자 스파이 직원이 있을수도 있고, 내부망을 타고 들어왔을수도 있는 등, 여러가지 가능성을 고려해서 조사해야 하기에 상당한 시일이 소요될 것으로 추정된다.&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Cyber Security</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/213</guid>
      <comments>https://cypsw.tistory.com/entry/BPFDoor%EC%9D%98-%EC%9B%90%EB%A6%AC%EC%99%80-%EA%B5%AC%ED%98%84#entry213comment</comments>
      <pubDate>Sun, 27 Apr 2025 14:33:43 +0900</pubDate>
    </item>
    <item>
      <title>오류: OSError: We couldn't connect to 'https://huggingface.co' to load this file 해결법.</title>
      <link>https://cypsw.tistory.com/entry/%EC%98%A4%EB%A5%98-OSError-We-couldnt-connect-to-httpshuggingfaceco-to-load-this-file-%ED%95%B4%EA%B2%B0%EB%B2%95</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;HuggingFace는 내부적으로 파일 다운시 IPv6를 사용하는것으로 추정된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;공유기나, 시스템적으로 IPv6 를 비활성화하면 발생하는 문제이므로, 활성화 해 주면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;438&quot; data-origin-height=&quot;167&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Q7Sgc/btsL3psdIGq/WVJTjavQIKCSoozoOg2260/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Q7Sgc/btsL3psdIGq/WVJTjavQIKCSoozoOg2260/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Q7Sgc/btsL3psdIGq/WVJTjavQIKCSoozoOg2260/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQ7Sgc%2FbtsL3psdIGq%2FWVJTjavQIKCSoozoOg2260%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;438&quot; height=&quot;167&quot; data-origin-width=&quot;438&quot; data-origin-height=&quot;167&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Programming/Python</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/212</guid>
      <comments>https://cypsw.tistory.com/entry/%EC%98%A4%EB%A5%98-OSError-We-couldnt-connect-to-httpshuggingfaceco-to-load-this-file-%ED%95%B4%EA%B2%B0%EB%B2%95#entry212comment</comments>
      <pubDate>Thu, 30 Jan 2025 15:35:42 +0900</pubDate>
    </item>
    <item>
      <title>[리뷰] DeepSeek-V3 Technical Report</title>
      <link>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-DeepSeek-V3-Technical-Report</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;해당 포스팅은 PC 환경에 최적화 되어 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DeepSeek 라는 중국의 스타트업에서 만든 V3 모델은, OpenAI의 4o 모델에 대응되는 모델로서, 그 성능이 4o와 유사하면서, 추론 비용이 압도적으로 저렴하기에 현재 AI 커뮤니티에서 큰 파장을 불러일으키고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1661&quot; data-origin-height=&quot;971&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWMMN6/btsL2fpqa8i/GkCk59H30AKDapJGkj2BhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWMMN6/btsL2fpqa8i/GkCk59H30AKDapJGkj2BhK/img.png&quot; data-alt=&quot;Figure 1 ❘ Benchmark performance of DeepSeek-V3 and its counterparts&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWMMN6/btsL2fpqa8i/GkCk59H30AKDapJGkj2BhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWMMN6%2FbtsL2fpqa8i%2FGkCk59H30AKDapJGkj2BhK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;468&quot; data-origin-width=&quot;1661&quot; data-origin-height=&quot;971&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 1 ❘ Benchmark performance of DeepSeek-V3 and its counterparts&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/pdf/2412.19437&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;논문&lt;/a&gt;의 Abstract 란에서 바로 벤치마크를 살펴볼 수 있다. Transformer 모델인 만큼 전반적인 벤치마크 수준은 o1, R1 모델 대비 낮지만, 벤치로 식별하기 어려운 창의적인 대화에서는 더 높은 성능을 보여준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 소개&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 몇년간 LLM 모델은 진화를 거듭하면서 AGI에 다가가고 있다. 대표적으로 ChatGPT, Claude, LLaMA, Qwen 등을 꼽을 수 있다. 이러한 변화의 물결에 올라, DeepSeek 사는 V3 모델을 제작하였다. V3는 MoE를 기반으로 제작되었으며, 오픈 소스 모델의 한계를 확장하기 위해 제작하였다고 밝히고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;V3 모델을 제작하며 DeepSeek 측에서는 특히&lt;span style=&quot;color: #f89009;&quot;&gt; '비용적'&lt;/span&gt; 측면에서 모델을 강화하려 노력했다 이를 위해 MLA&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Multi-head Latent Attention)&lt;/span&gt; 와 학습 비용 절약을 위해 DeepSeekMoE를 채택하고 있다. 이러한 두 아키텍처는 이미 V2 모델에서 검증되었으며, 효율적인 학습과 추론을 달성하면서도 견고한 모델 성능을 유지할 수 있는 능력을 입증했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;97&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUuvDi/btsL25fy5vP/VuKXyILOEzY5XArXonic0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUuvDi/btsL25fy5vP/VuKXyILOEzY5XArXonic0k/img.png&quot; data-alt=&quot;Table 1:&amp;amp;nbsp;Training costs of DeepSeek-V3, assuming the rental price of H800 is $2 per GPU hour.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUuvDi/btsL25fy5vP/VuKXyILOEzY5XArXonic0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUuvDi%2FbtsL25fy5vP%2FVuKXyILOEzY5XArXonic0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;623&quot; height=&quot;97&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;97&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Table 1:&amp;nbsp;Training costs of DeepSeek-V3, assuming the rental price of H800 is $2 per GPU hour.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 `Table 1` 에서 보여지는 총 훈련 비용이 인상적이다. 약 560만 달러, 즉 한화 80억원 가량의 비용만으로 최첨단 폐쇄형 모델 성능에 도달한 것이다. 또한 여기서 언급된 H800 GPU는 &lt;a href=&quot;https://www.fibermall.com/ko/blog/nvidia-ai-chip.htm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;중국시장에 판매하기 위해 고의적으로 성능을 낮춘 버전&lt;/a&gt;이다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(해당 내용에 관해서, 실제로는 '대여' 해서 학습하지 않았음에도, GPU '대여' 기준으로 학습비용을 낮춰잡았다는 일부 비판여론이 존재한다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 구조&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 언급한 MLA와 DeepSeekMoE가 해당 모델에서 특징적인 부분이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1644&quot; data-origin-height=&quot;1322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RsGLV/btsL1krw4kh/PhM0bu0LtesWuay8GgqgS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RsGLV/btsL1krw4kh/PhM0bu0LtesWuay8GgqgS1/img.png&quot; data-alt=&quot;Figure 2: &amp;amp;nbsp;Illustration of the basic architecture of DeepSeek-V3. Following DeepSeek-V2, we adopt MLA and DeepSeekMoE for efficient inference and economical training.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RsGLV/btsL1krw4kh/PhM0bu0LtesWuay8GgqgS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRsGLV%2FbtsL1krw4kh%2FPhM0bu0LtesWuay8GgqgS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;643&quot; data-origin-width=&quot;1644&quot; data-origin-height=&quot;1322&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 2: &amp;nbsp;Illustration of the basic architecture of DeepSeek-V3. Following DeepSeek-V2, we adopt MLA and DeepSeekMoE for efficient inference and economical training.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 좌측 부분에 Transformer Block을 확인할 수 있다. 일반적으로 Transformer Decoder 구조는 아래와 같이 구성된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;168&quot; data-origin-height=&quot;335&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hzipj/btsL0QYRU7r/OYLnklZ6HRegamFucE4tV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hzipj/btsL0QYRU7r/OYLnklZ6HRegamFucE4tV1/img.png&quot; data-alt=&quot;Transformer Decoder&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hzipj/btsL0QYRU7r/OYLnklZ6HRegamFucE4tV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHzipj%2FbtsL0QYRU7r%2FOYLnklZ6HRegamFucE4tV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;168&quot; height=&quot;335&quot; data-origin-width=&quot;168&quot; data-origin-height=&quot;335&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Transformer Decoder&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM 모델의 경우 일반적으로 Decoder 만 사용되지만, 원론적인 Decoder 구조와 다른 이유는 효율을 위해 DeepSeek 사에서 여러 변형을 거쳐 도출된 구조로 추정된다. V3 모델은 아래와 같이 구성되어 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RMSNorm &amp;rarr; Attention &amp;rarr; RMSNorm &amp;rarr; Feed-Forward Netwok
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Attention 구조는 MLA&lt;/li&gt;
&lt;li&gt;FFN 구조는 DeepSeekMoE&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;V3 모델의 핵심은 MLA, DeepSeekMoE 이기에, 해당 구조에 관해서 리뷰한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-1. Multi-head Latent Attention&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 리뷰를 보고있다면, Attention, Multi-head 같은 기본 지식을 인지하고 있을 것이기에 생략한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;365&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9Gnzo/btsL22pRb9w/AWBcNTCHWfUVtyBY6Ycxa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9Gnzo/btsL22pRb9w/AWBcNTCHWfUVtyBY6Ycxa1/img.png&quot; data-alt=&quot;Multi-head Latent Attention&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9Gnzo/btsL22pRb9w/AWBcNTCHWfUVtyBY6Ycxa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9Gnzo%2FbtsL22pRb9w%2FAWBcNTCHWfUVtyBY6Ycxa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;503&quot; height=&quot;365&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;365&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Multi-head Latent Attention&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 결국 Latent&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(잠재)&lt;/span&gt; 라는 단어가 남는데, 이 단어가 바로 키 포인트이다. 기본적으로 Attention을 진행할 때 관련성 있는 단어들간의 중요성을 평가하는 과정을 거친다. 이 때 모든시점의 은닉 상태들을 KV&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Key-Value)&lt;/span&gt; Cache 라는 이름으로 저장하는데, 이 과정에서 매우 많은 메모리를 소모하게 된다. 때문에 DeepSeek 팀에서는 KV 캐시를 작게 압축할 수 있는 방법인 MLA를 적용했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{align} &lt;br /&gt;\boxed{\mathbf{c}_t^{KV}}&amp;nbsp;&amp;amp;=&amp;nbsp;\mathbf{W}^{DKV}&amp;nbsp;\mathbf{h}_t,&amp;nbsp;\tag{1}&amp;nbsp;\\ &lt;br /&gt;\left[&amp;nbsp;\mathbf{k}_{t,1}^C;&amp;nbsp;\mathbf{k}_{t,2}^C;&amp;nbsp;\ldots;&amp;nbsp;\mathbf{k}_{t,n_h}^C&amp;nbsp;\right]&amp;nbsp;=&amp;nbsp;k^{C}_{t}&amp;nbsp;&amp;amp;=&amp;nbsp;\mathbf{W}^{UK}&amp;nbsp;\mathbf{c}_t^{KV},&amp;nbsp;\tag{2}&amp;nbsp;\\ &lt;br /&gt;\boxed{\mathbf{k}_t^R}&amp;nbsp;&amp;amp;=&amp;nbsp;\text{RoPE}\left(&amp;nbsp;\mathbf{W}^{KR}&amp;nbsp;\mathbf{h}_t&amp;nbsp;\right),&amp;nbsp;\tag{3}&amp;nbsp;\\ &lt;br /&gt;\mathbf{k}_{t,i}&amp;nbsp;&amp;amp;=&amp;nbsp;\left[&amp;nbsp;\mathbf{k}_{t,i}^C;\,&amp;nbsp;\mathbf{k}_t^R&amp;nbsp;\right],&amp;nbsp;\tag{4}&amp;nbsp;\\ &lt;br /&gt;\left[&amp;nbsp;\mathbf{v}_{t,1}^C;&amp;nbsp;\mathbf{v}_{t,2}^C;&amp;nbsp;\ldots;&amp;nbsp;\mathbf{v}_{t,n_h}^C&amp;nbsp;\right]&amp;nbsp;=&amp;nbsp;\mathbf{v}_t^C&amp;nbsp;&amp;amp;=&amp;nbsp;\mathbf{W}^{UV}&amp;nbsp;\mathbf{c}_t^{KV},&amp;nbsp;\tag{5} &lt;br /&gt;\end{align}$$&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$\boxed{\mathbf{c}_t^{KV}} = \mathbf{W}^{DKV} \mathbf{h}_t$&lt;/span&gt; : 입력 임베딩 $h_t$를 저차원 잠재 벡터 $c_t^{KV}$로 압축
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$C$&amp;nbsp;:&amp;nbsp;Compressed&amp;nbsp;벡터&lt;/li&gt;
&lt;li&gt;$h_t$ : $t$번째 토큰 입력 임베딩 벡터 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(차원 : $d$)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;$W^{DKV}$ : Down-Projection 행렬 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(차원 : $d_c \times d$)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;$c_t^{KV}$ : 압축된 Key Value 잠재 벡터 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(차원 : $d_c$)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;목적 : KV 캐시 메모리 사용량 감소&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$\left[ \mathbf{k}_{t,1}^C; \mathbf{k}_{t,2}^C; \ldots; \mathbf{k}_{t,n_h}^C \right] = k^{C}_{t} = \mathbf{W}^{UK} \mathbf{c}_t^{KV}$&lt;/span&gt; : 압축 벡터 $c_t^{KV}$를 Up-Projection 해서 Multihead-Key 를 복원&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$[;]$&amp;nbsp;:&amp;nbsp;벡터&amp;nbsp;연결&amp;nbsp;연산자&lt;/li&gt;
&lt;li&gt;$W^{UK}$ : Key Up-Projection 행렬 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(차원 : $d_h h_n \times d_c$)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;$k^C_{t,i}$ : $i$번째 헤드의 압축 Key 벡터 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(차원 : $d_h$)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;$n_h$ : 어텐션 헤드 수&lt;/li&gt;
&lt;li&gt;목적 : 행렬 분해를 통해 계산 효율성 확보&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$\boxed{\mathbf{k}_t^R} = \text{RoPE}\left( \mathbf{W}^{KR} \mathbf{h}_t \right)$&lt;/span&gt; : 입력 임베딩에 RoPE&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Rotary Positional Embedding)&lt;/span&gt;를 적용한 Key 생성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$W^{KR}$ : RoPE Key 프로젝션 행렬. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(차원 : $d^R_h \times d$)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;$K^R_t$ : 윗첨자 $R$은 RoPE가 적용된 Key 벡터를 의미.&lt;/li&gt;
&lt;li&gt;목적 : 위치 정보를 명시적으로 인코딩하여 Transformer 고질적 문제 해결&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$\mathbf{k}_{t,i} = \left[ \mathbf{k}_{t,i}^C;\, \mathbf{k}_t^R \right]$&lt;/span&gt; : 압축 키&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($K^{C}_{t,i}$)&lt;/span&gt; 와 RoPE Key &lt;span style=&quot;color: #9d9d9d;&quot;&gt;($K^R_t$)&lt;/span&gt;를 연결&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$k_{t,i}$ : $i$번째 헤드의 최종 Key &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(차원 : $d_h + d^R_h$)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;효과 : 압축 정보와 위치 정보를 병렬로 활용.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$\left[ \mathbf{v}_{t,1}^C; \mathbf{v}_{t,2}^C; \ldots; \mathbf{v}_{t,n_h}^C \right] = \mathbf{v}_t^C = \mathbf{W}^{UV} \mathbf{c}_t^{KV}$&lt;/span&gt; : 압축 벡터 $c^{KV}_t$ 를 Up-Projection 하여 멀티헤드 value 생성.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$W^{UV}$ : Value Up-Projection 행렬 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(차원 : $d_h n_h \times d_c$)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;$v^{C}_{t,i}$: $i$번째 헤드의 Value 벡터 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(차원 : $d_h$)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;즉, $v^{C}_{t,1}$ 내의 $C$는 $c^{KV}_{t}$ 에서 복원되었음을 의미.&lt;/li&gt;
&lt;li&gt;효과 : Key-Value 쌍이 동일한 압축 벡터 $c^{KV}_{t}$를 공유하여 메모리 효율성 증가.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복잡하게 기술되어 있지만 전체적으로 요약하자면 아래와 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;입력 압축: 고차원 입력&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($h_t$)&lt;/span&gt; &amp;rarr; 저차원&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($c^{KV}_{t}$)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Key 생성 : 압축 Key복원 (2) + RoPE 적용 (3) + 결합 (4)&lt;/li&gt;
&lt;li&gt;Value 생성 : 압축 벡터로부터 직접 복원 (5)&lt;/li&gt;
&lt;li&gt;결론 : KV 캐시 크기 감소&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($d_c \ll d_h n_h$)&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$d_c$ : 압축차원&lt;/li&gt;
&lt;li&gt;$d_h&amp;nbsp;h_h$&amp;nbsp;:&amp;nbsp;원본차원&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더하여, 위 로직과 비슷하게 Attention 의 Query 역시 훈련중 활성 메모리를 줄일 수 있는 low-rank 압축을 수행한다. 전반적으로 KV 와 비슷한 로직이므로 상세한 설명은 생략하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{align} &lt;br /&gt;{c}_t^{Q}&amp;nbsp;&amp;amp;=&amp;nbsp;\mathbf{W}^{DQ}&amp;nbsp;\mathbf{h}_t,&amp;nbsp;\tag{6}&amp;nbsp;\\ &lt;br /&gt;\left[&amp;nbsp;\mathbf{q}_{t,1}^C;&amp;nbsp;\mathbf{q}_{t,2}^C;&amp;nbsp;\ldots;&amp;nbsp;\mathbf{q}_{t,n_h}^C&amp;nbsp;\right]&amp;nbsp;=&amp;nbsp;q^{C}_{t}&amp;nbsp;&amp;amp;=&amp;nbsp;\mathbf{W}^{UQ}&amp;nbsp;\mathbf{c}_t^{Q},&amp;nbsp;\tag{7}&amp;nbsp;\\ &lt;br /&gt;\left[&amp;nbsp;\mathbf{q}_{t,1}^R;&amp;nbsp;\mathbf{q}_{t,2}^R;&amp;nbsp;\ldots;&amp;nbsp;\mathbf{q}_{t,n_h}^R&amp;nbsp;\right]&amp;nbsp;=&amp;nbsp;q^{R}_{t}&amp;nbsp;&amp;amp;=&amp;nbsp;\text{RoPE}(W^{QR}&amp;nbsp;c^Q_t),&amp;nbsp;\tag{8}\\ &lt;br /&gt;\mathbf{q}_{t,i}&amp;nbsp;&amp;amp;=&amp;nbsp;\left[&amp;nbsp;\mathbf{q}_{t,i}^C;\,&amp;nbsp;\mathbf{q}_{t,i}^R&amp;nbsp;\right],&amp;nbsp;\tag{9}&amp;nbsp;\\ &lt;br /&gt;\end{align}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;2-2.&lt;span&gt; DeepSeekMoE&amp;nbsp;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MoE&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Mixture of Experts)&lt;/span&gt; 는 여러 개의 전문가&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(expert)&lt;/span&gt; 하위 네트워크로 분할하는 신경망의 아키텍처 패턴으로서, 처음 해당 구조를 들엇을 때는 Attention에 사용될 것이라 예상했는데, V3 모델에 사용된 MoE는 FFN 레이어에서 사용된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;For Feed-Forward Networks (FFNs), DeepSeek-V3 employs the DeepSeekMoE architecture (Dai et al., 2024)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;V3에 사용된 DeepSeekMoE는 전통적인 MoE 기법인 GShard 와는 다르게, 세분화된 전문가들을 사용하며 일부 전문가들을 공유해서 사용한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mjt0C/btsL26eJd02/0Dl1iOG7cXJWn0AkKC1X61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mjt0C/btsL26eJd02/0Dl1iOG7cXJWn0AkKC1X61/img.png&quot; data-alt=&quot;DeepSeekMoE&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mjt0C/btsL26eJd02/0Dl1iOG7cXJWn0AkKC1X61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmjt0C%2FbtsL26eJd02%2F0Dl1iOG7cXJWn0AkKC1X61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;503&quot; height=&quot;284&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;284&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DeepSeekMoE&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 수식은, $u_t$가 FFN의 $t$번째 토큰의 입력을 나타낸다고 가정할 때, FFN의 출력 $h^{\prime}_t$ 를 계산하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{align} &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\mathbf{h}_t^{\prime}&amp;nbsp;&amp;amp;=&amp;nbsp;\mathbf{u}_t&amp;nbsp;+&amp;nbsp;\sum_{i=1}^{N_s}&amp;nbsp;\text{FFN}_i^{(s)}(\mathbf{u}_t)&amp;nbsp;+&amp;nbsp;\sum_{i=1}^{N_r}&amp;nbsp;g_{i,t}&amp;nbsp;\text{FFN}_i^{(r)}(\mathbf{u}_t),&amp;nbsp;\tag{12}&amp;nbsp;\\ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g_{i,t}&amp;nbsp;&amp;amp;=&amp;nbsp;\frac{g_{i,t}'}{\sum_{j=1}^{N_r}&amp;nbsp;g_{j,t}'},&amp;nbsp;\tag{13}&amp;nbsp;\\ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g_{i,t}'&amp;nbsp;&amp;amp;=&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\begin{cases}&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s_{i,t},&amp;nbsp;&amp;amp;&amp;nbsp;s_{i,t}&amp;nbsp;\in&amp;nbsp;\text{Top}k(\{s_{j,t}&amp;nbsp;|&amp;nbsp;1&amp;nbsp;\leq&amp;nbsp;j&amp;nbsp;\leq&amp;nbsp;N_r\},&amp;nbsp;K_r),&amp;nbsp;\\ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0,&amp;nbsp;&amp;amp;&amp;nbsp;\text{otherwise}, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\end{cases}&amp;nbsp;\tag{14}&amp;nbsp;\\ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s_{i,t}&amp;nbsp;&amp;amp;=&amp;nbsp;\sigma(\mathbf{u}_t^\top&amp;nbsp;\mathbf{e}_i),&amp;nbsp;\tag{15} &lt;br /&gt;\end{align}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상세하게 설명하자면 아래와 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$\mathbf{h}_t^{\prime} = \mathbf{u}_t + \sum_{i=1}^{N_s} \text{FFN}_i^{(s)}(\mathbf{u}_t) + \sum_{i=1}^{N_r} g_{i,t} \text{FFN}_i^{(r)}(\mathbf{u}_t)$&lt;/span&gt; : 최종 출력 계산
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$h^{\prime}_t$ : 최종 출력 벡터&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(토큰 $t$에 대한 출력.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;$u_t$ : 입력 벡터 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(토큰 $t$에 대한)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;$FFN_i^{(s)}$ : $i$ 번째 공유 전문가&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Shared Expert)&lt;/span&gt;로, 모든 토큰이 공통으로 사용하는 전문가.&lt;/li&gt;
&lt;li&gt;$FFN_i^{(r)}$ : $i$번째 라우팅 전문가&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Routed Expert)&lt;/span&gt;로, 특정 토큰에 따라 선택되는 전문가.&lt;/li&gt;
&lt;li&gt;$g_{i,t}$ : $i$번째 라우팅 전문가의 가중치. 해당 값은 토큰 $t$와 전문가 $i$의 유사도에 따라 결정.&lt;/li&gt;
&lt;li&gt;$N_s$ : 공유 전문가의 수&lt;/li&gt;
&lt;li&gt;$N_r$ : 라우팅 전문가의 수&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$g_{i,t} = \frac{g_{i,t}'}{\sum_{j=1}^{N_r} g_{j,t}'}$&lt;/span&gt; : 가중치 정규화 방법으로서, 선택된 전문가들의 가중치 합이 1이 되도록 보장하며 출력의 스케일 조정.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$g_{i,t}'= \begin{cases} s_{i,t}, &amp;amp; s_{i,t} \in \text{Top}k(\{s_{j,t} | 1 \leq j \leq N_r\}, K_r), \\ 0, &amp;amp; \text{otherwise}, \end{cases}$&lt;/span&gt; : 토큰 $t$와 각 라우팅 전문가 간의 유사도 점수를 기반으로 상위 $K_r$개의 전문가를 선택한다. 선택된 전문가의 초기 가중치 유사도는 점수 $s_{i,t}$로 설정되고, 나머지 전문가의 초기 가중치는 0로 설정한다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$s_{i,t} = \sigma(\mathbf{u}_t^\top \mathbf{e}_i)$&lt;/span&gt; : 토큰 $t$와 라우팅 전문가 $i$간의 유사도를 계산한다. 이 때 내적값이 클수록 두 벡터가 유사하다는 것을 의미하며, sigmoid&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($\sigma$)&lt;/span&gt; 0~1 범위로 정규화 된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종적으로 정리하자면, DeepSeekMoE는 공유 전문가, 라우팅 전문가를 사용하여 입력 토큰에 따라 다른 전문가를 선택하는 방식으로, 이 선택과정은 유사도 점수를 기반으로 상위 $K_r$개의 전문가를 선택하고, 이들의 출력을 &lt;a href=&quot;https://roseline124.github.io/data-analytics/2019/03/30/ML-Deep-Network.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;가중합&lt;/a&gt;으로 결합한다. 그 후 가중치 정규화를 통해 출력 스케일을 조정하고, $\sigma$ 함수를 통해 유사도 점수를 정규화한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외에도&amp;nbsp;논문에서는&amp;nbsp;적용된&amp;nbsp;여러&amp;nbsp;기법들에&amp;nbsp;대해서&amp;nbsp;설명하고&amp;nbsp;있다.&amp;nbsp;하지만&lt;span&gt;&amp;nbsp;&lt;/span&gt;핵심적인 기법은 MLA와 DeepSeekMoE 기법이기에 나머지 기법들에 대해선 생략한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;2-3.&lt;span&gt;&lt;span&gt; FP8&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;205&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6Masg/btsL2Tl6WV8/ETf4lCPcCjIlyeB5FCeVHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6Masg/btsL2Tl6WV8/ETf4lCPcCjIlyeB5FCeVHk/img.png&quot; data-alt=&quot;Figure 6 ❘ The overall mixed precision framework with FP8 data format. For clarification, only the Linear operator is illustrated&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6Masg/btsL2Tl6WV8/ETf4lCPcCjIlyeB5FCeVHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6Masg%2FbtsL2Tl6WV8%2FETf4lCPcCjIlyeB5FCeVHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;204&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;205&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 6 ❘ The overall mixed precision framework with FP8 data format. For clarification, only the Linear operator is illustrated&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 모델은 여러 버전으로 배포된 것으로 보인다. HuggingFace 에서 Tensor type 이 아래와 같기 때문이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;32&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cd6Pof/btsL1eMo8FD/3x6nakwkhsBCCQyBTa7GV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cd6Pof/btsL1eMo8FD/3x6nakwkhsBCCQyBTa7GV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cd6Pof/btsL1eMo8FD/3x6nakwkhsBCCQyBTa7GV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcd6Pof%2FbtsL1eMo8FD%2F3x6nakwkhsBCCQyBTa7GV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;225&quot; height=&quot;32&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;32&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 BF16 를 사용하는데, 해당 모델에서는 FP8을 사용하면서도 BF16대비 손실오차 0.25% 이하로 유지하는데 성공하였다. 즉, 성능하락은 체감하기 어려운 반면, 메모리 소모량은 크게 줄일 수 있는 방법을 적용하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 결론&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;678&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bF13xC/btsL1FQbTTM/RHJH9NfWzoPI9gQnJMviJK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bF13xC/btsL1FQbTTM/RHJH9NfWzoPI9gQnJMviJK/img.jpg&quot; data-alt=&quot;https://api-docs.deepseek.com/news/news1226&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bF13xC/btsL1FQbTTM/RHJH9NfWzoPI9gQnJMviJK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbF13xC%2FbtsL1FQbTTM%2FRHJH9NfWzoPI9gQnJMviJK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;424&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;678&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://api-docs.deepseek.com/news/news1226&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DeepSeek V3는 그 &lt;span style=&quot;color: #f89009;&quot;&gt;성능도 최고 수준&lt;/span&gt;이지만, 가장 무서운 점은 &lt;span style=&quot;color: #f89009;&quot;&gt;'압도적인 가성비'&lt;/span&gt; 이다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(여기서 말하는 가성비는 '추론' 가성비라 위에서 언급한 의심쩍은 '훈련' 비용과는 다르다.)&lt;/span&gt; 많은 사람들이 중국 제품에 대해 안전하지 못하다는 감정을 느끼면서도 중국 제품을 찾는 이유는 '가성비' 이다. 개인적으로 생각하기에도 3배 이상 저렴하다면, 일상적인 용도로 DeepSeek 제품을 충분히 권장할만 하다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(오히려 권장하지 않는다는게 문제라는 생각이다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한편으로 느끼는 궁금증은 다른 AI 제조사들의 비싼 비용이다. 내가 알기론, 이미 ChatGPT도 MoE를 사용하고 있으며, 추가로 많은 최적화 기법들이 고려되었을 것이다. 하지만 4o는 V3 보다 3배 비싸며, o1은 R1 보다 27배 더 비싸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문을 읽어보면서 느끼길, 논문의 내용을 내가 구현하기에는 무리가 있는 레벨이지만, 결코 OpenAI 가 구현하기에 버거울 수준의 내용은 아니라고 판단했다. 하지만 DeepSeek는 구현했고, OpenAI는 현재까지 구현하지 못했다. 조만간 2주내로 o3, o3-mini 모델이 공개될 예정인데... 잘 나와서 LLM 기술에서 경쟁이 활발해지길 바란다.&lt;/p&gt;</description>
      <category>Artificial Intelligence/Paper Review</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/211</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-DeepSeek-V3-Technical-Report#entry211comment</comments>
      <pubDate>Sun, 26 Jan 2025 22:53:55 +0900</pubDate>
    </item>
    <item>
      <title>[리뷰] DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning</title>
      <link>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-DeepSeek-R1-Incentivizing-Reasoning-Capability-in-LLMs-via-Reinforcement-Learning</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 &lt;a href=&quot;https://www.deepseek.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;DeepSeek&lt;/a&gt; 라는 중국 스타트업에서 제작한 LLM 모델이 뛰어난 성능으로 AI 업계에서 화두가 되고 있다. 해당 업체에서 만든 모델은 대표적으로 `R1` 모델과 `V3` 모델이 존재하는데, `V3` 모델의 경우 ChatGPT, Qwen, LLaMA 와 같은 일반적인 `Transformer` 기반의 LLM 모델이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 `R1` 모델은 논문의 제목을 보면 알 수 있듯 `Reinforcement Learning`을 기반으로 제작된 모델로, 해당 포스팅에서는 `R1` 모델과, &lt;a href=&quot;https://github.com/deepseek-ai/DeepSeek-R1/blob/main/DeepSeek_R1.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;논문&lt;/a&gt;에 관해서 간략히 포스팅 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 서론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강화학습을 LLM에 적용하자는 개념을 DeepSeek 사가 최초로 제안한것은 아니다. 최근 ChatGPT의 유료버전을 사용해 보았다면 `o1` 모델이 활성화 된 것을 확인할 수 있었을 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;489&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blb8CU/btsLUAvj00k/gvbSCNZFpCG0FHw93jPYF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blb8CU/btsLUAvj00k/gvbSCNZFpCG0FHw93jPYF1/img.png&quot; data-alt=&quot;ChatGPT 모델 선택 옵션들&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blb8CU/btsLUAvj00k/gvbSCNZFpCG0FHw93jPYF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fblb8CU%2FbtsLUAvj00k%2FgvbSCNZFpCG0FHw93jPYF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;350&quot; height=&quot;434&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;489&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ChatGPT 모델 선택 옵션들&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`GPT-4o` 모델은 Transformer 모델을 기반으로 작동하지만, `o1` 모델은 강화학습을 기반으로 작동한다. 이는 OpenAI 사의 &lt;a href=&quot;https://openai.com/index/learning-to-reason-with-llms/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Blog&lt;/a&gt;에 기재되어 있는 내용이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Our large-scale `reinforcement learning` algorithm teaches the model how to think productively using its chain of thought in a highly data-efficient training process. We have found that the performance of `o1` consistently improves with more `reinforcement learning` (train-time compute) and with more time spent thinking (test-tiChain&amp;nbsp;of&amp;nbsp;Thoughtme compute). The constraints on scaling this approach differ substantially from those of LLM pretraining, and we are continuing to investigate them.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenAI 측에서는 강화학습을 기반으로 '사고의 연쇄&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Chain of Thought, CoT)&lt;/span&gt;' 방식을 구현하여 큰 성능 향상을 이루어 내었다. 이를 통해 LLM 모델은 아래와 같은 작업들을 수행할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;큰 문제를 작은 문제로 분할해서 생각하는 방법&lt;/li&gt;
&lt;li&gt;실수를 인정하고, 이를 기반으로 수정하는 방법&lt;/li&gt;
&lt;li&gt;&lt;span&gt;현재 접근 방식이 작동하지 않을 때 다른 접근 방식을 시도하는 방법&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 마치 인간이 사고하는 방법과 유사하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 최근까지 어떤 다른 모델도 `o1` 모델과 동등한 수준의 성능을 달성하지 못했다. 반면 `R1` 모델은 최초로 `V3` 기반모델에 순수한 강화학습과 SFT를 적용하여 `o1`모델에 근접한 성능지표를 보여준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2103&quot; data-origin-height=&quot;1260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bperMO/btsLV9inPMn/weFW0apnnAMtBeTktX9HXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bperMO/btsLV9inPMn/weFW0apnnAMtBeTktX9HXk/img.png&quot; data-alt=&quot;Figure 1 ❘ Benchmark performance of DeepSeek-R1.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bperMO/btsLV9inPMn/weFW0apnnAMtBeTktX9HXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbperMO%2FbtsLV9inPMn%2FweFW0apnnAMtBeTktX9HXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;479&quot; data-origin-width=&quot;2103&quot; data-origin-height=&quot;1260&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 1 ❘ Benchmark performance of DeepSeek-R1.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히, 그래프에는 나타나있지 않지만 `V3` 기반모델에 순수한 강화학습을 적용하여 개발한 `DeepSeek-R1-Zero` 모델은 SFT&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Supervised Fine-Tuning)&lt;/span&gt; 같은 작업 없이 `OpenAI-o1-0912` 와 유사한 성능지표를 보여주었으나, 가독성 저하 및 다국어 혼용 문제를 겪었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 문제를 해결하기 위해 DeepSeek 사에서는 Qwen, LLaMA 모델을 통해 추론 능력을 '증류&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Distill)&lt;/span&gt;' 한 뒤&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(32B)&lt;/span&gt; SFT를 적용하여 모델을 완성했다. 가장 왼쪽에 존재하는 `R1` 모델은 MoE 모델로서 증류 과정을 거치지 않고, 강화학습과 SFT 만을 통해 반복 학습되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 고무적인 사실은 강화학습 만으로 학습시킨 `R1-Zero` 모델이 매우 유망한 성능을 보여준다는 점이다. SFT는 매우 큰 인건비를 지출하게 된다.그런데 오직 소량의 Cold-Start Data 와 강화학습만으로 학습한 모델의 성능이, 최신 SFT 튜닝모델 대비 3개월 정도의 뒤쳐진 성능을 보여준다는건 매우 큰 성과이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것이 해당 논문의 핵심적인 요약이다. 비록 &lt;a href=&quot;https://chat.deepseek.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;chat.deepseek.com&lt;/a&gt; 에서 운용하는 모델은 SFT를 거친 모델이지만, 단순 강화학습 만으로도 이렇게 뛰어난 성능의 모델을 제작할 수 있음을 오픈소스로 증명해 낸 것이 `DeepSeek-R1-Zero` 모델이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 중요한 내용은 명시되어 있지 않다.&lt;br /&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문에서 DeepSeek 모델의 '보상함수' 와 같은 상세한 구현 방법을 기재하지 않았다. 대략적으로 `2.2.2. Reward Modeling` 섹션에서는 아래와 같이 기술되어 있는데.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Accuracy rewards: The accuracy reward model evaluates whether the response is correct. For example, in the case of math problems with deterministic results, the model is required to provide the final answer in a specified format (e.g., within a box), enabling reliable rule-based verification of correctness. Similarly, for LeetCode problems, a compiler can be used to generate feedback based on predefined test cases.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수학문제나, LeetCode 문제와 같은 작업의 경우 최종적인 정답 여부를 rule-base 기반하에 판단한다고 기재되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 위와 같이 대략적으로만 기재해 두었을 뿐, 구체적으로 어떻게 구현하는지, 또 왜 이러한 접근 방식이 효율적인지 심층적인 원리나 분석은 논문에 밝히지 않고 있다. 물론, 아래와 같은 GRPO 수식은 나열하고 있지만.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ \mathcal{J}_{\text{GRPO}}(\theta) = \mathbb{E}\left[ \frac{1}{G} \sum_{i=1}^{G} \left( \min\left( \frac{\pi_\theta(o_i|q)}{\pi_{\theta_{\text{old}}}(o_i|q)} A_i, \text{clip}\left( \frac{\pi_\theta(o_i|q)}{\pi_{\theta_{\text{old}}}(o_i|q)}, 1-\epsilon, 1+\epsilon \right) A_i \right) - \beta \mathbb{D}_{\text{KL}}(\pi_\theta || \pi_{\text{ref}}) \right) \right] $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GRPO의 목표는 새로운 정책&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($\pi_\theta(o_i|q)$)&lt;/span&gt;이 이전 정책&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($ \pi_{\theta_{\text{old}}}(o_i|q)$)&lt;/span&gt; 보다 높은 보상을 얻도록 업데이트 하는 과정을 유도하여 좋은 결과를 내도록 하는것이 목적이다. 그런데 문제는 '&lt;span style=&quot;color: #f89009;&quot;&gt;어떤 판단 기준으로 새로운 정책에 더 높은 보상을 줄 것인가?&lt;/span&gt;' 에 대한 내용이 누락되어 있다. 보상로직이 핵심인데, 이 부분이 논문에 명시되어 있지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. MoE&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부가적으로 해당 모델에서는 MoE가 적용되었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1876&quot; data-origin-height=&quot;1528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4W9g3/btsLUSvbUlb/zsSmkkgLdmboK6CTeES7B1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4W9g3/btsLUSvbUlb/zsSmkkgLdmboK6CTeES7B1/img.png&quot; data-alt=&quot;Table 4 ❘ Comparison between DeepSeek-R1 and other representative models.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4W9g3/btsLUSvbUlb/zsSmkkgLdmboK6CTeES7B1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4W9g3%2FbtsLUSvbUlb%2FzsSmkkgLdmboK6CTeES7B1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;652&quot; data-origin-width=&quot;1876&quot; data-origin-height=&quot;1528&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Table 4 ❘ Comparison between DeepSeek-R1 and other representative models.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4번 테이블에서 DeepSeek 의 모델들을 살펴보면 재미있는 부분이 눈에 띈다. 바로 MoE 라고 하는 부분으로서, 총 파라미터 양은 671B로 매우 거대하지만, 실제로 순간적으로 활성화 되는 Activated Params 는 37B에 불과하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.nvidia.com/ko-kr/blog/applying-mixture-of-experts-in-llm-architectures/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MoE 기술&lt;/a&gt;을 간단하게 요약하자면 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;하나의 연산과정을 여러개의 전문가&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(expert)&lt;/span&gt; 하위 네트워크로 분할하는 방법.&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분할된 네트워크는 각각 독립적으로 자체적인 연산을 수행하며, 그 결과를 결합하여 MoE 레이어의 최종 출력을 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI를 공부해 보았다면 '앙상블 기법' 이라는 기법을 들어 보았을것이다. 앙상블 기법의 경우 관여하는 모든 모델이 전체 입력에 참여해서 최종적인 추론결과를 내놓는 다소 고전적인 기법이라면, MoE 기법은 입력 토큰마다 특정 하위 네트워크가 선택적으로 활성화되어 보다 효율적인 추론이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;적절한 비유가 아니라고 지적할 수도 있겠지만, MoE 기법은 앙상블 기법을 크게 고도화하여 하나의 신경망 내에 구현한 구조라고 비유할 수 있겠다.&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 결론&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;789&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1T1SH/btsL1p7T9TB/AI5Z1NymH1ZU7x835D1fL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1T1SH/btsL1p7T9TB/AI5Z1NymH1ZU7x835D1fL0/img.png&quot; data-alt=&quot;https://api-docs.deepseek.com/news/news250120&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1T1SH/btsL1p7T9TB/AI5Z1NymH1ZU7x835D1fL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1T1SH%2FbtsL1p7T9TB%2FAI5Z1NymH1ZU7x835D1fL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;584&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;789&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://api-docs.deepseek.com/news/news250120&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;627&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDi5w6/btsL3ieWP6M/rayphvKYXhAalUIwxfkltk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDi5w6/btsL3ieWP6M/rayphvKYXhAalUIwxfkltk/img.png&quot; data-alt=&quot;https://api-docs.deepseek.com/news/news250120&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDi5w6/btsL3ieWP6M/rayphvKYXhAalUIwxfkltk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDi5w6%2FbtsL3ieWP6M%2FrayphvKYXhAalUIwxfkltk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;392&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;627&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://api-docs.deepseek.com/news/news250120&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;DeepSeek R1 모델은 o1 모델과 동등한 성능을 제공하며, 추론 비용은 ${1 \over 27.3}$ 이다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 &lt;a href=&quot;https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-DeepSeek-V3-Technical-Report?category=1111972&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;기반이 되는 V3 모델&lt;/a&gt;의 추론 비용이 저렴한것이 가장 큰 원인으로 추정된다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Chain of Thought)&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 소감&lt;br /&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 논문을 읽어보며, 반쪽짜리 라는 감을 지울 순 없었지만&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(모델은 훌륭하다. 많은 제작 과정을 숨겼을뿐...)&lt;/span&gt;, Transformer 기반 모델에 강화학습을 적용하여 튜닝을 거친것 만으로 이렇게 뛰어난 성능이 도출된다는점이 흥미로웠다. 실제로 DeepSeek 모델을 테스트 해 본 결과 OpenAI 사의 GPT 모델과 성능 차이를 느끼지 못했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 나는 이 논문의 초입부를 읽기 시작한 뒤, 이제 Transformer 기반 모델이 더이상 LLM에서 필요 없어진것이 아닐까? 라는 생각을 잠깐 했었지만. 아래와 같은 장단점들이 존재한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Transformer 모델이 더 효율적이며&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(without using CoT)&lt;/span&gt;, 창의적인 결과물을 내 놓을 수 있다.&lt;/li&gt;
&lt;li&gt;강화학습 기반의 모델들은 정답이 명확히 정해진 작업들에서 더 우수한 성능을 보여주나, 그 원리 특성상&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(CoT) &lt;/span&gt;속도가 느리다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더하여 강화학습으로 만들어진 LLM 모델은, &lt;span style=&quot;color: #f89009;&quot;&gt;Transformer 모델을 기반으로&lt;/span&gt; 강화학습을 통해 튜닝을 거친것이므로 여전히 씨앗 역할을 하는 Transformer 모델은 중요하다.&lt;/p&gt;</description>
      <category>Artificial Intelligence/Paper Review</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/210</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-DeepSeek-R1-Incentivizing-Reasoning-Capability-in-LLMs-via-Reinforcement-Learning#entry210comment</comments>
      <pubDate>Wed, 22 Jan 2025 15:13:13 +0900</pubDate>
    </item>
    <item>
      <title>Ubuntu WOL 활성화</title>
      <link>https://cypsw.tistory.com/entry/Ubuntu-WOL-%ED%99%9C%EC%84%B1%ED%99%94</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;현재 나는 Windows / Ubuntu 듀얼부팅 환경에서 GRUB를 통해 OS를 선택하는 환경으로 구성해 두었다. 이 때 WOL을 사용하려면 Windows, Ubuntu 두 OS 모두에 WOL 설정이 되어 있어야만 원활하게 WOL을 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 포스팅에선 기본적인 BIOS 셋팅과, Windows 환경에서의 WOL 설정법, 그리고 네트워크 장비의 WOL 설정 방법에 대해서는 생략한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 필요 프로그램 설치&lt;/h2&gt;
&lt;pre id=&quot;code_1735953097227&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt-get install net-tools ethtool wakeonlan&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`net-tools`, `ethtool`, `wakeonlan` 3가지를 설치해 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Network interface 확인&lt;/h2&gt;
&lt;pre id=&quot;code_1735952978142&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ ifconfig
enp7s1: flags=4163&amp;lt;UP,BROADCAST,RUNNING,MULTICAST&amp;gt;  mtu 1500
        inet 192.168.100.88  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::e9d:92ff:fe83:6c6f  prefixlen 64  scopeid 0x20&amp;lt;link&amp;gt;
        ether 0c:9d:92:83:6c:6f  txqueuelen 1000  (Ethernet)
        RX packets 6137  bytes 6958570 (6.9 MB)
        RX errors 0  dropped 1  overruns 0  frame 0
        TX packets 3745  bytes 733228 (733.2 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device memory 0xfcc00000-fcc1ffff  

lo: flags=73&amp;lt;UP,LOOPBACK,RUNNING&amp;gt;  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10&amp;lt;host&amp;gt;
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 508  bytes 52750 (52.7 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 508  bytes 52750 (52.7 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 `ifconfig` 명령어를 통해 네트워크 인터페이스 이름을 확인한다. 나의 경우 `enp7s1`을 메인으로 사용하고 있음을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. WOL 활성화&lt;/h2&gt;
&lt;pre id=&quot;code_1735953179767&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo ethtool -s **** wol g
sudo ethtool ****&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`****`부분을 위에서 체크한 본인의 네트워크 인터페이스 이름으로 교체한다. 명령어를 수행하고 나면 아래와 같이 `Wake-on: g`를 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cI54qZ/btsLEoHeoOp/0z3RKh2Wbw1mpk2FSbhhyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cI54qZ/btsLEoHeoOp/0z3RKh2Wbw1mpk2FSbhhyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cI54qZ/btsLEoHeoOp/0z3RKh2Wbw1mpk2FSbhhyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcI54qZ%2FbtsLEoHeoOp%2F0z3RKh2Wbw1mpk2FSbhhyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;505&quot; height=&quot;264&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;264&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4. 재부팅시 WOL 자동 활성화.&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Netplan 을 통해서 재부팅시 자동으로 WOL 이 활성화 되도록 조치한다. 아래 명령어를 파일이 존재하는지 찾는다.&lt;/p&gt;
&lt;pre id=&quot;code_1735953404411&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo ls /etc/netplan&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 디렉토리에 위치한 폴더가 존재한다면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;790&quot; data-origin-height=&quot;103&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BBdDO/btsLC5hwzqq/jY3dgzGVBH5kFTxyVTfaWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BBdDO/btsLC5hwzqq/jY3dgzGVBH5kFTxyVTfaWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BBdDO/btsLC5hwzqq/jY3dgzGVBH5kFTxyVTfaWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBBdDO%2FbtsLC5hwzqq%2FjY3dgzGVBH5kFTxyVTfaWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;78&quot; data-origin-width=&quot;790&quot; data-origin-height=&quot;103&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 파일 내부에서 위에서 정의한 네트워크 인터페이스 이름인 `****`가 존재하는지 체크한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsZF7m/btsLCKq9kOh/YhQ9wFdwzgWqK2aMshdFlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsZF7m/btsLCKq9kOh/YhQ9wFdwzgWqK2aMshdFlK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsZF7m/btsLCKq9kOh/YhQ9wFdwzgWqK2aMshdFlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsZF7m%2FbtsLCKq9kOh%2FYhQ9wFdwzgWqK2aMshdFlK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;557&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;존재한다면 들여쓰기 규칙을 맞춰서 아래 이미지와 같이 `wakeonlan: true` 를 추가해 준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6APCp/btsLEhg2yhi/25eMm9vD2qbKX7TQdAQHUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6APCp/btsLEhg2yhi/25eMm9vD2qbKX7TQdAQHUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6APCp/btsLEhg2yhi/25eMm9vD2qbKX7TQdAQHUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6APCp%2FbtsLEhg2yhi%2F25eMm9vD2qbKX7TQdAQHUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;557&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 파일이 존재하지 않는다면, 해당 위치에 `*.yaml` 파일을 생성해서 위 규칙대로 만들면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 설정 적용&lt;/h2&gt;
&lt;pre id=&quot;code_1735953733596&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo netplan apply&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 재부팅후 적용되었는지 체크&lt;/h2&gt;
&lt;pre id=&quot;code_1735953763106&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo ethtool ****&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cI54qZ/btsLEoHeoOp/0z3RKh2Wbw1mpk2FSbhhyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cI54qZ/btsLEoHeoOp/0z3RKh2Wbw1mpk2FSbhhyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cI54qZ/btsLEoHeoOp/0z3RKh2Wbw1mpk2FSbhhyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcI54qZ%2FbtsLEoHeoOp%2F0z3RKh2Wbw1mpk2FSbhhyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;505&quot; height=&quot;264&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;264&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`Wake-on: g` 가 표기되어 있다면 제대로 적용된 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 `ethtool` 명령어의 경우 `sudo`를 통해 `root`로 적용시키지 않는다면 `Wake-on: g` 가 표기되지 않으니 유의하기 바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Operating System/Linux</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/209</guid>
      <comments>https://cypsw.tistory.com/entry/Ubuntu-WOL-%ED%99%9C%EC%84%B1%ED%99%94#entry209comment</comments>
      <pubDate>Sat, 4 Jan 2025 10:25:36 +0900</pubDate>
    </item>
    <item>
      <title>RX6800+ROCm VS Tesla T4+CUDA</title>
      <link>https://cypsw.tistory.com/entry/RX6800ROCm-VS-Tesla-T4Cuda</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cypsw.tistory.com/entry/WSL2-%EC%97%90%EC%84%9C-ROCm-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 포스팅&lt;/a&gt;을 통해 `RX6800 + WSL2 + ROCm` 의 작동불가를 확인했다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 &lt;a href=&quot;https://potatosalad775.tistory.com/14&quot;&gt;몇몇 포스팅들을 참고&lt;/a&gt;한 결과 네이티브한 Ubuntu 환경에서 작동함을 확인하였고&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;직접 Ubuntu 24.04를 설치하여 실제 ROCm을 구동해 보았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1580&quot; data-origin-height=&quot;590&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n8EOC/btsLBY3cjYC/ofbk0oFn97ZW4ubIykv99k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n8EOC/btsLBY3cjYC/ofbk0oFn97ZW4ubIykv99k/img.png&quot; data-alt=&quot;공식적으로 WSL2를 포함해 ROCm 을 지원하는 Radeon GPU 목록.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n8EOC/btsLBY3cjYC/ofbk0oFn97ZW4ubIykv99k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn8EOC%2FbtsLBY3cjYC%2Fofbk0oFn97ZW4ubIykv99k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;299&quot; data-origin-width=&quot;1580&quot; data-origin-height=&quot;590&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;공식적으로 WSL2를 포함해 ROCm 을 지원하는 Radeon GPU 목록.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 ROCm을 통해 `RX6800` 의 Pytorch 신경망 처리와&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Colab 에서 운용되는 `Tesla T4` GPU 간의 연산성능차이를 비교해 보고자 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;참고로 `Tesla T4` 의 성능은 내 체감상 `RTX 3070` 대비 약 30% 정도 더 느린 속도를 보여준다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;1. 신경망 벤치.&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;소스코드는 워낙 풀려있는게 많기에 GPT o1을 통해서 생성해 줬다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;검토해 봐도 큰문제가 없어 보이기에 그대로 사용하였다.&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;Code.py&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1735648205985&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import torch
import torch.nn as nn
import torch.optim as optim
import time

def main():
    # GPU 사용 가능 여부 확인
    if not torch.cuda.is_available():
        print(&quot;CUDA가 사용 불가능합니다. ROCm이 제대로 설치되었는지 확인해주세요.&quot;)
        return

    device = torch.device(&quot;cuda&quot;)
    print(f&quot;사용 중인 디바이스: {torch.cuda.get_device_name(device)}&quot;)

    # 대규모 신경망 정의
    class LargeNet(nn.Module):
        def __init__(self):
            super(LargeNet, self).__init__()
            self.layers = nn.Sequential(
                nn.Linear(10000, 5000),
                nn.ReLU(),
                nn.Linear(5000, 5000),
                nn.ReLU(),
                nn.Linear(5000, 5000),
                nn.ReLU(),
                nn.Linear(5000, 1000),
                nn.ReLU(),
                nn.Linear(1000, 100)
            )

        def forward(self, x):
            return self.layers(x)

    model = LargeNet().to(device)

    # 손실 함수 및 옵티마이저 설정
    criterion = nn.MSELoss()
    optimizer = optim.Adam(model.parameters(), lr=0.001)

    # 무작위 데이터 생성
    batch_size = 128
    input_size = 10000
    output_size = 100
    num_batches = 10000  # 총 배치 수

    # 데이터 로더 대신 직접 생성
    def get_random_batch():
        inputs = torch.randn(batch_size, input_size, device=device)
        targets = torch.randn(batch_size, output_size, device=device)
        return inputs, targets

    # 학습 시작
    print(&quot;대규모 신경망 학습을 시작합니다...&quot;)
    start_time = time.time()

    for batch_idx in range(1, num_batches + 1):
        inputs, targets = get_random_batch()

        # 순전파
        outputs = model(inputs)
        loss = criterion(outputs, targets)

        # 역전파 및 최적화
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if batch_idx % 1000 == 0:
            elapsed = time.time() - start_time
            print(f&quot;{batch_idx}번째 배치 처리 완료. 누적 시간: {elapsed:.2f}초, 현재 손실: {loss.item():.4f}&quot;)

    end_time = time.time()
    total_time = end_time - start_time
    print(f&quot;대규모 신경망 학습 완료. 총 소요 시간: {total_time / 60:.2f}분&quot;)

    # 최종 손실 출력 (선택 사항)
    # print(f&quot;최종 손실: {loss.item()}&quot;)

if __name__ == &quot;__main__&quot;:
    main()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;2221&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yLFXi/btsLAYQSSWy/pQKaJECgZH73VdMEh3Nuo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yLFXi/btsLAYQSSWy/pQKaJECgZH73VdMEh3Nuo1/img.png&quot; data-alt=&quot;RX6800&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yLFXi/btsLAYQSSWy/pQKaJECgZH73VdMEh3Nuo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyLFXi%2FbtsLAYQSSWy%2FpQKaJECgZH73VdMEh3Nuo1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;592&quot; data-filename=&quot;edited_blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;2221&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;RX6800&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;신경망 학습을 진행하는데 `4.6분`이 소모되었다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;GPU 부하 확인 여부는 `radeontop` 이라는 소프트웨어를 통해 확인하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1845&quot; data-origin-height=&quot;1021&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hkn8V/btsLA0upwTi/0FUS1Tw0uhsW1XpqONrMi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hkn8V/btsLA0upwTi/0FUS1Tw0uhsW1XpqONrMi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hkn8V/btsLA0upwTi/0FUS1Tw0uhsW1XpqONrMi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHkn8V%2FbtsLA0upwTi%2F0FUS1Tw0uhsW1XpqONrMi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;443&quot; data-origin-width=&quot;1845&quot; data-origin-height=&quot;1021&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;약 4.2GB 의 VRAM 을 사용하며, Graphic pipe 부하량 100% 를 보여준다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;편의를 위해 GUI Ubuntu 를 사용하고 있기에, 평시 VRAM 사용량이 2.7GB 남짓이므로,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;실질적으로 해당 코드를 구동하는데 사용되는 VRAM은 1.5GB 정도이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;다음으로 Google Colab 에서 `Tesla T4` 를 통해 학습을 진행해 보았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;880&quot; data-origin-height=&quot;1414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dy1uxo/btsLCsQtJS8/HpYVeUG8fBkxTCXK6cjmfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dy1uxo/btsLCsQtJS8/HpYVeUG8fBkxTCXK6cjmfk/img.png&quot; data-alt=&quot;Tesla T4 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dy1uxo/btsLCsQtJS8/HpYVeUG8fBkxTCXK6cjmfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdy1uxo%2FbtsLCsQtJS8%2FHpYVeUG8fBkxTCXK6cjmfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;550&quot; height=&quot;884&quot; data-origin-width=&quot;880&quot; data-origin-height=&quot;1414&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Tesla T4 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;`T4` 는 `7.58분`의 결과를 보여주고 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;즉 `RX6800`의 연산성능은 체감상 `RTX3070`과 동급인데다, VRAM이 16GB 이기에 더 강점이 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;참고로 동일 코드, CPU `5700x3d` 를 기준으로는&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;831&quot; data-origin-height=&quot;820&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NYqT5/btsLClKVDRv/DPM7eCMRMK1akZA2rmxW4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NYqT5/btsLClKVDRv/DPM7eCMRMK1akZA2rmxW4k/img.png&quot; data-alt=&quot;5700X3d CPU&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NYqT5/btsLClKVDRv/DPM7eCMRMK1akZA2rmxW4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNYqT5%2FbtsLClKVDRv%2FDPM7eCMRMK1akZA2rmxW4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;612&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;831&quot; data-origin-height=&quot;820&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;5700X3d CPU&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;무려 `75분`이 걸린다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;2. Whisper large v3&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Whisper large v3 에서도 같은 방식으로 테스트를 진행해 보았다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;테스트 데이터는 `distil-whisper/librispeech_long` 음성 데이터 샘플을 기준으로 하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Wbs6p/btsLBinJr1T/niqXPkP8c8sOkeMfMUpwok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Wbs6p/btsLBinJr1T/niqXPkP8c8sOkeMfMUpwok/img.png&quot; data-origin-width=&quot;1201&quot; data-origin-height=&quot;1045&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;35.49&quot; data-filename=&quot;blob&quot; width=&quot;800&quot; height=&quot;696&quot; style=&quot;width: 35.0739%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Wbs6p/btsLBinJr1T/niqXPkP8c8sOkeMfMUpwok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWbs6p%2FbtsLBinJr1T%2FniqXPkP8c8sOkeMfMUpwok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1201&quot; height=&quot;1045&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NOuOA/btsLDO6lo5p/mox5p0KUCiKI01shHvduV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NOuOA/btsLDO6lo5p/mox5p0KUCiKI01shHvduV1/img.png&quot; width=&quot;800&quot; height=&quot;383&quot; data-origin-width=&quot;982&quot; data-origin-height=&quot;470&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; style=&quot;width: 63.7633%;&quot; data-widthpercent=&quot;64.51&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NOuOA/btsLDO6lo5p/mox5p0KUCiKI01shHvduV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNOuOA%2FbtsLDO6lo5p%2Fmox5p0KUCiKI01shHvduV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;982&quot; height=&quot;470&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;RX6800 ROCm with Whisper Large v3&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;`RX6800` 기준 VRAM 소모량은 3.5GB 남짓, 소요시간은 `8.6초`이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2YaBG/btsLDNsPpJ8/SnkqyXyPXdHspqXU5rnrV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2YaBG/btsLDNsPpJ8/SnkqyXyPXdHspqXU5rnrV1/img.png&quot; data-alt=&quot;Tesla T4 CUDA with Whisper Large v3&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2YaBG/btsLDNsPpJ8/SnkqyXyPXdHspqXU5rnrV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2YaBG%2FbtsLDNsPpJ8%2FSnkqyXyPXdHspqXU5rnrV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;284&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;362&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Tesla T4 CUDA with Whisper Large v3&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;반면 `T4` 에서 소요시간은 `9.01초` 이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;3. Qwen2.5-7B-Instruct&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Qwen 2.5 는 llama 와 같은 Open LLM 모델이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;중국 Alibaba 측에서 개발하였으며,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;매 버전 업데이트 마다 동급의 llama 대비 우수하기에 좋아하는 AI 모델이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;7B를 선택한 이유는, BF16 양자화 수준이 16GB VRAM 으로 구동가능한 한계치이기 때문이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아래 코드를 통해 `RX6800`과 `T4` 에서 각각 생성시간이 얼마나 되는지 체크해 보았다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Qwen 2.5 는 한국어를 지원하기에 프롬프트를 직접 한국어로 기입했다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1735842876041&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from transformers import AutoModelForCausalLM, AutoTokenizer
import time

model_name = &quot;Qwen/Qwen2.5-7B-Instruct&quot;

model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype=&quot;auto&quot;,
    device_map=&quot;auto&quot;
)
tokenizer = AutoTokenizer.from_pretrained(model_name)

time_start = time.time()
prompt = &quot;우주의 시작은 어떻게 시작되었는지 상세하게 설명 해 줄 수 있니?&quot;
messages = [
    {&quot;role&quot;: &quot;system&quot;, &quot;content&quot;: &quot;You are Qwen, created by Alibaba Cloud. You are a helpful assistant.&quot;},
    {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: prompt}
]
text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors=&quot;pt&quot;).to(model.device)

generated_ids = model.generate(
    **model_inputs,
    max_new_tokens=512
)
generated_ids = [
    output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]

response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]

time_end = time.time()

print(response)
print(f&quot;{time_end - time_start:.5f} sec&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;생성 결과는 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1735842984651&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-RX6800-
우주의 시작, 즉 대폭발(The Big Bang)이 어떻게 일어났는지에 대한 우리의 이해는 여전히 진행 중이며 과학자들은 이 사건을 매우 복잡하고 미묘한 과정으로 설명합니다. 대폭발 이론은 우주의 시작과 그 이후의 발전을 설명하는 가장 잘 입증된 이론입니다. 그러나 이 주제는 아직 완벽히 이해되지 않은 부분이 많습니다.

### 대폭발 이론

1. **시작**: 약 138억 년 전, 우주는 무한히 작은 점(싱글톤)에서 출발했습니다. 이 점은 무한히 밀도가 높았고 온도도 무한히 높았습니다. 이 점에서 모든 시간과 공간이 시작되었습니다.

2. **확장**: 이 점에서 갑작스럽게 폭발하여 확장되기 시작했습니다. 이 확장은 초기에는 매우 빠르게 이루어졌습니다. 초기 몇 초 동안, 우주가 빛보다 빠르게 확장되었다는 개념이 존재하며, 이는 &quot;루비코 경계&quot;라고 불립니다.

3. **냉각과 구조 형성**: 초기의 높은 온도와 밀도는 시간이 지남에 따라 냉각되면서 물질의 구조를 형성하였습니다. 중성자, 프로톤, 엘리트론 등 원소들이 생성되었으며, 이들 원소는 더 나중에 별과 행성, 그리고 우리 같은 생명체를 이루는 원소로 발전할 것입니다.

4. **대칭성 깨짐**: 초기 우주에서는 다양한 대칭성이 있었지만, 시간이 지남에 따라 이러한 대칭성이 깨져서 우리가 경험하는 물리 법칙이 형성되었습니다.

5. **대폭발 이후의 역사**: 대폭발 이후 몇 억 년 동안, 중력으로 인해 물질들이 집합하여 별과 은하계를 형성했습니다. 지구는 약 46억 년 전에 형성되었으며, 생명은 몇 억 년 후에 나타났습니다.

### 현재 연구

- **다크 에너지와 다크 물질**: 현재 우주의 확장


-Tesla T4-

우주의 시작은 대폭발 이론, 즉 우주 대폭발 혹은 빅뱅 이론을 통해 설명됩니다. 이 이론은 현재 가장 널리 받아들여지는 우주의 초기 상태와 진화 과정에 대한 설명입니다. 하지만 이 이론은 매우 복잡하고 미지의 영역이 많습니다. 아래에 주요 내용을 간략히 설명하겠습니다:

1. **대폭발 이론의 기본 개념**: 
   - 약 138억 년 전, 우주는 초온고밀도의 상태에서 불어나기 시작했다.
   - 이 초기 상태에서는 모든 물질과 에너지가 무한히 높은 온도와 밀도를 가진 점으로 존재했다.

2. **초기 상태**:
   - 초기 우주는 매우 작은 공간 내에서 무한히 높은 온도와 밀도를 가진 상태였습니다. 이 상태는 '싱크로마시'(Singularity)라고도 부릅니다.
   - 이 시점에서 물질과 에너지가 구분되지 않았으며, 시간과 공간 자체가 아직 존재하지 않았습니다.

3. **대폭발의 발생**:
   - 어떤 이유로 인해 이 초온고밀도의 상태가 불어나기 시작했을 때, 초당 수십억 킬로미터의 속도로 확장되기 시작했습니다.
   - 이 과정은 매우 빠르게 진행되었고, 초기 몇 분 동안에는 핵 합성 과정이 일어나서 중소량의 원소들이 형성되었습니다.

4. **확장 과정**:
   - 대폭발 이후, 우주는 계속해서 확장하고 있습니다.
   - 이 과정에서 온도가 낮아지고 밀도가 감소하면서 우주가 더 큰 공간으로 확장됩니다.
   - 현재까지도 우주는 지속적으로 확장되고 있으며, 이 확장 속도는 가속화되고 있습니다.

5. **현재 이해도**:
   - 대폭발 이론은 많은 실험과 관측 결과를 통해 검증되었지만, 여전히 많은 미지의 영역이 남아 있습니다.
   - 예를 들어, 대폭발 이론은 우주의 초기 상태를 설명&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bK1j40/btsLDmpbkYS/noipMnlj7gYkJgCq6HgC7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bK1j40/btsLDmpbkYS/noipMnlj7gYkJgCq6HgC7K/img.png&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;785&quot; data-is-animation=&quot;false&quot; style=&quot;width: 50.3359%; margin-right: 10px;&quot; data-widthpercent=&quot;50.93&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bK1j40/btsLDmpbkYS/noipMnlj7gYkJgCq6HgC7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbK1j40%2FbtsLDmpbkYS%2FnoipMnlj7gYkJgCq6HgC7K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;623&quot; height=&quot;785&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tueeu/btsLC6z4zKG/jHq6D6KHaRB16Zyl72fcJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tueeu/btsLC6z4zKG/jHq6D6KHaRB16Zyl72fcJ1/img.png&quot; data-origin-width=&quot;546&quot; data-origin-height=&quot;714&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;49.07&quot; style=&quot;width: 48.5013%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tueeu/btsLC6z4zKG/jHq6D6KHaRB16Zyl72fcJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftueeu%2FbtsLC6z4zKG%2FjHq6D6KHaRB16Zyl72fcJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;546&quot; height=&quot;714&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;left : RX6800, Right : Tesla T4&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;생성된 토큰수는 5% 미만의 차이를 보이며, 같은 Pre-Trained 모델을 기반으로 Inference 하는것이므로&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;답변 품질을 비교하는것은 무의미하다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;생성 시간 비교에 의미를 두어야 하며 `RX6800`이 `T4` 대비 20% 더 빠른것을 확인할 수 있다.&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(25/08/04 설명 추가: 당시 output token per second를 비교하지 못했습니다.)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;4. 결론.&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;두가지 간단한 테스트 결과를 보면, ROCm 을 충분히 AI 공부용으로 사용할 수 있다고 생각한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;다만 `RX6800 + ROCm` 을 사용하며 딱 한가지 거슬리는 부분이라 하면,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;`RX6800` 자체가 official 하게 ROCm 지원 대상이 아니라는 점이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;만약 반드시 Radeon 을 구입하여야 하는데 AI 역시 염두에 두고 있다면&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(이럴일이 있나 싶지만.)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;공식적으로 지원되는 `7900GRE` 상위모델이나, 곧 출시될 `RX9000` 번대를 고려해보길 바란다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;지원 GPU 들은 WSL2 와 함께 사용할 수 있어서 특히 더 유용하다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그 외에 RDNA2 이상 버전의 GPU를 가지고 있는 사람들은&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;'이런 대안도 있구나' 정도로 봐주는편이 좋겠다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;5. Tensorflow 사용시 주의사항.&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;여담으로 현재 `ROCm + Pytorch`는 Ubuntu 24.04 버전을 잘 지원하는 반면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;`ROCm + Tensorflow` 는 Ubuntu 24.04 버전을 제대로 지원하지 못한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;물론 24.04 도 출시된지 1년이 다 되어가니, 조만간 Tensorflow 를 지원하겠지만&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;2025년 상반기에 ROCm 을 사용할 계획이 있다면, 22.04 버전을 좀 더 권장드린다.&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Artificial Intelligence/Preferences</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/208</guid>
      <comments>https://cypsw.tistory.com/entry/RX6800ROCm-VS-Tesla-T4Cuda#entry208comment</comments>
      <pubDate>Tue, 31 Dec 2024 21:45:38 +0900</pubDate>
    </item>
    <item>
      <title>Windows 블루스크린 분석하기</title>
      <link>https://cypsw.tistory.com/entry/Windows-%EB%B8%94%EB%A3%A8%EC%8A%A4%ED%81%AC%EB%A6%B0-%EB%B6%84%EC%84%9D%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 블루스크린은 커널모드에서 문제가 생겨 발생한다. 내 경험상의 원인은 대부분 Windows 자체가 아니라 Intel, AMD, Nvidia, Realtek ... 등에서 만든 드라이버 문제로 인해서 발생한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bl6s9F/btsKoN9JgGN/kI2HM0ucnzmwtuCXv0tdzk/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bl6s9F/btsKoN9JgGN/kI2HM0ucnzmwtuCXv0tdzk/img.webp&quot; data-alt=&quot;블루스크린 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bl6s9F/btsKoN9JgGN/kI2HM0ucnzmwtuCXv0tdzk/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbl6s9F%2FbtsKoN9JgGN%2FkI2HM0ucnzmwtuCXv0tdzk%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;600&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;블루스크린 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 블루스크린이 발생한뒤 분석하는법을 약 3달쯤 알았는데, 오늘 또 블루스크린이 발생했다&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(...)&lt;/span&gt; 3달이나 지나 방법을 또 까먹어 이것저것 찾아보았는데, 이럴바에 내 블로그에 올려두는것이 속 편할듯 하여 포스팅을 쓴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Dell의 메뉴얼 참조&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1730210846468&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Windows 디버거를 사용하여 블루 스크린 문제를 해결하는 방법 | Dell 대한민국&quot; data-og-description=&quot;지침 컴퓨터에 블루 스크린이 나타나는 경우 발생한 상황을 알아내고 문제를 해결하며 재발을 방지하려면 어떻게 해야 할까요? 이 상황에서는 메모리 덤프 파일이 유용할 수 있습니다. 메모리 &quot; data-og-host=&quot;www.dell.com&quot; data-og-source-url=&quot;https://www.dell.com/support/kbdoc/ko-kr/000149411/windows-%EB%94%94%EB%B2%84%EA%B1%B0%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EB%B8%94%EB%A3%A8-%EC%8A%A4%ED%81%AC%EB%A6%B0-%EB%AC%B8%EC%A0%9C%EB%A5%BC-%ED%95%B4%EA%B2%B0%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95&quot; data-og-url=&quot;https://www.dell.com/support/kbdoc/ko-kr/000149411/windows-%EB%94%94%EB%B2%84%EA%B1%B0%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EB%B8%94%EB%A3%A8-%EC%8A%A4%ED%81%AC%EB%A6%B0-%EB%AC%B8%EC%A0%9C%EB%A5%BC-%ED%95%B4%EA%B2%B0%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.dell.com/support/kbdoc/ko-kr/000149411/windows-%EB%94%94%EB%B2%84%EA%B1%B0%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EB%B8%94%EB%A3%A8-%EC%8A%A4%ED%81%AC%EB%A6%B0-%EB%AC%B8%EC%A0%9C%EB%A5%BC-%ED%95%B4%EA%B2%B0%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.dell.com/support/kbdoc/ko-kr/000149411/windows-%EB%94%94%EB%B2%84%EA%B1%B0%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EB%B8%94%EB%A3%A8-%EC%8A%A4%ED%81%AC%EB%A6%B0-%EB%AC%B8%EC%A0%9C%EB%A5%BC-%ED%95%B4%EA%B2%B0%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Windows 디버거를 사용하여 블루 스크린 문제를 해결하는 방법 | Dell 대한민국&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;지침 컴퓨터에 블루 스크린이 나타나는 경우 발생한 상황을 알아내고 문제를 해결하며 재발을 방지하려면 어떻게 해야 할까요? 이 상황에서는 메모리 덤프 파일이 유용할 수 있습니다. 메모리&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.dell.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Microsoft 의 메뉴얼도 있지만, 체감상 Dell의 메뉴얼이 훨신 잘 되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 블루스크린 발생 후 Windows는 자체적으로 `.dmp` 파일을 생성한다. Dell의 메뉴얼을 참조하여 생성된 `.dmp` 파일을 디버깅하여 출력 결과를 얻자.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 출력결과 분석&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1730211026359&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;For analysis of this file, run !analyze -v
nt!KeBugCheckEx:
fffff805e7cb8680 48894c2408      mov     qword ptr [rsp+8],rcx ss:0018:fffff601ebc650f0=000000000000000a
0: kd&amp;gt; !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high.  This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.
Arguments:
Arg1: 0000000000000050, memory referenced
Arg2: 0000000000000002, IRQL
Arg3: 0000000000000000, value 0 = read operation, 1 = write operation
Arg4: fffff8057b203e1f, address which referenced memory

Debugging Details:
------------------


KEY_VALUES_STRING: 1

    Key  : Analysis.CPU.mSec
    Value: 1453

    Key  : Analysis.Elapsed.mSec
    Value: 7686

    Key  : Analysis.IO.Other.Mb
    Value: 28

    Key  : Analysis.IO.Read.Mb
    Value: 1

    Key  : Analysis.IO.Write.Mb
    Value: 36

    Key  : Analysis.Init.CPU.mSec
    Value: 890

    Key  : Analysis.Init.Elapsed.mSec
    Value: 34715

    Key  : Analysis.Memory.CommitPeak.Mb
    Value: 108

    Key  : Analysis.Version.DbgEng
    Value: 10.0.27725.1000

    Key  : Analysis.Version.Description
    Value: 10.2408.27.01 amd64fre

    Key  : Analysis.Version.Ext
    Value: 1.2408.27.1

    Key  : Bugcheck.Code.LegacyAPI
    Value: 0xd1

    Key  : Bugcheck.Code.TargetModel
    Value: 0xd1

    Key  : Dump.Attributes.AsUlong
    Value: 21808

    Key  : Dump.Attributes.DiagDataWrittenToHeader
    Value: 1

    Key  : Dump.Attributes.ErrorCode
    Value: 0

    Key  : Dump.Attributes.KernelGeneratedTriageDump
    Value: 1

    Key  : Dump.Attributes.LastLine
    Value: Dump completed successfully.

    Key  : Dump.Attributes.ProgressPercentage
    Value: 0

    Key  : Failure.Bucket
    Value: AV_NETIO!StreamInvokeCalloutAndNormalizeAction

    Key  : Failure.Hash
    Value: {c2ca2d1f-cfdc-88d5-c7bc-7693b8f0de04}

    Key  : Hypervisor.Enlightenments.ValueHex
    Value: 7497cf94

    Key  : Hypervisor.Flags.AnyHypervisorPresent
    Value: 1

    Key  : Hypervisor.Flags.ApicEnlightened
    Value: 1

    Key  : Hypervisor.Flags.ApicVirtualizationAvailable
    Value: 0

    Key  : Hypervisor.Flags.AsyncMemoryHint
    Value: 0

    Key  : Hypervisor.Flags.CoreSchedulerRequested
    Value: 0

    Key  : Hypervisor.Flags.CpuManager
    Value: 1

    Key  : Hypervisor.Flags.DeprecateAutoEoi
    Value: 0

    Key  : Hypervisor.Flags.DynamicCpuDisabled
    Value: 1

    Key  : Hypervisor.Flags.Epf
    Value: 0

    Key  : Hypervisor.Flags.ExtendedProcessorMasks
    Value: 1

    Key  : Hypervisor.Flags.HardwareMbecAvailable
    Value: 1

    Key  : Hypervisor.Flags.MaxBankNumber
    Value: 0

    Key  : Hypervisor.Flags.MemoryZeroingControl
    Value: 0

    Key  : Hypervisor.Flags.NoExtendedRangeFlush
    Value: 0

    Key  : Hypervisor.Flags.NoNonArchCoreSharing
    Value: 1

    Key  : Hypervisor.Flags.Phase0InitDone
    Value: 1

    Key  : Hypervisor.Flags.PowerSchedulerQos
    Value: 0

    Key  : Hypervisor.Flags.RootScheduler
    Value: 0

    Key  : Hypervisor.Flags.SynicAvailable
    Value: 1

    Key  : Hypervisor.Flags.UseQpcBias
    Value: 0

    Key  : Hypervisor.Flags.Value
    Value: 38408431

    Key  : Hypervisor.Flags.ValueHex
    Value: 24a10ef

    Key  : Hypervisor.Flags.VpAssistPage
    Value: 1

    Key  : Hypervisor.Flags.VsmAvailable
    Value: 1

    Key  : Hypervisor.RootFlags.AccessStats
    Value: 1

    Key  : Hypervisor.RootFlags.CrashdumpEnlightened
    Value: 1

    Key  : Hypervisor.RootFlags.CreateVirtualProcessor
    Value: 1

    Key  : Hypervisor.RootFlags.DisableHyperthreading
    Value: 0

    Key  : Hypervisor.RootFlags.HostTimelineSync
    Value: 1

    Key  : Hypervisor.RootFlags.HypervisorDebuggingEnabled
    Value: 0

    Key  : Hypervisor.RootFlags.IsHyperV
    Value: 1

    Key  : Hypervisor.RootFlags.LivedumpEnlightened
    Value: 1

    Key  : Hypervisor.RootFlags.MapDeviceInterrupt
    Value: 1

    Key  : Hypervisor.RootFlags.MceEnlightened
    Value: 1

    Key  : Hypervisor.RootFlags.Nested
    Value: 0

    Key  : Hypervisor.RootFlags.StartLogicalProcessor
    Value: 1

    Key  : Hypervisor.RootFlags.Value
    Value: 1015

    Key  : Hypervisor.RootFlags.ValueHex
    Value: 3f7


BUGCHECK_CODE:  d1

BUGCHECK_P1: 50

BUGCHECK_P2: 2

BUGCHECK_P3: 0

BUGCHECK_P4: fffff8057b203e1f

FILE_IN_CAB:  102924-12781-01.dmp

TAG_NOT_DEFINED_202b:  *** Unknown TAG in analysis list 202b


DUMP_FILE_ATTRIBUTES: 0x21808
  Kernel Generated Triage Dump

FAULTING_THREAD:  ffffe40edbd2d040

READ_ADDRESS: fffff805e87c34b0: Unable to get MiVisibleState
Unable to get NonPagedPoolStart
Unable to get NonPagedPoolEnd
Unable to get PagedPoolStart
Unable to get PagedPoolEnd
unable to get nt!MmSpecialPagesInUse
 0000000000000050 

BLACKBOXBSD: 1 (!blackboxbsd)


BLACKBOXNTFS: 1 (!blackboxntfs)


BLACKBOXPNP: 1 (!blackboxpnp)


BLACKBOXWINLOGON: 1

CUSTOMER_CRASH_COUNT:  1

PROCESS_NAME:  System

TRAP_FRAME:  fffff601ebc65230 -- (.trap 0xfffff601ebc65230)
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=0000000000000000 rbx=0000000000000000 rcx=ffffe40effbf6a00
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=fffff8057b203e1f rsp=fffff601ebc653c0 rbp=0000000000000003
 r8=0000000000001001  r9=0000000000001001 r10=0000000000000000
r11=ffffe40ef6396560 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei ng nz na pe nc
NETIO!StreamInvokeCalloutAndNormalizeAction+0x2f3:
fffff8057b203e1f 396a50          cmp     dword ptr [rdx+50h],ebp ds:0000000000000050=????????
Resetting default scope

STACK_TEXT:  
fffff601ebc650e8 fffff805e7e87ae9     : 000000000000000a 0000000000000050 0000000000000002 0000000000000000 : nt!KeBugCheckEx
fffff601ebc650f0 fffff805e7e82da8     : ffffe40ef668ab02 0000000000000108 fffff601ebc65440 fffff8058516e800 : nt!KiBugCheckDispatch+0x69
fffff601ebc65230 fffff8057b203e1f     : 0000000000000000 ffffe40ef6396560 ffffe40ef6396501 ffffe40ef2d332b0 : nt!KiPageFault+0x468
fffff601ebc653c0 fffff8057b200dcb     : 0000000000000000 ffffe40f0003ea00 ffffe40ef6396560 fffff601ebc65898 : NETIO!StreamInvokeCalloutAndNormalizeAction+0x2f3
fffff601ebc654b0 fffff8057b201219     : ffffe40effbf6a60 fffff601ebc65680 ffffe40ef6396560 fffff601ebc65e30 : NETIO!StreamCalloutProcessData+0x5f
fffff601ebc65540 fffff8057b1e0785     : fffff601ebc65e30 fffff601ebc65680 ffffe40ef6396560 ffffe40ef6396501 : NETIO!StreamCalloutProcessingLoop+0x175
fffff601ebc655e0 fffff8057b1af60a     : 0000000000000014 fffff80585161310 fffff60100000001 fffff601ebc660f0 : NETIO!StreamProcessCallout+0x609
fffff601ebc65710 fffff8057b1ae3c0     : ffffe40ed97e0014 fffff601ebc660f0 ffffe40eef284e50 fffff601ebc65e30 : NETIO!ProcessCallout+0x2ea
fffff601ebc657e0 fffff8057b1f8646     : 0000000000004800 ffffe40ed98e6aa0 fffff601ebc65ae8 ffffe40ed98e9bc0 : NETIO!ArbitrateAndEnforce+0x1e0
fffff601ebc65920 fffff805e7b3e2c8     : fffff601ebc65b60 fffff8057b1f8600 0000000000000002 fffff601ebc65e00 : NETIO!ArbitrateAndEnforceCallout+0x46
fffff601ebc65980 fffff805e7b3e1dd     : fffff8057b1f8600 fffff601ebc65b60 ffffe40ed8ef8ec0 fffff601ebc660f0 : nt!KeExpandKernelStackAndCalloutInternal+0xd8
fffff601ebc659f0 fffff8057b1d4cfe     : 0000000000000000 fffff601ebc65e80 0000000000000001 fffff601ebc66110 : nt!KeExpandKernelStackAndCalloutEx+0x1d
fffff601ebc65a30 fffff8057b1c8932     : 0000000000000000 fffff8057b22e000 0000000000000014 ffffe40ed98e6aa0 : NETIO!NetioExpandKernelStackAndCallout+0x7e
fffff601ebc65a80 fffff8057b203934     : 0000000100010006 ffffe40eef2894c0 ffffe40eef286430 ffffe40ef2d64400 : NETIO!KfdClassify+0x622
fffff601ebc65d90 fffff8057b1fdc7d     : ffffe40efe69eeb0 fffff601ebc66000 fffff601ebc66520 ffffe40effbf6a60 : NETIO!StreamInternalClassify+0x168
fffff601ebc65f00 fffff8057b1a623e     : ffffe40ef644cc01 fffff805e7ac6825 ffffe40f06543000 00000000000000ff : NETIO!StreamClassify+0x43d
fffff601ebc66090 fffff8057b1a5e61     : 0000000000000000 ffffe40ef644cc70 0000000000000000 0000000000000000 : NETIO!StreamCommonInspect+0x29a
fffff601ebc664a0 fffff8057b43545c     : 0000000000000000 ffffe40effbf6c88 fffff601ebc66620 ffffe40edbe468e0 : NETIO!WfpStreamInspectReceive+0x1d1
fffff601ebc66520 fffff8057b3f9f03     : fffffffffffac002 0000000000000000 0000000000000000 ffffe40edbeaf668 : tcpip!TcpProcessFastDatagramBatch+0xcac
fffff601ebc66680 fffff8057b3f8806     : 0000000000000001 0000000000000002 0000000000000000 ffffe40effbf6a60 : tcpip!TcpTcbReceive+0x313
fffff601ebc66810 fffff8057b4b46b2     : ffffe40edbeaf7b0 ffffe40edbeaf7b0 ffffe40edbe468e0 ffffe40edbe468e0 : tcpip!TcpMatchReceive+0x226
fffff601ebc66960 fffff8057b4b4356     : ffffe40e00000007 0000000000000000 ffffe40edf478001 0000000000000000 : tcpip!TcpReceive+0x312
fffff601ebc669f0 fffff8057b468ecf     : 0000000000000001 ffffe40edbeaf7b0 00000000ffffff00 fffff805e7ad1300 : tcpip!TcpNlClientReceiveDatagrams+0x16
fffff601ebc66a20 fffff8057b467a31     : fffff8057b5cb750 0000000000000006 ffffe40edf682828 fffff601ebc66b80 : tcpip!IppProcessDeliverList+0xbf
fffff601ebc66b20 fffff8057b4a4172     : fffff8057b5cb750 ffffe40edbe938a0 0000000000000000 ffffe40edf6d2400 : tcpip!IppReceiveHeaderBatch+0x301
fffff601ebc66bf0 fffff8057b4f2217     : ffffe40edf2a13e0 0000000000000000 0000000e00000501 fffff60100000000 : tcpip!IppReceivePackets+0x4e2
fffff601ebc66d30 fffff8057b4f5868     : ffffe40edf2a13e0 ffffe40edf6ce2a0 0000000000000000 ffffe40f11390230 : tcpip!IpFlcReceivePreValidatedPackets+0xad7
fffff601ebc66e70 fffff805e7b3e2c8     : fffff601ebc67110 ffffe40edbd2d0bd 0000000000000002 fffff601ebc67110 : tcpip!FlReceiveNetBufferListChainCalloutRoutine+0x568
fffff601ebc66fe0 fffff805e7b3e1dd     : fffff8057b4f5300 fffff601ebc67110 ffffe40edbcfb6f0 0000000000000000 : nt!KeExpandKernelStackAndCalloutInternal+0xd8
fffff601ebc67050 fffff8057b48ed28     : ffffe40edf6d22a0 00000000c0000225 0000000000000001 fffff8057ce53288 : nt!KeExpandKernelStackAndCalloutEx+0x1d
fffff601ebc67090 fffff8057b4f52e8     : 0000000000000000 fffff601ebc67260 0000000000000000 ffffe40edf94b010 : tcpip!NetioExpandKernelStackAndCallout+0x58
fffff601ebc670e0 fffff8057affa1b3     : fffff601ebc671d0 ffffe40edf6ce2a0 ffffe40e00000007 ffffe40f00000007 : tcpip!FlReceiveNetBufferListChain+0x138
fffff601ebc67160 fffff8057aff7447     : ffffe40edf9688b0 0000000000000000 0000000000000000 0000000000000007 : ndis!ndisMIndicateNetBufferListsToOpen+0x503
fffff601ebc67450 fffff8057affb6df     : ffffe40ede95b1a0 ffffe40edf6ce2a0 ffffe40ede95b1a0 fffff8057b4f5b01 : ndis!ndisMTopReceiveNetBufferLists+0x227
fffff601ebc67560 fffff80585d79a9b     : ffffe40edf6ce2a0 ffffe40edf6d5030 ffffe40edf544080 ffffe40edf543000 : ndis!NdisMIndicateReceiveNetBufferLists+0xb2f
fffff601ebc67780 ffffe40edf6ce2a0     : ffffe40edf6d5030 ffffe40edf544080 ffffe40edf543000 0000000000000801 : e1r+0x19a9b
fffff601ebc67788 ffffe40edf6d5030     : ffffe40edf544080 ffffe40edf543000 0000000000000801 0000000000000007 : 0xffffe40edf6ce2a0
fffff601ebc67790 ffffe40edf544080     : ffffe40edf543000 0000000000000801 0000000000000007 ffffe40edf6ce2a0 : 0xffffe40edf6d5030
fffff601ebc67798 ffffe40edf543000     : 0000000000000801 0000000000000007 ffffe40edf6ce2a0 ffffe40edf6d22a0 : 0xffffe40edf544080
fffff601ebc677a0 0000000000000801     : 0000000000000007 ffffe40edf6ce2a0 ffffe40edf6d22a0 0000000000000000 : 0xffffe40edf543000
fffff601ebc677a8 0000000000000007     : ffffe40edf6ce2a0 ffffe40edf6d22a0 0000000000000000 ffffe40edf544080 : 0x801
fffff601ebc677b0 ffffe40edf6ce2a0     : ffffe40edf6d22a0 0000000000000000 ffffe40edf544080 0000000000000007 : 0x7
fffff601ebc677b8 ffffe40edf6d22a0     : 0000000000000000 ffffe40edf544080 0000000000000007 fffff80585d7acc8 : 0xffffe40edf6ce2a0
fffff601ebc677c0 0000000000000000     : ffffe40edf544080 0000000000000007 fffff80585d7acc8 ffffe40edf6d2200 : 0xffffe40edf6d22a0


SYMBOL_NAME:  NETIO!StreamInvokeCalloutAndNormalizeAction+2f3

MODULE_NAME: NETIO

IMAGE_NAME:  NETIO.SYS

IMAGE_VERSION:  10.0.26100.1882

STACK_COMMAND:  .process /r /p 0xffffe40ed74ae040; .thread 0xffffe40edbd2d040 ; kb

BUCKET_ID_FUNC_OFFSET:  2f3

FAILURE_BUCKET_ID:  AV_NETIO!StreamInvokeCalloutAndNormalizeAction

OSPLATFORM_TYPE:  x64

OSNAME:  Windows 10

FAILURE_ID_HASH:  {c2ca2d1f-cfdc-88d5-c7bc-7693b8f0de04}

Followup:     MachineOwner
---------&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 꽤 긴데, 귀찮다면 ChatGPT 와 같은 LLM 모델을 통해 분석을 대신 부탁해도 된다. 대략적인 원인을 파악해 줄 것이다. 해당 포스팅에서는 내가 직접 디버깅된 결과를 분석해 볼 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2-1. DRIVER_IRQL_NOT_LESS_OR_EQUAL&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최상단에 `DRIVER_IRQL_NOT_LESS_OR_EQUAL` 이라는 명칭이 보인다. 아래부터는 이러한 설명이 보인다.&lt;/p&gt;
&lt;pre id=&quot;code_1730211299579&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;너무 높은 인터럽트 요청 수준(IRQL)에서 페이지 가능한(또는 완전히 유효하지 않은) 주소에 액세스하려고 시도했습니다.

이는 일반적으로 다음과 같습니다
부적절한 주소를 사용하는 운전자로 인해 발생합니다.
커널 디버거를 사용할 수 있는 경우 스택 백트레이스를 가져옵니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 오류 코드 관련해서, Microsoft 커뮤니티에서는&amp;nbsp; &lt;a href=&quot;https://answers.microsoft.com/ko-kr/windows/forum/all/%EB%B8%94%EB%A3%A8-%EC%8A%A4%ED%81%AC%EB%A6%B0/5da19f04-e9ca-4bf4-84cf-d082060aa0fe&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Microsoft 담당자의 답변&lt;/a&gt;도 살펴볼 수 있는데, 세상 쓸모없는 답변이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1314&quot; data-origin-height=&quot;440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6zACn/btsKoWyAyxK/TcSGCck5MBokfMTKkGGhU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6zACn/btsKoWyAyxK/TcSGCck5MBokfMTKkGGhU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6zACn/btsKoWyAyxK/TcSGCck5MBokfMTKkGGhU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6zACn%2FbtsKoWyAyxK%2FTcSGCck5MBokfMTKkGGhU1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;268&quot; data-origin-width=&quot;1314&quot; data-origin-height=&quot;440&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 어느정도 이해는 하지만, 일반적으로 저런 방식으로 블루스크린 문제는 해결되지 않는다. 특히 `Dism` 과 `sfc` 명령어가 정확히 어떤 방식으로 동작하는지는 모르겠으나, Windows 운영체제를 사용한지 거의 20년이 다 되어가는데 저 명령어를 처음 접한 순간부터, 현재까지 단한번도 저 명령어를 통해 문제가 해결된 경험이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2-2. Arguments&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1730211814337&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Arguments:
Arg1: 0000000000000050, memory referenced
Arg2: 0000000000000002, IRQL
Arg3: 0000000000000000, value 0 = read operation, 1 = write operation
Arg4: fffff8057b203e1f, address which referenced memory&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`Arguments` 에는 위와같은 정보를 제공해주고 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;0x0000000000000050 : 접근하고자 시도한 메모리 주소&lt;/li&gt;
&lt;li&gt;0x0000000000000002 : IRQL&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(너무 높은 인터럽트 요청 수준, 즉 일종의 메모리 접근 권한문제)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;0x0000000000000000 : 주석과 같이 0는 오직 읽기&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(read)&lt;/span&gt; 만 가능함을 의미&lt;/li&gt;
&lt;li&gt;0xfffff8057b203e1f : 오류가&amp;nbsp;발생한&amp;nbsp;드라이버&amp;nbsp;또는&amp;nbsp;커널&amp;nbsp;모듈의&amp;nbsp;특정&amp;nbsp;위치&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2-2. STACK_TEXT&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1730212441761&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;STACK_TEXT:  
fffff601ebc650e8 fffff805e7e87ae9     : 000000000000000a 0000000000000050 0000000000000002 0000000000000000 : nt!KeBugCheckEx
fffff601ebc650f0 fffff805e7e82da8     : ffffe40ef668ab02 0000000000000108 fffff601ebc65440 fffff8058516e800 : nt!KiBugCheckDispatch+0x69
fffff601ebc65230 fffff8057b203e1f     : 0000000000000000 ffffe40ef6396560 ffffe40ef6396501 ffffe40ef2d332b0 : nt!KiPageFault+0x468
fffff601ebc653c0 fffff8057b200dcb     : 0000000000000000 ffffe40f0003ea00 ffffe40ef6396560 fffff601ebc65898 : NETIO!StreamInvokeCalloutAndNormalizeAction+0x2f3
fffff601ebc654b0 fffff8057b201219     : ffffe40effbf6a60 fffff601ebc65680 ffffe40ef6396560 fffff601ebc65e30 : NETIO!StreamCalloutProcessData+0x5f
fffff601ebc65540 fffff8057b1e0785     : fffff601ebc65e30 fffff601ebc65680 ffffe40ef6396560 ffffe40ef6396501 : NETIO!StreamCalloutProcessingLoop+0x175
fffff601ebc655e0 fffff8057b1af60a     : 0000000000000014 fffff80585161310 fffff60100000001 fffff601ebc660f0 : NETIO!StreamProcessCallout+0x609
fffff601ebc65710 fffff8057b1ae3c0     : ffffe40ed97e0014 fffff601ebc660f0 ffffe40eef284e50 fffff601ebc65e30 : NETIO!ProcessCallout+0x2ea
fffff601ebc657e0 fffff8057b1f8646     : 0000000000004800 ffffe40ed98e6aa0 fffff601ebc65ae8 ffffe40ed98e9bc0 : NETIO!ArbitrateAndEnforce+0x1e0
fffff601ebc65920 fffff805e7b3e2c8     : fffff601ebc65b60 fffff8057b1f8600 0000000000000002 fffff601ebc65e00 : NETIO!ArbitrateAndEnforceCallout+0x46
fffff601ebc65980 fffff805e7b3e1dd     : fffff8057b1f8600 fffff601ebc65b60 ffffe40ed8ef8ec0 fffff601ebc660f0 : nt!KeExpandKernelStackAndCalloutInternal+0xd8
fffff601ebc659f0 fffff8057b1d4cfe     : 0000000000000000 fffff601ebc65e80 0000000000000001 fffff601ebc66110 : nt!KeExpandKernelStackAndCalloutEx+0x1d
fffff601ebc65a30 fffff8057b1c8932     : 0000000000000000 fffff8057b22e000 0000000000000014 ffffe40ed98e6aa0 : NETIO!NetioExpandKernelStackAndCallout+0x7e
fffff601ebc65a80 fffff8057b203934     : 0000000100010006 ffffe40eef2894c0 ffffe40eef286430 ffffe40ef2d64400 : NETIO!KfdClassify+0x622
fffff601ebc65d90 fffff8057b1fdc7d     : ffffe40efe69eeb0 fffff601ebc66000 fffff601ebc66520 ffffe40effbf6a60 : NETIO!StreamInternalClassify+0x168
fffff601ebc65f00 fffff8057b1a623e     : ffffe40ef644cc01 fffff805e7ac6825 ffffe40f06543000 00000000000000ff : NETIO!StreamClassify+0x43d
fffff601ebc66090 fffff8057b1a5e61     : 0000000000000000 ffffe40ef644cc70 0000000000000000 0000000000000000 : NETIO!StreamCommonInspect+0x29a
fffff601ebc664a0 fffff8057b43545c     : 0000000000000000 ffffe40effbf6c88 fffff601ebc66620 ffffe40edbe468e0 : NETIO!WfpStreamInspectReceive+0x1d1
fffff601ebc66520 fffff8057b3f9f03     : fffffffffffac002 0000000000000000 0000000000000000 ffffe40edbeaf668 : tcpip!TcpProcessFastDatagramBatch+0xcac
fffff601ebc66680 fffff8057b3f8806     : 0000000000000001 0000000000000002 0000000000000000 ffffe40effbf6a60 : tcpip!TcpTcbReceive+0x313
fffff601ebc66810 fffff8057b4b46b2     : ffffe40edbeaf7b0 ffffe40edbeaf7b0 ffffe40edbe468e0 ffffe40edbe468e0 : tcpip!TcpMatchReceive+0x226
fffff601ebc66960 fffff8057b4b4356     : ffffe40e00000007 0000000000000000 ffffe40edf478001 0000000000000000 : tcpip!TcpReceive+0x312
fffff601ebc669f0 fffff8057b468ecf     : 0000000000000001 ffffe40edbeaf7b0 00000000ffffff00 fffff805e7ad1300 : tcpip!TcpNlClientReceiveDatagrams+0x16
fffff601ebc66a20 fffff8057b467a31     : fffff8057b5cb750 0000000000000006 ffffe40edf682828 fffff601ebc66b80 : tcpip!IppProcessDeliverList+0xbf
fffff601ebc66b20 fffff8057b4a4172     : fffff8057b5cb750 ffffe40edbe938a0 0000000000000000 ffffe40edf6d2400 : tcpip!IppReceiveHeaderBatch+0x301
fffff601ebc66bf0 fffff8057b4f2217     : ffffe40edf2a13e0 0000000000000000 0000000e00000501 fffff60100000000 : tcpip!IppReceivePackets+0x4e2
fffff601ebc66d30 fffff8057b4f5868     : ffffe40edf2a13e0 ffffe40edf6ce2a0 0000000000000000 ffffe40f11390230 : tcpip!IpFlcReceivePreValidatedPackets+0xad7
fffff601ebc66e70 fffff805e7b3e2c8     : fffff601ebc67110 ffffe40edbd2d0bd 0000000000000002 fffff601ebc67110 : tcpip!FlReceiveNetBufferListChainCalloutRoutine+0x568
fffff601ebc66fe0 fffff805e7b3e1dd     : fffff8057b4f5300 fffff601ebc67110 ffffe40edbcfb6f0 0000000000000000 : nt!KeExpandKernelStackAndCalloutInternal+0xd8
fffff601ebc67050 fffff8057b48ed28     : ffffe40edf6d22a0 00000000c0000225 0000000000000001 fffff8057ce53288 : nt!KeExpandKernelStackAndCalloutEx+0x1d
fffff601ebc67090 fffff8057b4f52e8     : 0000000000000000 fffff601ebc67260 0000000000000000 ffffe40edf94b010 : tcpip!NetioExpandKernelStackAndCallout+0x58
fffff601ebc670e0 fffff8057affa1b3     : fffff601ebc671d0 ffffe40edf6ce2a0 ffffe40e00000007 ffffe40f00000007 : tcpip!FlReceiveNetBufferListChain+0x138
fffff601ebc67160 fffff8057aff7447     : ffffe40edf9688b0 0000000000000000 0000000000000000 0000000000000007 : ndis!ndisMIndicateNetBufferListsToOpen+0x503
fffff601ebc67450 fffff8057affb6df     : ffffe40ede95b1a0 ffffe40edf6ce2a0 ffffe40ede95b1a0 fffff8057b4f5b01 : ndis!ndisMTopReceiveNetBufferLists+0x227
fffff601ebc67560 fffff80585d79a9b     : ffffe40edf6ce2a0 ffffe40edf6d5030 ffffe40edf544080 ffffe40edf543000 : ndis!NdisMIndicateReceiveNetBufferLists+0xb2f
fffff601ebc67780 ffffe40edf6ce2a0     : ffffe40edf6d5030 ffffe40edf544080 ffffe40edf543000 0000000000000801 : e1r+0x19a9b
fffff601ebc67788 ffffe40edf6d5030     : ffffe40edf544080 ffffe40edf543000 0000000000000801 0000000000000007 : 0xffffe40edf6ce2a0
fffff601ebc67790 ffffe40edf544080     : ffffe40edf543000 0000000000000801 0000000000000007 ffffe40edf6ce2a0 : 0xffffe40edf6d5030
fffff601ebc67798 ffffe40edf543000     : 0000000000000801 0000000000000007 ffffe40edf6ce2a0 ffffe40edf6d22a0 : 0xffffe40edf544080
fffff601ebc677a0 0000000000000801     : 0000000000000007 ffffe40edf6ce2a0 ffffe40edf6d22a0 0000000000000000 : 0xffffe40edf543000
fffff601ebc677a8 0000000000000007     : ffffe40edf6ce2a0 ffffe40edf6d22a0 0000000000000000 ffffe40edf544080 : 0x801
fffff601ebc677b0 ffffe40edf6ce2a0     : ffffe40edf6d22a0 0000000000000000 ffffe40edf544080 0000000000000007 : 0x7
fffff601ebc677b8 ffffe40edf6d22a0     : 0000000000000000 ffffe40edf544080 0000000000000007 fffff80585d7acc8 : 0xffffe40edf6ce2a0
fffff601ebc677c0 0000000000000000     : ffffe40edf544080 0000000000000007 fffff80585d7acc8 ffffe40edf6d2200 : 0xffffe40edf6d22a0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심적인 정보는 `STACK_TEXT` 와 그 내용으로부터 확인할 수 있다. 위에서 언급한 Arg4 메모리 위치가 3번째 줄에서 확인되며, 그 메시지는 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1730212561502&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fffff601ebc65230 fffff8057b203e1f     : 0000000000000000 ffffe40ef6396560 ffffe40ef6396501 ffffe40ef2d332b0 : nt!KiPageFault+0x468&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 PageFault 오류가 발생한것이며, 이는 `StreamInvokeCalloutAndNormalizeAction` 함수를 호출하던 도중에 발생하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;STACK 이므로 하단에 있을수록 더 먼저 발생한 사건이고, 최상단에 있는것이 나중에 발생한 사건일것이다. 때문에 `nids` 즉, Network Driver Interface Specification 에서부터 시작되어서 `tcpip` 를 통해서 특정 작업을 수행하다가, `NETIO` 작업을 수행하던 도중 `StreamInvokeCalloutAndNormalizeAction` 작업에서 가상메모리-메모리간 스왑과정에서 시스템에 접근해서는 안되는 메모리 영역&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(null 이거나, 접근 권한이 없거나)&lt;/span&gt; 을 접근하면서 만들어낸 문제라는 사실을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2-3. 요약사항&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분석결과 최하단에는 간단하게 요약사항이 적혀있다.&lt;/p&gt;
&lt;pre id=&quot;code_1730213079122&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SYMBOL_NAME:  NETIO!StreamInvokeCalloutAndNormalizeAction+2f3

MODULE_NAME: NETIO

IMAGE_NAME:  NETIO.SYS

IMAGE_VERSION:  10.0.26100.1882

STACK_COMMAND:  .process /r /p 0xffffe40ed74ae040; .thread 0xffffe40edbd2d040 ; kb

BUCKET_ID_FUNC_OFFSET:  2f3

FAILURE_BUCKET_ID:  AV_NETIO!StreamInvokeCalloutAndNormalizeAction

OSPLATFORM_TYPE:  x64

OSNAME:  Windows 10

FAILURE_ID_HASH:  {c2ca2d1f-cfdc-88d5-c7bc-7693b8f0de04}

Followup:     MachineOwner&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 해결방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 오류 메세지는 모두 Network와 연관된 HW, SW가 문제라고 지목한다. 나는 여러번의 블루스크린 발생 메세지 중에서, 이러한 Network 블루스크린 문제가 반복되어 왔으므로 명확히 Network 장비 문제라는점을 확인할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 만약 DRAM, MMU&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Memory management unit)&lt;/span&gt; 와 같은 HW 장비에 이상이 발생한 경우, 여러번의 블루스크린에서 Network 장비 뿐만 아니라 여러 장비에서 복합적인 문제가 발생했을 것이기에 한번의 Dump 파일 분석만으로 Network 장비 문제라고 단정지을수는 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종적으로, Intel I211 Network Driver를 업데이트 하는것으로 해결하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 25/01/22 추가사항.&lt;br /&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 뒤로도 계속해서 관련 블루스크린이 발생하여 원인을 조사해 본 결과, 네트워크 단에서 작동하는 광고차단 프로그램 AdGuard 와 Windows 24H2 의 호환성 문제로 추측되어 AdGuard 를 일시적으로 비활성화 한 결과 문제가 해결되었다.&lt;/p&gt;</description>
      <category>Operating System/Windows</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/207</guid>
      <comments>https://cypsw.tistory.com/entry/Windows-%EB%B8%94%EB%A3%A8%EC%8A%A4%ED%81%AC%EB%A6%B0-%EB%B6%84%EC%84%9D%ED%95%98%EA%B8%B0#entry207comment</comments>
      <pubDate>Tue, 29 Oct 2024 23:55:10 +0900</pubDate>
    </item>
    <item>
      <title>WSL2 에서 ROCm 사용하기</title>
      <link>https://cypsw.tistory.com/entry/WSL2-%EC%97%90%EC%84%9C-ROCm-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;a href=&quot;https://cypsw.tistory.com/206#6.%20WSL%20%ED%99%98%EA%B2%BD%EC%9D%B4%20%EC%95%84%EB%8B%8C%2C%20Native%20Ubuntu%20%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C%EB%8A%94%20%EC%98%AC%EB%B0%94%EB%A5%B4%EA%B2%8C%20%EC%9E%91%EB%8F%99%ED%95%9C%EB%8B%A4.-1-5&quot;&gt;해당 부분&lt;/a&gt;을 먼저 참조하시는걸 권장드립니다.&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이전에 &lt;a href=&quot;https://cypsw.tistory.com/entry/%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%A1%9C%EC%84%9C-Radeon-%EC%9D%B4-%EC%B5%9C%EC%95%85%EC%9D%B8-%EC%9D%B4%EC%9C%A0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Radeon 욕을 좀 했었는데&lt;/a&gt;, 최근들어서 다시 Radeon 시스템을 사용하게 되었다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;사실 순수 게임용도나, 고전적인 GPU 연산 코딩용도로 Radeon GPU는 나쁘지 않다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 ML 개발자로서 Radeon GPU를 활용하기에는 문서가 꽤나 불친절한 편이다...&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;가지고 놀아볼 겸, ROCm을 설치하는 과정에서도 여러 문제점이 있었기에, 해당 포스팅에 설치 방법을 정리한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Ubuntu 22.04 버전을 사용하자&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1730042272783&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;WSL support matrices by ROCm version &amp;mdash; Use ROCm on Radeon GPUs&quot; data-og-description=&quot;Available from PyTorch.org nightly builds, not tested extensively by AMD.&quot; data-og-host=&quot;rocm.docs.amd.com&quot; data-og-source-url=&quot;https://rocm.docs.amd.com/projects/radeon/en/latest/docs/compatibility/wsl/wsl_compatibility.html&quot; data-og-url=&quot;https://rocm.docs.amd.com/projects/radeon/en/latest/docs/compatibility/wsl/wsl_compatibility.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://rocm.docs.amd.com/projects/radeon/en/latest/docs/compatibility/wsl/wsl_compatibility.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://rocm.docs.amd.com/projects/radeon/en/latest/docs/compatibility/wsl/wsl_compatibility.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;WSL support matrices by ROCm version &amp;mdash; Use ROCm on Radeon GPUs&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Available from PyTorch.org nightly builds, not tested extensively by AMD.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;rocm.docs.amd.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;현재 `2024년 10월 28일` 기준 Ubuntu 24.04 버전이 나온지도 거의 반년이 지났지만 지원하지 않는다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 24.04 버전으로 시도하다가 각종 오류 발생으로 인해 자료를 찾아보니 22.04 버전을 사용해야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.microsoft.com/store/productId/9PN20MSR04DW?ocid=pdpshare&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Microsoft Store 에서 Ubuntu 22.04 버전을 다운&lt;/a&gt;받아 WSL을 사용하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. ROCm 설치&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1730042562190&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Install Radeon software for WSL with ROCm &amp;mdash; Use ROCm on Radeon GPUs&quot; data-og-description=&quot;After the Unified Driver Deb Package repositories are installed, run the installer script with appropriate --usecase parameters to install the driver components. AMD recommends installing the WSL usecase by default. Post-install verification check Run a po&quot; data-og-host=&quot;rocm.docs.amd.com&quot; data-og-source-url=&quot;https://rocm.docs.amd.com/projects/radeon/en/latest/docs/install/wsl/install-radeon.html&quot; data-og-url=&quot;https://rocm.docs.amd.com/projects/radeon/en/latest/docs/install/wsl/install-radeon.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://rocm.docs.amd.com/projects/radeon/en/latest/docs/install/wsl/install-radeon.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://rocm.docs.amd.com/projects/radeon/en/latest/docs/install/wsl/install-radeon.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Install Radeon software for WSL with ROCm &amp;mdash; Use ROCm on Radeon GPUs&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;After the Unified Driver Deb Package repositories are installed, run the installer script with appropriate --usecase parameters to install the driver components. AMD recommends installing the WSL usecase by default. Post-install verification check Run a po&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;rocm.docs.amd.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해당 과정을 그대로 따라 설치하면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Ubuntu 22.04 버전에서는 아무 문제 없이 잘 설치된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그 후 `rocminfo` 명령어를 입력하면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;CPU로 Agent1 이 출력되고, GPU로 Agent2 가 출력된다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(일반적인 single-gpu 환경)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1730042869263&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;root@Cyp:~# rocminfo
=====================
HSA System Attributes
=====================
Runtime Version:         1.1
System Timestamp Freq.:  1000.000000MHz
Sig. Max Wait Duration:  18446744073709551615 (0xFFFFFFFFFFFFFFFF) (timestamp count)
Machine Model:           LARGE
System Endianness:       LITTLE
Mwaitx:                  ENABLED
DMAbuf Support:          YES

==========
HSA Agents
==========
*******
Agent 1
*******
  Name:                    CPU
  Uuid:                    CPU-XX
  Marketing Name:          CPU
  Vendor Name:             CPU
  Feature:                 None specified
  Profile:                 FULL_PROFILE
  Float Round Mode:        NEAR
  Max Queue Number:        0(0x0)
  Queue Min Size:          0(0x0)
  Queue Max Size:          0(0x0)
  Queue Type:              MULTI
  Node:                    0
  Device Type:             CPU
  Cache Info:
  Chip ID:                 0(0x0)
  Cacheline Size:          64(0x40)
  Internal Node ID:        0
  Compute Unit:            12
  SIMDs per CU:            0
  Shader Engines:          0
  Shader Arrs. per Eng.:   0
  Features:                None
  Pool Info:
    Pool 1
      Segment:                 GLOBAL; FLAGS: KERNARG, FINE GRAINED
      Size:                    16334012(0xf93cbc) KB
      Allocatable:             TRUE
      Alloc Granule:           4KB
      Alloc Recommended Granule:4KB
      Alloc Alignment:         4KB
      Accessible by all:       TRUE
    Pool 2
      Segment:                 GLOBAL; FLAGS: COARSE GRAINED
      Size:                    16334012(0xf93cbc) KB
      Allocatable:             TRUE
      Alloc Granule:           4KB
      Alloc Recommended Granule:4KB
      Alloc Alignment:         4KB
      Accessible by all:       TRUE
  ISA Info:
*******
Agent 2
*******
  Name:                    gfx1030
  Marketing Name:          AMD Radeon RX 6800
  Vendor Name:             AMD
  Feature:                 KERNEL_DISPATCH
  Profile:                 BASE_PROFILE
  Float Round Mode:        NEAR
  Max Queue Number:        16(0x10)
  Queue Min Size:          4096(0x1000)
  Queue Max Size:          131072(0x20000)
  Queue Type:              MULTI
  Node:                    1
  Device Type:             GPU
  Cache Info:
    L1:                      32(0x20) KB
    L3:                      131072(0x20000) KB
  Chip ID:                 29631(0x73bf)
  Cacheline Size:          64(0x40)
  Max Clock Freq. (MHz):   1950
  Internal Node ID:        1
  Compute Unit:            60
  SIMDs per CU:            2
  Shader Engines:          4
  Shader Arrs. per Eng.:   2
  Coherent Host Access:    FALSE
  Features:                KERNEL_DISPATCH
  Fast F16 Operation:      TRUE
  Wavefront Size:          32(0x20)
  Workgroup Max Size:      1024(0x400)
  Workgroup Max Size per Dimension:
    x                        1024(0x400)
    y                        1024(0x400)
    z                        1024(0x400)
  Max Waves Per CU:        32(0x20)
  Max Work-item Per CU:    1024(0x400)
  Grid Max Size:           4294967295(0xffffffff)
  Grid Max Size per Dimension:
    x                        4294967295(0xffffffff)
    y                        4294967295(0xffffffff)
    z                        4294967295(0xffffffff)
  Max fbarriers/Workgrp:   32
  Packet Processor uCode:: 118
  SDMA engine uCode::      0
  IOMMU Support::          None
  Pool Info:
    Pool 1
      Segment:                 GLOBAL; FLAGS: COARSE GRAINED
      Size:                    16703716(0xfee0e4) KB
      Allocatable:             TRUE
      Alloc Granule:           4KB
      Alloc Recommended Granule:2048KB
      Alloc Alignment:         4KB
      Accessible by all:       FALSE
    Pool 2
      Segment:                 GROUP
      Size:                    64(0x40) KB
      Allocatable:             FALSE
      Alloc Granule:           0KB
      Alloc Recommended Granule:0KB
      Alloc Alignment:         0KB
      Accessible by all:       FALSE
  ISA Info:
    ISA 1
      Name:                    amdgcn-amd-amdhsa--gfx1030
      Machine Models:          HSA_MACHINE_MODEL_LARGE
      Profiles:                HSA_PROFILE_BASE
      Default Rounding Mode:   NEAR
      Default Rounding Mode:   NEAR
      Fast f16:                TRUE
      Workgroup Max Size:      1024(0x400)
      Workgroup Max Size per Dimension:
        x                        1024(0x400)
        y                        1024(0x400)
        z                        1024(0x400)
      Grid Max Size:           4294967295(0xffffffff)
      Grid Max Size per Dimension:
        x                        4294967295(0xffffffff)
        y                        4294967295(0xffffffff)
        z                        4294967295(0xffffffff)
      FBarrier Max Size:       32
*** Done ***&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Agent2 에서 설치된 Radeon GPU를 확인할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;나의 경우는 RX6800을 사용중이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Pytorch 설치&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1730042692420&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Install PyTorch for ROCm &amp;mdash; Use ROCm on Radeon GPUs&quot; data-og-description=&quot;AMD recommends the PIP install method to create a PyTorch environment when working with ROCm&amp;trade; for machine learning development. Note The latest version of Python module numpy v2.0 is incompatible with the torch wheels for this version. Downgrade to an ol&quot; data-og-host=&quot;rocm.docs.amd.com&quot; data-og-source-url=&quot;https://rocm.docs.amd.com/projects/radeon/en/latest/docs/install/wsl/install-pytorch.html&quot; data-og-url=&quot;https://rocm.docs.amd.com/projects/radeon/en/latest/docs/install/wsl/install-pytorch.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://rocm.docs.amd.com/projects/radeon/en/latest/docs/install/wsl/install-pytorch.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://rocm.docs.amd.com/projects/radeon/en/latest/docs/install/wsl/install-pytorch.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Install PyTorch for ROCm &amp;mdash; Use ROCm on Radeon GPUs&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;AMD recommends the PIP install method to create a PyTorch environment when working with ROCm&amp;trade; for machine learning development. Note The latest version of Python module numpy v2.0 is incompatible with the torch wheels for this version. Downgrade to an ol&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;rocm.docs.amd.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;위 과정을 따라 Pytorch 를 설치하면 그대로 호환된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;개인적으로 현재 Tensorflow 는 거의 사용하지 않아서 따로 설치해보진 않았다.&amp;bull;&amp;bull;&amp;bull;&amp;bull;&amp;bull;&amp;bull;&amp;bull;&amp;bull;&amp;bull;&amp;bull;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://rocm.docs.amd.com/projects/radeon/en/latest/docs/install/wsl/install-pytorch.html#verify-pytorch-installation&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;verify pytorch installation&lt;/a&gt; 란을 확인해서 제대로 Pytorch가 GPU 환경에서 동작하는지 확인하자.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 최종확인&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, 다시한번 GPU가 제대로 Pytorch 에서 포착되는지 체크하자.&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;test.py&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1730043645719&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import torch
# ROCm 버전 확인
if hasattr(torch.version, 'hip'):
    print(f&quot;ROCm version: {torch.version.hip}&quot;)
else:
    print(&quot;ROCm is not available&quot;)

# GPU 감지 확인
if torch.cuda.is_available():
    print(&quot;CUDA GPU available&quot;)
elif hasattr(torch, 'hip') and torch.hip.is_available():
    print(&quot;ROCm GPU available&quot;)
else:
    print(&quot;No GPU detected&quot;)

# 사용 가능한 GPU 개수와 이름 확인
if torch.cuda.is_available() or (hasattr(torch, 'hip') and torch.hip.is_available()):
    print(f&quot;Number of GPUs: {torch.cuda.device_count()}&quot;)
    print(f&quot;GPU Name: {torch.cuda.get_device_name(0)}&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;output&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1730043752824&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ROCm version: 6.1.40093-bd86f1708
CUDA GPU available
Number of GPUs: 1
GPU Name: AMD Radeon RX 6800&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 문제점&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1730046544593&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import torch

# GPU 기본 정보 확인
print(&quot;CUDA available:&quot;, torch.cuda.is_available())
if torch.cuda.is_available():
    print(&quot;Current GPU:&quot;, torch.cuda.current_device())
    print(&quot;GPU name:&quot;, torch.cuda.get_device_name(0))
    print(&quot;GPU memory:&quot;, torch.cuda.get_device_properties(0).total_memory / 1024**3, &quot;GB&quot;)

# 아주 작은 텐서로 빠른 테스트
print(&quot;\n=== Quick Test ===&quot;)
x = torch.rand(100, 100, device=&quot;cuda&quot;)
y = torch.rand(100, 100, device=&quot;cuda&quot;)
print(&quot;Small tensors created on GPU&quot;)

# 간단한 연산 테스트
z = torch.matmul(x, y)
print(&quot;Matrix multiplication completed&quot;)

# GPU 메모리 상태 확인
if torch.cuda.is_available():
    print(&quot;\nGPU Memory Status:&quot;)
    print(f&quot;Allocated: {torch.cuda.memory_allocated(0)/1024**2:.2f} MB&quot;)
    print(f&quot;Cached: {torch.cuda.memory_reserved(0)/1024**2:.2f} MB&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;간단한 위의 코드를 실행시켜 보면 `x, y`에 텐서값을 할당할 때 연산이 되지 않는다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 코드가 `x` 지점에서 멈추며, 5분이상 기다려봐도 작동하지 않는다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;관련되서 Reddit 과 Github에 여러 의견이 있는데 참고하길 바란다.&lt;/p&gt;
&lt;figure id=&quot;og_1730046535096&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;From the ROCm community on Reddit&quot; data-og-description=&quot;Explore this post and more from the ROCm community&quot; data-og-host=&quot;www.reddit.com&quot; data-og-source-url=&quot;https://www.reddit.com/r/ROCm/comments/1e9uo5l/help_using_rocm_pytorch_on_wsl/&quot; data-og-url=&quot;https://www.reddit.com/r/ROCm/comments/1e9uo5l/help_using_rocm_pytorch_on_wsl/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bsPuv6/hyXlSqPjvW/aCYHwEAXxk9dzk8cfeREL0/img.jpg?width=1120&amp;amp;height=584&amp;amp;face=0_0_1120_584,https://scrap.kakaocdn.net/dn/FtOzl/hyXpo2HM2R/qORcf5EmagWM1t5IkLwkG1/img.jpg?width=1120&amp;amp;height=584&amp;amp;face=0_0_1120_584&quot;&gt;&lt;a href=&quot;https://www.reddit.com/r/ROCm/comments/1e9uo5l/help_using_rocm_pytorch_on_wsl/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.reddit.com/r/ROCm/comments/1e9uo5l/help_using_rocm_pytorch_on_wsl/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bsPuv6/hyXlSqPjvW/aCYHwEAXxk9dzk8cfeREL0/img.jpg?width=1120&amp;amp;height=584&amp;amp;face=0_0_1120_584,https://scrap.kakaocdn.net/dn/FtOzl/hyXpo2HM2R/qORcf5EmagWM1t5IkLwkG1/img.jpg?width=1120&amp;amp;height=584&amp;amp;face=0_0_1120_584');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;From the ROCm community on Reddit&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Explore this post and more from the ROCm community&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.reddit.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;뭐 그룹 추가 문제라는데... 시도해도 안된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;물론, RX6800은 AMD에서 공식적으로 ROCm을 지원하는 GPU가 아니기에 그럴 수 있다.&lt;/p&gt;
&lt;figure id=&quot;og_1730047010190&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;System requirements (Linux) &amp;mdash; ROCm installation (Linux)&quot; data-og-description=&quot;The following table shows the supported AMD Instinct&amp;trade; accelerators, and Radeon&amp;trade; PRO and Radeon GPUs. If a GPU is not listed on this table, it&amp;rsquo;s not officially supported by AMD. Accelerators and GPUs listed in the following table support compute workl&quot; data-og-host=&quot;rocm.docs.amd.com&quot; data-og-source-url=&quot;https://rocm.docs.amd.com/projects/install-on-linux/en/latest/reference/system-requirements.html#supported-gpus&quot; data-og-url=&quot;https://rocm.docs.amd.com/projects/install-on-linux/en/latest/reference/system-requirements.html#supported-gpus&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://rocm.docs.amd.com/projects/install-on-linux/en/latest/reference/system-requirements.html#supported-gpus&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://rocm.docs.amd.com/projects/install-on-linux/en/latest/reference/system-requirements.html#supported-gpus&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;System requirements (Linux) &amp;mdash; ROCm installation (Linux)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The following table shows the supported AMD Instinct&amp;trade; accelerators, and Radeon&amp;trade; PRO and Radeon GPUs. If a GPU is not listed on this table, it&amp;rsquo;s not officially supported by AMD. Accelerators and GPUs listed in the following table support compute workl&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;rocm.docs.amd.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;좀 재미있는 사실은, &lt;br /&gt;&lt;br /&gt;Windows 에서는 ROCm의 하위격인 HIP를 RX6800을 대상으로 지원한다.&lt;/p&gt;
&lt;figure id=&quot;og_1730047385261&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;System requirements (Windows) &amp;mdash; HIP SDK installation (Windows)&quot; data-og-description=&quot;ROCm components are described in What is ROCm? Support on Windows is provided with two levels on enablement. Note Some math libraries are Linux exclusive.&quot; data-og-host=&quot;rocm.docs.amd.com&quot; data-og-source-url=&quot;https://rocm.docs.amd.com/projects/install-on-windows/en/latest/reference/system-requirements.html&quot; data-og-url=&quot;https://rocm.docs.amd.com/projects/install-on-windows/en/latest/reference/system-requirements.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://rocm.docs.amd.com/projects/install-on-windows/en/latest/reference/system-requirements.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://rocm.docs.amd.com/projects/install-on-windows/en/latest/reference/system-requirements.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;System requirements (Windows) &amp;mdash; HIP SDK installation (Windows)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;ROCm components are described in What is ROCm? Support on Windows is provided with two levels on enablement. Note Some math libraries are Linux exclusive.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;rocm.docs.amd.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1083&quot; data-origin-height=&quot;1794&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yRn9U/btsKmS3f80e/K2b99jU3M1QPjkp2f8ZiCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yRn9U/btsKmS3f80e/K2b99jU3M1QPjkp2f8ZiCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yRn9U/btsKmS3f80e/K2b99jU3M1QPjkp2f8ZiCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyRn9U%2FbtsKmS3f80e%2FK2b99jU3M1QPjkp2f8ZiCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;1325&quot; data-origin-width=&quot;1083&quot; data-origin-height=&quot;1794&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;위에 22H2를 지원한다고 적혀있는데, 나는 현재 Windows 24H2 버전을 사용하고 있기에...&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;굳이 시도해보고 싶지 않다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(WSL2에 설치도 그냥 심심해서 시도해 본건데, 내 인내심이 다했다.)&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1730049007281&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;From the pytorch community on Reddit&quot; data-og-description=&quot;Explore this post and more from the pytorch community&quot; data-og-host=&quot;www.reddit.com&quot; data-og-source-url=&quot;https://www.reddit.com/r/pytorch/comments/10fiyyo/pytorch_windows_amd_radeon_gpu/&quot; data-og-url=&quot;https://www.reddit.com/r/pytorch/comments/10fiyyo/pytorch_windows_amd_radeon_gpu/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/X6kLg/hyXlIV28Gs/GFEmeY9m1z6hGVSJBw44i0/img.jpg?width=1120&amp;amp;height=584&amp;amp;face=0_0_1120_584,https://scrap.kakaocdn.net/dn/hau12/hyXlVVp3gb/7Nt8774vJsi17TPpiz8hTK/img.jpg?width=1120&amp;amp;height=584&amp;amp;face=0_0_1120_584&quot;&gt;&lt;a href=&quot;https://www.reddit.com/r/pytorch/comments/10fiyyo/pytorch_windows_amd_radeon_gpu/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.reddit.com/r/pytorch/comments/10fiyyo/pytorch_windows_amd_radeon_gpu/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/X6kLg/hyXlIV28Gs/GFEmeY9m1z6hGVSJBw44i0/img.jpg?width=1120&amp;amp;height=584&amp;amp;face=0_0_1120_584,https://scrap.kakaocdn.net/dn/hau12/hyXlVVp3gb/7Nt8774vJsi17TPpiz8hTK/img.jpg?width=1120&amp;amp;height=584&amp;amp;face=0_0_1120_584');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;From the pytorch community on Reddit&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Explore this post and more from the pytorch community&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.reddit.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;DirectML을 기반으로 잘 작동한다는 2년전 후기가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;결론적으로 ChatGPT를 기반으로 시작된 AI 붐으로 인해 AMD 측도 ROCm 생태계에 많은 관심을 쏟고 있는 듯 하지만,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;현재까지는 Nvidia 에 비해서 사용하기 매우 불편하다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;연구자들이건, 개발자들이건, 학생이건 복잡하게 셋팅하는걸 싫어하는데 ROCm은 셋팅이 짜증나고 자료도 적으며,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;버전마다 파편화가 심하다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Nvidia 는 GTX 1000 번대로도 잘 돌아간다.)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;여담으로 &lt;a href=&quot;https://ollama.com/blog/amd-preview&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Ollama 에서도 Radeon을 지원&lt;/a&gt;하기에 RX6800으로 Qwen 2.5 14B 모델도 구동시켜 보았지만,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이전에 사용하던 RTX3070 대비 토큰 생성속도가 1/4 정도이다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(깡성능은 오히려 RX6800이 +10% 이상 우위이다.)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;나는 앞으로 2027년도 까지는 Radeon RX 버전을 ML과 연관짓지 않기로 마음먹었다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6. WSL 환경이 아닌, Native Ubuntu 환경에서는 올바르게 작동한다.&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1735649654082&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;RX6800+ROCm VS Tesla T4+Cuda&quot; data-og-description=&quot;우선 이전 포스팅에서 WSL2 에서 ROCm 이 돌아가지 않아서, 반쯤 포기했었는데또다시 어느정도 기운을 차려서 다시한번 뻘짓을 하고 있다.이전 포스팅을 통해 내가 시도했던 WSL2 환경 위에서 RX6800&quot; data-og-host=&quot;cypsw.tistory.com&quot; data-og-source-url=&quot;https://cypsw.tistory.com/entry/RX6800ROCm-VS-Tesla-T4Cuda&quot; data-og-url=&quot;https://cypsw.tistory.com/entry/RX6800ROCm-VS-Tesla-T4Cuda&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/iBJhl/hyXWvUdHwC/lwuKJn1liSGcHZcuJmvSP0/img.png?width=800&amp;amp;height=298&amp;amp;face=0_0_800_298,https://scrap.kakaocdn.net/dn/Zelxy/hyXWthMXe4/dqxhht2Kwa7Vb2La9kT5yK/img.png?width=800&amp;amp;height=298&amp;amp;face=0_0_800_298,https://scrap.kakaocdn.net/dn/dkDbPV/hyXWwS5WSa/SMbIkS7T3tso2JMLrEkgq1/img.png?width=880&amp;amp;height=1414&amp;amp;face=0_0_880_1414&quot;&gt;&lt;a href=&quot;https://cypsw.tistory.com/entry/RX6800ROCm-VS-Tesla-T4Cuda&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cypsw.tistory.com/entry/RX6800ROCm-VS-Tesla-T4Cuda&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/iBJhl/hyXWvUdHwC/lwuKJn1liSGcHZcuJmvSP0/img.png?width=800&amp;amp;height=298&amp;amp;face=0_0_800_298,https://scrap.kakaocdn.net/dn/Zelxy/hyXWthMXe4/dqxhht2Kwa7Vb2La9kT5yK/img.png?width=800&amp;amp;height=298&amp;amp;face=0_0_800_298,https://scrap.kakaocdn.net/dn/dkDbPV/hyXWwS5WSa/SMbIkS7T3tso2JMLrEkgq1/img.png?width=880&amp;amp;height=1414&amp;amp;face=0_0_880_1414');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;RX6800+ROCm VS Tesla T4+Cuda&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;우선 이전 포스팅에서 WSL2 에서 ROCm 이 돌아가지 않아서, 반쯤 포기했었는데또다시 어느정도 기운을 차려서 다시한번 뻘짓을 하고 있다.이전 포스팅을 통해 내가 시도했던 WSL2 환경 위에서 RX6800&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;cypsw.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Operating System/WSL</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/206</guid>
      <comments>https://cypsw.tistory.com/entry/WSL2-%EC%97%90%EC%84%9C-ROCm-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0#entry206comment</comments>
      <pubDate>Mon, 28 Oct 2024 01:44:49 +0900</pubDate>
    </item>
    <item>
      <title>[리뷰] A Comprehensive Evaluation of Quantization Strategies for Large Language Models</title>
      <link>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-A-Comprehensive-Evaluation-of-Quantization-Strategies-for-Large-Language-Models</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2402.16775&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;해당&lt;/a&gt;논문은 LLM모델의 양자화와 성능의 상관관계에 대해서 기술한 논문으로, 최근 ollama 와 같은 local LLM 실행을 편리하게 도와줄 수 있는 기술들이 많이 등장한 가운데에 주목할만한 논문이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;만약 양자화에 대해서 잘 모른다면 아래 포스팅을 참고하길 바란다.&lt;/p&gt;
&lt;figure id=&quot;og_1727598496823&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[LLM] 양자화 기술&quot; data-og-description=&quot;양자화는 모델의 가중치와 활성화를 고정밀도 데이터 표현(F32)에서 저정밀도 데이터 표현으로 변환하는 모델 압축 기술쉽게 말해 복잡한 정보를 저장할 수 있는 데이터 유형에서 더 적은 정보&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@yuneun92/LLM-%EC%96%91%EC%9E%90%ED%99%94-%EA%B8%B0%EC%88%A0&quot; data-og-url=&quot;https://velog.io/@yuneun92/LLM-양자화-기술&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ck4WdM/hyW6EM8lVT/aCkfve8MftvoJg2HTL2FOK/img.png?width=1126&amp;amp;height=532&amp;amp;face=0_0_1126_532,https://scrap.kakaocdn.net/dn/em0GNd/hyW6HJQFIL/WLTAMoLtCIGMLObHlDAXLk/img.png?width=1126&amp;amp;height=532&amp;amp;face=0_0_1126_532,https://scrap.kakaocdn.net/dn/JzMRg/hyW6AcUKn0/SxfZsP90el41C8SMeAIsdK/img.png?width=1017&amp;amp;height=689&amp;amp;face=0_0_1017_689&quot;&gt;&lt;a href=&quot;https://velog.io/@yuneun92/LLM-%EC%96%91%EC%9E%90%ED%99%94-%EA%B8%B0%EC%88%A0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@yuneun92/LLM-%EC%96%91%EC%9E%90%ED%99%94-%EA%B8%B0%EC%88%A0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ck4WdM/hyW6EM8lVT/aCkfve8MftvoJg2HTL2FOK/img.png?width=1126&amp;amp;height=532&amp;amp;face=0_0_1126_532,https://scrap.kakaocdn.net/dn/em0GNd/hyW6HJQFIL/WLTAMoLtCIGMLObHlDAXLk/img.png?width=1126&amp;amp;height=532&amp;amp;face=0_0_1126_532,https://scrap.kakaocdn.net/dn/JzMRg/hyW6AcUKn0/SxfZsP90el41C8SMeAIsdK/img.png?width=1017&amp;amp;height=689&amp;amp;face=0_0_1017_689');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[LLM] 양자화 기술&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;양자화는 모델의 가중치와 활성화를 고정밀도 데이터 표현(F32)에서 저정밀도 데이터 표현으로 변환하는 모델 압축 기술쉽게 말해 복잡한 정보를 저장할 수 있는 데이터 유형에서 더 적은 정보&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;포스팅에 앞서&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 논문에 관심을 가지게 된 계기는 ollama에 배포된 대부분의 LLM 모델들이 4bit 양자화를 채택하고 있기 때문이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cR3lfR/btsJQyyi8PR/MDCoKQoyX2dh8q0AHzXX51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cR3lfR/btsJQyyi8PR/MDCoKQoyX2dh8q0AHzXX51/img.png&quot; data-origin-width=&quot;1118&quot; data-origin-height=&quot;755&quot; data-is-animation=&quot;false&quot; width=&quot;600&quot; height=&quot;405&quot; style=&quot;width: 50.9176%; margin-right: 10px;&quot; data-widthpercent=&quot;51.52&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cR3lfR/btsJQyyi8PR/MDCoKQoyX2dh8q0AHzXX51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcR3lfR%2FbtsJQyyi8PR%2FMDCoKQoyX2dh8q0AHzXX51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1118&quot; height=&quot;755&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p37i4/btsJPKfolSC/r6HYqHZkaTswRNBgxQ2hHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p37i4/btsJPKfolSC/r6HYqHZkaTswRNBgxQ2hHk/img.png&quot; data-origin-width=&quot;1133&quot; data-origin-height=&quot;813&quot; data-is-animation=&quot;false&quot; width=&quot;600&quot; height=&quot;431&quot; style=&quot;width: 47.9196%;&quot; data-widthpercent=&quot;48.48&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p37i4/btsJPKfolSC/r6HYqHZkaTswRNBgxQ2hHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp37i4%2FbtsJPKfolSC%2Fr6HYqHZkaTswRNBgxQ2hHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1133&quot; height=&quot;813&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4bit이면 상당히 낮은 bit의 양자화 수준이라고 할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;32bit : 양자화되지 않은&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(unquantized)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;16bit : Half-precision&lt;/li&gt;
&lt;li&gt;8bit&lt;/li&gt;
&lt;li&gt;4bit&lt;/li&gt;
&lt;li&gt;3bit&lt;/li&gt;
&lt;li&gt;2bit&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 양자화를 사용하는 이유는, 양자화에 따라서 필요한 VRAM 용량이 크게 줄어들기 때문이다. &lt;a href=&quot;https://www.reddit.com/r/LocalLLaMA/comments/1fljyly/llama_31_70b_at_60_toks_on_rtx_4090_iq2_xs/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Reddit의 한 사용자&lt;/a&gt;에 의하면 LLaMA 3.1 70B 2bit 양자화 모델은 RTX4090 24GB에서 구동된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본래 저정도의 LLM을 32bit 양자화 수준에서 구동하려면 어마어마한 VRAM이 필요하다. XiongjieDai 유저가 만든 &lt;a href=&quot;https://github.com/XiongjieDai/GPU-Benchmarks-on-LLM-Inference&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Gibhub 저장소&lt;/a&gt;에서는&amp;nbsp;LLaMA 3.0 모델의 양자화별 Benchmark를 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;1982&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ebbBT7/btsJQ3LqOfJ/qjgKswShkl4H1Agm3UVPH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ebbBT7/btsJQ3LqOfJ/qjgKswShkl4H1Agm3UVPH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ebbBT7/btsJQ3LqOfJ/qjgKswShkl4H1Agm3UVPH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FebbBT7%2FbtsJQ3LqOfJ%2FqjgKswShkl4H1Agm3UVPH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;1284&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;1982&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 표와 계산을 통해 예측해보면, 양자화되지 않은&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(32bit)&lt;/span&gt; 70B 수준의 모델을 Inference 용으로 구동하려면 최소한 280GB 수준의 VRAM이 필요하다는 사실을 추측할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 16bit 수준의 모델은 RTX3090 * 6, 즉 144GB 수준에서 구동이 가능한 것을 확인할 수 있다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(물론 초당 토큰 생성 개수가 5.82개 라면 끔찍하게 느린편이긴 하다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 자료들을 찾아보면서 궁금한점이 생겼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;양자화 수준과, 성능의 상관관계는 어떻게 될까?&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;서론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문의 시작 지점에서 저자들은 아래와 같은 점을 명확히 하고 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;본 논문에서는 공개적으로 이용 가능한 다양한 벤치마크를 활용하여 명령어 튜닝을 수행하는 양자화된 LLM에 대한 포괄적인 평가를 수행합니다. 이러한 벤치마크는 언어 이해 및 생성뿐만 아니라 LLM의 두 가지 중요한 측면인 지식, 역량 및 정렬을 다룹니다. 또한 생성 속도 및 메모리 소비 측면에서 효율성을 위해 다양한 양자화 전략을 평가합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 해당 논문은 어떠한 새로운것을 제안하지 않고, 속도와 메모리 소비 측면에서 Benchmark 데이터를 제공하는것에 그 목적을 둔다. 때문에 어려운 수식을 볼 필요도 없고, 이해하기 위해 머리를 싸맬 필요가 적은 논문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 양자화에는 크게 두가지 종류가 존재하는데 PTQ와 QAT라고 칭한다. 논문에서 저자들은 두가지 기법에 대해 아래와 같이 밝히고 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;PTQ는 모델 훈련 후에 양자화를 적용하는 반면, QAT는 훈련 과정에서 양자화의 영향을 고려하므로 상당한 리소스와 전문 지식이 필요하므로 광범위한 적용이 제한됩니다. 따라서 우리의 연구는 주로 PTQ에 중점을 두고 있습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔직히 나도 양자화에 관해서는 이론적인 배경만 잘 알고 있지, 실제로 QAT를 진행하는것이 얼마나 까다로운지는 잘 모른다. 하지만 QAT의 장점이 그만큼 뛰어나다면 현재 OpenLLM 기준 최고의 쌍두마차를 달리는 Meta, Alibaba 측에서 QAT 기반으로 된 양자화 모델을 출시하지 않을리가 없다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 관련된 자료가 딱히 보이지 않는걸로 봐서는 생각보다 QAT를 수행하는데 들어가는 수고로움 보다는 PTQ로 퉁쳐버리는게 싸고, 효율이 좋게 먹이는듯 싶다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(아니면 효율적인 관점에서 애매하다고 봐서 포기했거나.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 자료를 찾아봐도 정확한 데이터가 나오진 않으나, 위에서 언급한 ollama 의 양자화 역시 PTQ 일 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;평가 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자들은 양자화된 LLM을 평가하기 위해 아래와 같이 구조화된 평가 프레임워크를 제안하고 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;LLM에 대한 종합적인 평가는 다양성, 광범위한 적용, 설명 가능성 부족으로 인해 오랜 과제를 안고 있습니다. 이를 해결하기 위해 우리는 (1) Knowledge and Capacity, (2) Alignment, (3) Efficiency이라는 세 가지 중요한 차원을 포함하는 구조화된 평가 프레임워크를 제안합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 (1) Knowledge&amp;nbsp;and&amp;nbsp;Capacity을 테스트 하기 위해서 MMLU, C-EVAL 벤치마크를 사용한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(역사, 화학, 경제학을 포함한 다양한 주제를 통해 테스트)&lt;/span&gt;, 또한 언어능력을 평가하기 위해 FLORES-200, CNN/DailyMail, XSum, GSM8K, SNLI 벤치마크를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(2) Alignment을 테스트하기 위해 Askell et al. 이 제안한 HHH 기준을 사용한다. 주요 평가 기준은 helpfulness, honesty, harmlessness 이다. 3가지 기준을 각각을 테스트 하기 위해서 FollowBench&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Jiang et al.)&lt;/span&gt;, TruthfulQA&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Lin et al.)&lt;/span&gt;, BBQ&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Parrish et al.)&lt;/span&gt;를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(3) Efficiency를 테스트하기 위해 LLM을 실제로 Inference 중 사용되는 메모리의 양과, 생성 속도를 기준으로 평가한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 평가 과정은 Qwen-chat LLM 통해 진행된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;평가 결과&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그래프에 존재하는 GPTQ, LLM.int8(), SPQR은 서로다른 양자화 기법을 의미한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;(1) Knowledge and Capacity 부분에서 MMLU, C-EVAL 테스트를 진행한 결과는 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqKik6/btsJQbcyFd0/SsQ6Nubl3GDeLc7WrywiNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqKik6/btsJQbcyFd0/SsQ6Nubl3GDeLc7WrywiNK/img.png&quot; data-origin-width=&quot;1661&quot; data-origin-height=&quot;997&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqKik6/btsJQbcyFd0/SsQ6Nubl3GDeLc7WrywiNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqKik6%2FbtsJQbcyFd0%2FSsQ6Nubl3GDeLc7WrywiNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1661&quot; height=&quot;997&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JOrqG/btsJQCm6gT6/fBq5zAdvXJIsNB6FNVkyhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JOrqG/btsJQCm6gT6/fBq5zAdvXJIsNB6FNVkyhk/img.png&quot; data-origin-width=&quot;1661&quot; data-origin-height=&quot;997&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JOrqG/btsJQCm6gT6/fBq5zAdvXJIsNB6FNVkyhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJOrqG%2FbtsJQCm6gT6%2FfBq5zAdvXJIsNB6FNVkyhk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1661&quot; height=&quot;997&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;(a) MMLU, (b) C-EVAL&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;(1) 부분에서 언어능력 평가를 위해 사용한 FLORES-200 벤치마크는 영어 &amp;rarr; 중국어, 중국어 &amp;rarr; 영어 번역을 통해 진행하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQpIaZ/btsJQkNR4zd/KYwOO019sU2m8FcJjxUUMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQpIaZ/btsJQkNR4zd/KYwOO019sU2m8FcJjxUUMk/img.png&quot; data-origin-width=&quot;1661&quot; data-origin-height=&quot;997&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQpIaZ/btsJQkNR4zd/KYwOO019sU2m8FcJjxUUMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQpIaZ%2FbtsJQkNR4zd%2FKYwOO019sU2m8FcJjxUUMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1661&quot; height=&quot;997&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0aIjO/btsJPGYwHZf/qj9NZaEoatCyCVcpnrt5b0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0aIjO/btsJPGYwHZf/qj9NZaEoatCyCVcpnrt5b0/img.png&quot; data-origin-width=&quot;1661&quot; data-origin-height=&quot;997&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0aIjO/btsJPGYwHZf/qj9NZaEoatCyCVcpnrt5b0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0aIjO%2FbtsJPGYwHZf%2Fqj9NZaEoatCyCVcpnrt5b0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1661&quot; height=&quot;997&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;(좌) 영어 &amp;rarr; 중국어, (우) 중국어 &amp;rarr; 영어&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마찬가지로 (1)의 언어영역을 평가하기 위해 XSum을 사용하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csYmmb/btsJPLenJzp/SzOsTOr8oYj2Dl2RKOJapk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csYmmb/btsJPLenJzp/SzOsTOr8oYj2Dl2RKOJapk/img.png&quot; data-origin-width=&quot;1661&quot; data-origin-height=&quot;997&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csYmmb/btsJPLenJzp/SzOsTOr8oYj2Dl2RKOJapk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsYmmb%2FbtsJPLenJzp%2FSzOsTOr8oYj2Dl2RKOJapk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1661&quot; height=&quot;997&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brj2uF/btsJPD8wYI7/LuxkG2Wp6wsAU2xVYYHEtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brj2uF/btsJPD8wYI7/LuxkG2Wp6wsAU2xVYYHEtK/img.png&quot; data-origin-width=&quot;1661&quot; data-origin-height=&quot;997&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brj2uF/btsJPD8wYI7/LuxkG2Wp6wsAU2xVYYHEtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbrj2uF%2FbtsJPD8wYI7%2FLuxkG2Wp6wsAU2xVYYHEtK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1661&quot; height=&quot;997&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NwSeu/btsJPlNPdRH/kFKfQfSaO2B0dvBRbjm7I0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NwSeu/btsJPlNPdRH/kFKfQfSaO2B0dvBRbjm7I0/img.png&quot; data-origin-width=&quot;1661&quot; data-origin-height=&quot;997&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%;&quot; data-widthpercent=&quot;33.34&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NwSeu/btsJPlNPdRH/kFKfQfSaO2B0dvBRbjm7I0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNwSeu%2FbtsJPlNPdRH%2FkFKfQfSaO2B0dvBRbjm7I0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1661&quot; height=&quot;997&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;(a) Hard Satisfaction Rate (b) Soft Satisfaction Rate (c) Consistent Satisfaction Levels&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(2) Alignment 부분을 평가하기 위해 TruthfulQA 를 사용하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mv8nS/btsJPFSM5RC/TmYKzqbLKaHloDg3BNEVEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mv8nS/btsJPFSM5RC/TmYKzqbLKaHloDg3BNEVEK/img.png&quot; data-origin-width=&quot;1661&quot; data-origin-height=&quot;997&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mv8nS/btsJPFSM5RC/TmYKzqbLKaHloDg3BNEVEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmv8nS%2FbtsJPFSM5RC%2FTmYKzqbLKaHloDg3BNEVEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1661&quot; height=&quot;997&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6I24Z/btsJRDS1Vzr/xUSUFNo5rQFXUMkXAKTdk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6I24Z/btsJRDS1Vzr/xUSUFNo5rQFXUMkXAKTdk1/img.png&quot; data-origin-width=&quot;1661&quot; data-origin-height=&quot;997&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6I24Z/btsJRDS1Vzr/xUSUFNo5rQFXUMkXAKTdk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6I24Z%2FbtsJRDS1Vzr%2FxUSUFNo5rQFXUMkXAKTdk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1661&quot; height=&quot;997&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;(a)Bias scores in ambiguous context. (b)Bias scores in disambiguated context.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(3) Efficiency 부분의 테스트 결과&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIoNlL/btsJRoBNs95/KkmJFu0kLx16bGdkE2KcJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIoNlL/btsJRoBNs95/KkmJFu0kLx16bGdkE2KcJk/img.png&quot; data-origin-width=&quot;1661&quot; data-origin-height=&quot;997&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIoNlL/btsJRoBNs95/KkmJFu0kLx16bGdkE2KcJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIoNlL%2FbtsJRoBNs95%2FKkmJFu0kLx16bGdkE2KcJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1661&quot; height=&quot;997&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1q5j3/btsJPBiMlrT/JkNTzG1HSonXyOqip3fZY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1q5j3/btsJPBiMlrT/JkNTzG1HSonXyOqip3fZY1/img.png&quot; data-origin-width=&quot;1661&quot; data-origin-height=&quot;997&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1q5j3/btsJPBiMlrT/JkNTzG1HSonXyOqip3fZY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1q5j3%2FbtsJPBiMlrT%2FJkNTzG1HSonXyOqip3fZY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1661&quot; height=&quot;997&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;(a) Memory, (b) Speed&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SPQR의 경우 양자화된 가중치를 '고정밀도 형식' 으로 표현하는데, 이는 단순히 양자화된 가중치를 저정밀도 형식과 일치하도록 제한하는 방식이다. 이로 인해 실제 계산은 여전히 '고정밀도 방식' 으로 이뤄지므로 메모리 소비를 줄이는 효과가 존재하지 않는다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;SpQR Dettmers et al. (2023b) cleverly combines GPTQ (Frantar et al., 2023) and outlier value protection to further improve quantization performance. It uses a smaller group size and saves outliers through a sparse matrix. Currently, this method has not yet implemented the CUDA operator. So we need to use floating point numbers to simulate the integer quantization, which is called fake quantization. The code used in our experiments was modified from the official code$^5$ and adapted to Qwen.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 해당논문에서 제시하는 SPQR은 성능평가만 확인하고, 메모리 평가는 보지 않는것이 좋겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소감&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 전반적인 그래프를 확인하면 알 수 있듯 3bit 이하의 양자화는 가급적 사용하지 않는것이 좋겠다. 메모리 사용량도 4bit 양자화에 비해서 크게 효율적이지 않은 반면, 성능 하락폭은 상당히 큰 것을 볼 수 있다. 이는 ollama에서 왜 4bit 양자화를 메인으로 채택하였는지 알 수 있는 부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 전반적으로 SPQR의 성능이 GPTQ보다 높은 수준이다. 해당 논문에서는 메모리 소비를 실제로 감소시키는 SPQR을 적용시키지 않았기에 그 득실관계를 명확히 파악하기에 어려운 부분이 있지만, 어쨋든 성능적으로는 SPQR이 더 우세함을 알 수 있다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(메모리 소비는 아마 GPTQ와 큰 차이 없으리라 생각된다.)&lt;/span&gt;&lt;/p&gt;</description>
      <category>Artificial Intelligence/Paper Review</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/205</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-A-Comprehensive-Evaluation-of-Quantization-Strategies-for-Large-Language-Models#entry205comment</comments>
      <pubDate>Sun, 29 Sep 2024 18:34:14 +0900</pubDate>
    </item>
    <item>
      <title>모니터 PPI 추천</title>
      <link>https://cypsw.tistory.com/entry/%EB%AA%A8%EB%8B%88%ED%84%B0-PPI-%EC%B6%94%EC%B2%9C</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. PPI 란?&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;Pixels Per Inch&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;즉 1인치당 얼마나 많은 픽셀이 들어갈 수 있는지 나타내며, 아래와 같은 공식으로 계산할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;$$ \text{diagonal} = \sqrt{\text{width}^2 + \text{height}^2} $$&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;대각선&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(diagonal)&lt;/span&gt;의 길이는 피타고라스 공식을 통해 간단히 계산할 수 있으며&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이 대각선의 길이가 1인치일 때 해당 범위 내의 픽셀이 몇 개인지 구하면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;$$ \text{PPI} = \dfrac{\text{diagonal in pixels}}{\text{diagonal in inches}} $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. PPI 프리셋&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;1인치당 픽셀이 많을수록, 화면이 더 선명해진다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;404&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/puwWz/btsJuCuovCB/q35ZW0yQCtJe7mTieYhCcK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/puwWz/btsJuCuovCB/q35ZW0yQCtJe7mTieYhCcK/img.jpg&quot; data-alt=&quot;https://piamulholland.wordpress.com/unit-19/pixel/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/puwWz/btsJuCuovCB/q35ZW0yQCtJe7mTieYhCcK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpuwWz%2FbtsJuCuovCB%2Fq35ZW0yQCtJe7mTieYhCcK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;404&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;404&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://piamulholland.wordpress.com/unit-19/pixel/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;대중적으로 사용되는 모니터들의 PPI를 살펴보자&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;FHD(1920 x 1080)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;center&gt;
&lt;table style=&quot;border-collapse: collapse; width: 53.3722%; height: 165px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 33px;&quot;&gt;Inch&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 33px;&quot;&gt;PPI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 33px;&quot;&gt;22&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 33px;&quot;&gt;100.13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 33px;&quot;&gt;24&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 33px;&quot;&gt;91.76&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 33px;&quot;&gt;27&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 33px;&quot;&gt;81.59&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 33px;&quot;&gt;32&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 33px;&quot;&gt;68.84&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/center&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;QHD(2560 x 1440)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;center&gt;
&lt;table style=&quot;border-collapse: collapse; width: 53.3722%; height: 165px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;Inch&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;PPI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;22&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;133.51&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;24&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;122.38&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;27&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;108.79&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;32&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;91.79&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/center&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;UWQHD(3440 x 1440)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;center&gt;
&lt;table style=&quot;border-collapse: collapse; width: 53.2558%; height: 54px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;Inch&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;PPI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;34&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;109.68&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/center&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;UHD(3840 x 2160)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;center&gt;
&lt;table style=&quot;border-collapse: collapse; width: 53.3722%; height: 221px;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;Inch&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;PPI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;22&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;200.26&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;24&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;183.58&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;27&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;163.18&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;32&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 33px; text-align: center;&quot;&gt;137.68&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 28px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 28px;&quot;&gt;43&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 28px;&quot;&gt;102.46&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 28px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 28px;&quot;&gt;48&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 28px;&quot;&gt;91.79&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/center&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;WUHD(5120 x 2160)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;center&gt;
&lt;table style=&quot;border-collapse: collapse; width: 53.6047%; height: 74px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 17px;&quot;&gt;Inch&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 17px;&quot;&gt;PPI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 17px;&quot;&gt;40&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 17px;&quot;&gt;138.92&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/center&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 보편적으로 추천되는 PPI&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;보편적으로 아래와 같은 사양을 권장한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;FHD = 27인치 이하&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;QHD = 32인치 이하&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;4K = 48인치 이하&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 개인적으로 추천하는 PPI&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;위에서는 어느정도 포멀한 의견을 나열했고... 겉치레 없는 내 생각을 말하자면&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;32인치 FHD는 쓰레기다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;몇몇 PC방에서 32인치 FHD를 사용하던데, 순수 게임만 하더라도 매우 비추천한다. 픽셀이 전부 보이는 수준이다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;27인치 FHD, 32인치 QHD를 많은 곳에서 널리 사용하고 있지만... 나라면 안쓴다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;PPI가 높은편이 아니기에, 문서 작업을 할 때 피로도가 증가한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;24인치 FHD도 왠만하면 안쓰는게 좋다. 아니, 그냥 FHD 해상도 자체를 권장하지 않는다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;물론 게임용이면 FHD 사용해도 괜찮다. 하지만 금전적 문제가 아닌 이상, 글을 전문적으로 보는 용도로 FHD 모니터 자체를 비추천한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;개인적으로 PPI 120 이상의 모니터를 추천한다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;24인치 QHD도 조금 눈에 거슬리긴 하나, 27인치 FHD 따위에 비하면 훨신 선명하게, 쾌적한 작업이 가능하다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;32인치 모니터를 글을 보는 용도로 쓰고 싶다면 4K를 추천한다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;32인치 4K HiDPI 150% 기준 선명하게 사용할 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;참고로 높은 PPI에서는 가급적 HiDPI를 사용하는 것을 권장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 극한의 PPI&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;iMac 에서 사용하는 27인치 5120 x 2880 해상도 모델의 PPI가 218이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;나도 이정도의 제품을 사용하고 싶으나, Windows를 메인으로 사용하기에 마땅한 제품이 없으며&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;보통 5K 모니터는 Mac 전용이다.&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1725663866594&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;[다나와] 삼성전자 뷰피니티 S9 S90PC S27C900&quot; data-og-description=&quot;최저가 1,259,170원, 현금최저가: 1,159,990원&quot; data-og-host=&quot;prod.danawa.com&quot; data-og-source-url=&quot;https://prod.danawa.com/info/?pcode=20635622&amp;amp;keyword=5K+%EB%AA%A8%EB%8B%88%ED%84%B0&amp;amp;cate=112757&quot; data-og-url=&quot;https://prod.danawa.com/info/?cate=112757&amp;amp;keyword=5K+%EB%AA%A8%EB%8B%88%ED%84%B0&amp;amp;pcode=20635622&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cgAwSj/hyWY8NoVLT/HVnK4zazjKqD0mAGt720R1/img.jpg?width=160&amp;amp;height=160&amp;amp;face=0_0_160_160,https://scrap.kakaocdn.net/dn/cM0mJv/hyWZgSdZFB/4EXWYcwyG2L4YRw5knwJRk/img.jpg?width=330&amp;amp;height=330&amp;amp;face=0_0_330_330&quot;&gt;&lt;a href=&quot;https://prod.danawa.com/info/?pcode=20635622&amp;amp;keyword=5K+%EB%AA%A8%EB%8B%88%ED%84%B0&amp;amp;cate=112757&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://prod.danawa.com/info/?pcode=20635622&amp;amp;keyword=5K+%EB%AA%A8%EB%8B%88%ED%84%B0&amp;amp;cate=112757&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cgAwSj/hyWY8NoVLT/HVnK4zazjKqD0mAGt720R1/img.jpg?width=160&amp;amp;height=160&amp;amp;face=0_0_160_160,https://scrap.kakaocdn.net/dn/cM0mJv/hyWZgSdZFB/4EXWYcwyG2L4YRw5knwJRk/img.jpg?width=330&amp;amp;height=330&amp;amp;face=0_0_330_330');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[다나와] 삼성전자 뷰피니티 S9 S90PC S27C900&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;최저가 1,259,170원, 현금최저가: 1,159,990원&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;prod.danawa.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;게이밍 겸용인 제품은 더더욱 없기에, 어쩔 수 없이 4K 32인치 모니터를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;마지막으로, PPI는 어디까지 높여야 그 한계에 달할까?&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.discovery.com/science/mexapixels-in-human-eye&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;몇몇 포스팅&lt;/a&gt;에서 우리의 눈의 해상도에 대해 추론한 것을 볼 수 있으며,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;576,000,000 픽셀 정도가 눈의 해상도라고 주장한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 위 포스팅 내용에 근거해, 1미터 간격을 둔 32인치 모니터의 Maximum PPI를 대-강 환산하자면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;약 16K 해상도, 즉 PPI 550정도면 눈의 물리적인 한계를 초과하기에&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;더이상 높은 PPI가 필요하지 않으리라 생각된다.&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Miscellaneous/Hardware</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/202</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%AA%A8%EB%8B%88%ED%84%B0-PPI-%EC%B6%94%EC%B2%9C#entry202comment</comments>
      <pubDate>Sat, 7 Sep 2024 08:08:47 +0900</pubDate>
    </item>
    <item>
      <title>Firefox는 131 버전에서 세로 탭(Vertical Tab) 기능을 지원할 예정</title>
      <link>https://cypsw.tistory.com/entry/Firefox%EB%8A%94-131-%EB%B2%84%EC%A0%84%EC%97%90%EC%84%9C-%EC%84%B8%EB%A1%9C-%ED%83%ADVertical-Tab-%EA%B8%B0%EB%8A%A5%EC%9D%84-%EA%B3%B5%EC%8B%9D-%EC%A7%80%EC%9B%90%ED%95%A0-%EC%98%88%EC%A0%95</link>
      <description>&lt;figure id=&quot;og_1724350885535&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Firefox Sidebar and Vertical tabs: try them out in Nightly Firefox Labs 131 &amp;ndash; Firefox Nightly News&quot; data-og-description=&quot;We are excited to share that vertical tabs and a new sidebar experience are now available in Nightly 131. This update has been highly anticipated and requested by the community, ...&quot; data-og-host=&quot;blog.nightly.mozilla.org&quot; data-og-source-url=&quot;https://blog.nightly.mozilla.org/2024/08/07/firefox-sidebar-and-vertical-tabs-try-them-out-in-nightly-firefox-labs-131/&quot; data-og-url=&quot;https://blog.nightly.mozilla.org/2024/08/07/firefox-sidebar-and-vertical-tabs-try-them-out-in-nightly-firefox-labs-131&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dJuo5s/hyWSfTwMzZ/fuq7Z2GVi9VvaSeTxZ2jak/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512,https://scrap.kakaocdn.net/dn/bob9j3/hyWSbwNLVD/wfeu7HEumRtoqxkgtgH8M0/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512&quot;&gt;&lt;a href=&quot;https://blog.nightly.mozilla.org/2024/08/07/firefox-sidebar-and-vertical-tabs-try-them-out-in-nightly-firefox-labs-131/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://blog.nightly.mozilla.org/2024/08/07/firefox-sidebar-and-vertical-tabs-try-them-out-in-nightly-firefox-labs-131/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dJuo5s/hyWSfTwMzZ/fuq7Z2GVi9VvaSeTxZ2jak/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512,https://scrap.kakaocdn.net/dn/bob9j3/hyWSbwNLVD/wfeu7HEumRtoqxkgtgH8M0/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Firefox Sidebar and Vertical tabs: try them out in Nightly Firefox Labs 131 &amp;ndash; Firefox Nightly News&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;We are excited to share that vertical tabs and a new sidebar experience are now available in Nightly 131. This update has been highly anticipated and requested by the community, ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.nightly.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;24년 8월 7일 Firefox 블로그에서 드디어 Vertical Tab 기능을 지원한다는 포스팅을 기재했다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;내가 아는 바에 의하면 Vertical Tab을 온전히 지원하는 브라우저는 Edge가 유일하다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Whale 에서도 지원은 하는데... 뭔가 나사가 빠진듯 작동한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이 기능은 Nightly 버전에 그대로 구현되어서 현재 사용해 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;1104&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bu4We4/btsJb5xvOeO/gMqeNDOyPbaIjhX2PXh2fK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bu4We4/btsJb5xvOeO/gMqeNDOyPbaIjhX2PXh2fK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bu4We4/btsJb5xvOeO/gMqeNDOyPbaIjhX2PXh2fK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbu4We4%2FbtsJb5xvOeO%2FgMqeNDOyPbaIjhX2PXh2fK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;650&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;1104&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;현재는 `Sidebar` + `Vertical Tab`을 동시에 활성화 해야 사용할 수 있는데,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;좀 비 직관적이라는 생각이 들었다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아마도 Mozilla 측의 개발자들과, 커뮤니티 기여자들 역시 나와 비슷한 생각을 할 것이기에&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;정식 버전 업데이트에서는 옵션 선택이 보다 간결해 질 것으로 예상한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/va6ky/btsJbHQ4khN/OmsmImRUpkMNzrMo9a5KWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/va6ky/btsJbHQ4khN/OmsmImRUpkMNzrMo9a5KWK/img.png&quot; data-origin-width=&quot;1916&quot; data-origin-height=&quot;1552&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;49.97&quot; data-filename=&quot;blob&quot; style=&quot;width: 49.3875%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/va6ky/btsJbHQ4khN/OmsmImRUpkMNzrMo9a5KWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fva6ky%2FbtsJbHQ4khN%2FOmsmImRUpkMNzrMo9a5KWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1916&quot; height=&quot;1552&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhkz8r/btsJcSKX1dF/zYZwK6nberV1zyLRk1RIz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhkz8r/btsJcSKX1dF/zYZwK6nberV1zyLRk1RIz1/img.png&quot; data-origin-width=&quot;1911&quot; data-origin-height=&quot;1546&quot; data-is-animation=&quot;false&quot; width=&quot;800&quot; height=&quot;649&quot; data-widthpercent=&quot;50.03&quot; data-filename=&quot;blob&quot; style=&quot;width: 49.4498%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhkz8r/btsJcSKX1dF/zYZwK6nberV1zyLRk1RIz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbhkz8r%2FbtsJcSKX1dF%2FzYZwK6nberV1zyLRk1RIz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1911&quot; height=&quot;1546&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;위와 같이 Sidebar 표시 옵션을 지정하여 Vertical Tab을 펼치거나 접을 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;여담으로 현재 Firefox의 Sidebar는 단일로 구동되어 여러 확장기능과 충돌이 발생한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이는 정식 버전 출시시 고쳐지리라 믿는다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;예상 정식 버전 업데이트 시기는 24년 10월이나, 여러 문제로 인해 연기될 가능성도 존재한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;+ 2025.01.08 추가사항&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1492&quot; data-origin-height=&quot;448&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDnImL/btsLGWKTyZl/zLRfJYfJzo9QNxt19alLWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDnImL/btsLGWKTyZl/zLRfJYfJzo9QNxt19alLWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDnImL/btsLGWKTyZl/zLRfJYfJzo9QNxt19alLWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDnImL%2FbtsLGWKTyZl%2FzLRfJYfJzo9QNxt19alLWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;240&quot; data-origin-width=&quot;1492&quot; data-origin-height=&quot;448&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;안정성이 부족하다 느꼇는지 정식 Relase 에서는 출시하지 않았다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 `about:config` 옵션에서 활성화 시킬 수 있다.&lt;/p&gt;</description>
      <category>Tools/Etc</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/201</guid>
      <comments>https://cypsw.tistory.com/entry/Firefox%EB%8A%94-131-%EB%B2%84%EC%A0%84%EC%97%90%EC%84%9C-%EC%84%B8%EB%A1%9C-%ED%83%ADVertical-Tab-%EA%B8%B0%EB%8A%A5%EC%9D%84-%EA%B3%B5%EC%8B%9D-%EC%A7%80%EC%9B%90%ED%95%A0-%EC%98%88%EC%A0%95#entry201comment</comments>
      <pubDate>Fri, 23 Aug 2024 03:31:20 +0900</pubDate>
    </item>
    <item>
      <title>VMware Workstation Pro 다운로드 방법</title>
      <link>https://cypsw.tistory.com/entry/VMware-Workstation-Pro-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C-%EB%B0%A9%EB%B2%95</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Vmware_workstation_16_icon.svg.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJtAAv/btsIKA6fj3m/3XiPbAUtuWDN6VoH0OrMbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJtAAv/btsIKA6fj3m/3XiPbAUtuWDN6VoH0OrMbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJtAAv/btsIKA6fj3m/3XiPbAUtuWDN6VoH0OrMbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJtAAv%2FbtsIKA6fj3m%2F3XiPbAUtuWDN6VoH0OrMbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;180&quot; height=&quot;180&quot; data-filename=&quot;Vmware_workstation_16_icon.svg.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;VMware Workstation Pro&lt;/b&gt;&lt;/span&gt; 는 가상머신 프로그램으로서&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Broadcom에 인수된 상황이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;130&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d04dHP/btsINbwJaX3/u5jWxJax6Py5qI59ZOShm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d04dHP/btsINbwJaX3/u5jWxJax6Py5qI59ZOShm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d04dHP/btsINbwJaX3/u5jWxJax6Py5qI59ZOShm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd04dHP%2FbtsINbwJaX3%2Fu5jWxJax6Py5qI59ZOShm0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;584&quot; height=&quot;130&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;130&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그런데 문제는 Broadcom이 인수하면서 웹사이트의 편의성이 많이 안좋아졌다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 VMware Workstation을 다운로드 하는 방법 역시 까다로워 졌다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아무리 Broadcom 이 B2B에 치중되어 있다지만,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;유저 경험에 있어서 신경을 안 쓴 치명적인 UI로 여러 커뮤니티에서 욕받이가 되고 있다&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(...)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;1199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bisjJl/btsIKLmecvw/BVOWc2NLYjBqtk8RlWvldK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bisjJl/btsIKLmecvw/BVOWc2NLYjBqtk8RlWvldK/img.png&quot; data-alt=&quot;https://www.reddit.com/r/vmware/comments/1d4eivz/vmware_workstation_pro_17_windows_where_to/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bisjJl/btsIKLmecvw/BVOWc2NLYjBqtk8RlWvldK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbisjJl%2FbtsIKLmecvw%2FBVOWc2NLYjBqtk8RlWvldK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;880&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;1199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://www.reddit.com/r/vmware/comments/1d4eivz/vmware_workstation_pro_17_windows_where_to/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Broadcom 사이트에서 다운받는게 까다로우니 아카이빙된 파일을 다운받아 사용하는 유저들의 모습을 볼 수 있는데,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이는 위험한 방식이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Broadcom 사이트에서 직접 다운로드 받는것을 추천하며, 그 방법에 대해서 소개한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. Broadcom 사이트에 회원가입 &amp;amp; 로그인&lt;/b&gt;&lt;/h4&gt;
&lt;figure id=&quot;og_1721814217319&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Home - Support Portal - Broadcom support portal&quot; data-og-description=&quot;It appears your Broadcom Products and Services are supported by one of our certified Support partners Click below to be redirected to the appropriate Support Partner Portal to request support For non-product related issues (Support Portal / Licensing) Clic&quot; data-og-host=&quot;support.broadcom.com&quot; data-og-source-url=&quot;https://support.broadcom.com/web/ecx/home&quot; data-og-url=&quot;https://support.broadcom.com/web/ecx&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cgh1qo/hyWCI24ziO/SwYGfBcbz147MzQnG1UKM0/img.png?width=1250&amp;amp;height=1250&amp;amp;face=0_0_1250_1250,https://scrap.kakaocdn.net/dn/hfeGL/hyWCL6zU3q/yHNydB4QYinfwF5jkTU8K1/img.png?width=1250&amp;amp;height=1250&amp;amp;face=0_0_1250_1250&quot;&gt;&lt;a href=&quot;https://support.broadcom.com/web/ecx/home&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://support.broadcom.com/web/ecx/home&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cgh1qo/hyWCI24ziO/SwYGfBcbz147MzQnG1UKM0/img.png?width=1250&amp;amp;height=1250&amp;amp;face=0_0_1250_1250,https://scrap.kakaocdn.net/dn/hfeGL/hyWCL6zU3q/yHNydB4QYinfwF5jkTU8K1/img.png?width=1250&amp;amp;height=1250&amp;amp;face=0_0_1250_1250');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Home - Support Portal - Broadcom support portal&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;It appears your Broadcom Products and Services are supported by one of our certified Support partners Click below to be redirected to the appropriate Support Partner Portal to request support For non-product related issues (Support Portal / Licensing) Clic&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;support.broadcom.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Broadcom Support Portal에 가입 및 로그인한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. VMWare Cloud Foundation 진입&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2183&quot; data-origin-height=&quot;1214&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rax3T/btsIKKHBR7v/bN3hfQKPiMqkKfBH720KVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rax3T/btsIKKHBR7v/bN3hfQKPiMqkKfBH720KVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rax3T/btsIKKHBR7v/bN3hfQKPiMqkKfBH720KVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frax3T%2FbtsIKKHBR7v%2FbN3hfQKPiMqkKfBH720KVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;445&quot; data-origin-width=&quot;2183&quot; data-origin-height=&quot;1214&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. My Downloads 진입 후 Workstation 검색 &amp;rarr; VMware Workstation Pro 클릭&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2435&quot; data-origin-height=&quot;1064&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Dg6aq/btsIKJWe3qe/R4FtKVRKR4h73Wf4wNCiKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Dg6aq/btsIKJWe3qe/R4FtKVRKR4h73Wf4wNCiKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Dg6aq/btsIKJWe3qe/R4FtKVRKR4h73Wf4wNCiKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDg6aq%2FbtsIKJWe3qe%2FR4FtKVRKR4h73Wf4wNCiKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;350&quot; data-origin-width=&quot;2435&quot; data-origin-height=&quot;1064&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. Personal Use 버전 다운로드&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2050&quot; data-origin-height=&quot;1531&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEa6hM/btsIMGqbFyj/Xjusmek5BzUrRC8lyf3K01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEa6hM/btsIMGqbFyj/Xjusmek5BzUrRC8lyf3K01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEa6hM/btsIMGqbFyj/Xjusmek5BzUrRC8lyf3K01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEa6hM%2FbtsIMGqbFyj%2FXjusmek5BzUrRC8lyf3K01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;597&quot; data-origin-width=&quot;2050&quot; data-origin-height=&quot;1531&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;특별한 이유가 없다면 Release 버전은 최신 버전을 권장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2052&quot; data-origin-height=&quot;1016&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dhHDXy/btsIKBKPXr7/JnseUb7k4XeAcUN1ftTGw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dhHDXy/btsIKBKPXr7/JnseUb7k4XeAcUN1ftTGw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dhHDXy/btsIKBKPXr7/JnseUb7k4XeAcUN1ftTGw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdhHDXy%2FbtsIKBKPXr7%2FJnseUb7k4XeAcUN1ftTGw1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;396&quot; data-origin-width=&quot;2052&quot; data-origin-height=&quot;1016&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;우측의 다운로드를 클릭하여 다운받는다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. VMware Workstation Pro 설치 후 실행&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;436&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QyQol/btsIMbqGQgZ/fjmQ7mbnvRKkvPw6PDKbtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QyQol/btsIMbqGQgZ/fjmQ7mbnvRKkvPw6PDKbtk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QyQol/btsIMbqGQgZ/fjmQ7mbnvRKkvPw6PDKbtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQyQol%2FbtsIMbqGQgZ%2FfjmQ7mbnvRKkvPw6PDKbtk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;481&quot; height=&quot;436&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;436&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;기업, 기관에서 사용시 반드시 라이센스를 구입하길 바라며,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;개인 용도로 사용시에만 Personal Use를 클릭하여 실행하면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;VMware에서 다운받을때는 절차가 직관적이여서, 어떤 Guideline 도 보지 않고 쉽게 다운로드 할 수 있었지만&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Broadcom이 인수하고 난 뒤에는 &lt;span style=&quot;text-align: center;&quot;&gt;Guideline 없이 다운로드 하는게 어렵다는것이 중론이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: center;&quot;&gt;다만 Broadcom 입장에서는 개인 사용자가 매출에 직접적으로 도움이 되는것도 아니니..&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: center;&quot;&gt;개선될 전망은 없어 보인다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: center;&quot;&gt;무료로 배포해 줌에 감사하며 사용할 예정이다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Tools/Etc</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/199</guid>
      <comments>https://cypsw.tistory.com/entry/VMware-Workstation-Pro-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C-%EB%B0%A9%EB%B2%95#entry199comment</comments>
      <pubDate>Wed, 24 Jul 2024 18:56:48 +0900</pubDate>
    </item>
    <item>
      <title>Ubuntu SSH 2FA 활성화 방법</title>
      <link>https://cypsw.tistory.com/entry/Ubuntu-SSH-2FA-%ED%99%9C%EC%84%B1%ED%99%94-%EB%B0%A9%EB%B2%95</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;기본적으로 Canoncial Ubuntu 공식 홈페이지에서 제공하는 방법을 따른다.&lt;/p&gt;
&lt;figure id=&quot;og_1720280244999&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;https://ubuntu.com/tutorials/configure-ssh-2fa#1-overview&quot; data-og-description=&quot;&quot; data-og-host=&quot;ubuntu.com&quot; data-og-source-url=&quot;https://ubuntu.com/tutorials/configure-ssh-2fa#1-overview&quot; data-og-url=&quot;https://ubuntu.com/tutorials/configure-ssh-2fa#1-overview&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://ubuntu.com/tutorials/configure-ssh-2fa#1-overview&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ubuntu.com/tutorials/configure-ssh-2fa#1-overview&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;https://ubuntu.com/tutorials/configure-ssh-2fa#1-overview&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ubuntu.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;다만 해당 Guideline 기준 다른점이 하나 존재하고,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;몇몇 설정에 관해 설명이 필요할 듯 싶어 포스팅을 작성한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;1. 사전에 알아두어야 사항&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Ubuntu 16.04 LTS 버전 이상을 구동할 수 있는 컴퓨터&lt;/li&gt;
&lt;li&gt;안드로이드 또는 IOS 휴대폰&lt;/li&gt;
&lt;li&gt;구성된 SSH 연결&lt;/li&gt;
&lt;li&gt;비밀번호 도난의 위험성을 이해&lt;/li&gt;
&lt;li&gt;2FA가 무엇인지, 어떻게 작동하는지 알 필요는 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;실질적인 준비물은 위에서 3가지 이며, 대부분 사용자가 충족할 것이라 생각된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;'비밀번호 도난의 위험성을 이해' 에 대한 이야기를 하자면,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;키보드 후킹으로 인해 비밀번호 노출위험이 있으며, 설사 키보드 후킹 방지가 되어 있더라도&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;CCTV, 엿보기, 실수 등으로 인해 평문 비밀번호는 상당히 쉽게 노출될 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 100자리 비밀번호를 지정한다고 해도 큰 의미가 없을 수 있기에&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;2FA를 모든곳에서 사용하는것을 권장한다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;2.&lt;span&gt; 설치 방법&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Google Authenticator 모듈을 설치한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1720275847255&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apt install libpam-google-authenticator&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;`/etc/pam.d/sshd` 파일에 아래 문구 추가&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(최하단에 추가하면 된다)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1720276275007&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;auth required pam_google_authenticator.so&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;sshd 재시작&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1720285071846&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;systemctl restart sshd.service&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;`/etc/ssh/sshd_config` 파일 내의 KbdInteractiveAuthentication&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(ChallengeResponseAuthentication)&lt;/span&gt; yes 로 수정&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1720276765771&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;KbdInteractiveAuthentication yes&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Ubuntu 24.04 버전 기준으로 ChallengeResponseAuthentication 옵션은 KbdInteractiveAuthentication 로 &lt;a href=&quot;https://askubuntu.com/questions/1403846/ssh-challengeresponseauthentication-in-22-04-ubuntu&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;대체&lt;/a&gt;되었다. 때문에 둘중 확인된 하나의 옵션만 yes 로 변경해 주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;터미널에서 설치한 Google&amp;nbsp;Authenticator를&amp;nbsp;실행한다.&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1720277239550&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;google-authenticator&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;화면에 보이는 QR 코드를 스마트폰 Authenticator 앱에 인식시켜 등록 과정을 진행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;369&quot; data-origin-height=&quot;495&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qyskF/btsIrcCTAxB/fmxwitXOviuLNy6PMPTek1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qyskF/btsIrcCTAxB/fmxwitXOviuLNy6PMPTek1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qyskF/btsIrcCTAxB/fmxwitXOviuLNy6PMPTek1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqyskF%2FbtsIrcCTAxB%2FfmxwitXOviuLNy6PMPTek1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;369&quot; height=&quot;495&quot; data-origin-width=&quot;369&quot; data-origin-height=&quot;495&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 Ubuntu에 설치한 모듈이 Google Authenticator 라고 해서 반드시 스마트폰에서 Google Authenticator를 사용할 필요는 없다. Microsoft Authenticator 등도 원활히 작동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 제공되는 emergency scratch codes는 가능하면 물리적으로 적어 서랍 등에 보관하는 것을 권장한다. 본인이 보안 전문가가 아닌이상 디지털 매체에 적어둘 경우, 어떤 매체에서 어떻게 보안이슈가 발생했는지 파악하기 어렵다. 하지만 내 집 서랍속에 기록된 scratch codes가 도난당할 경우, 어떻게 보안이슈가 발생했는지 파악하기 용이하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;추가 옵션 지정&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1720278560643&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. Do you want me to update your &quot;/root/.google_authenticator&quot; file? (y/n) y

2. Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y

3. By default, a new token is generated every 30 seconds by the mobile app.
In order to compensate for possible time-skew between the client and the server,
we allow an extra token before and after the current time. This allows for a
time skew of up to 30 seconds between authentication server and client. If you
experience problems with poor time synchronization, you can increase the window
from its default size of 3 permitted codes (one previous code, the current
code, the next code) to 17 permitted codes (the 8 previous codes, the current
code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
between client and server.
Do you want to do so? (y/n) n

4. If the computer that you are logging into is not hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting? (y/n) y&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;1.옵션은 Google Authenticator를 사용하기 위해 y로 지정한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;2.옵션은 만약 로그인을 실패할 시 동일한 인증 토큰을 사용할 수 없게 지정한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(y 권장)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;3. 옵션은 시간동기화 기능을 느슨하게 한다. 이로 인해 보안 취약성이 '약간' 증가할 수 있다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(n 권장)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;4. 30초마다 3회 이하의 로그인 시도로 제한한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(y 권장)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;3.&lt;span&gt;&lt;span&gt;&amp;nbsp;로그인&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;로그인 시 아래와 같이 Verification Code를 입력하는 창이 발생한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;159&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nxZfe/btsIpZq0YIF/h6mMdfA8KRUfO05HUWuwX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nxZfe/btsIpZq0YIF/h6mMdfA8KRUfO05HUWuwX1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nxZfe/btsIpZq0YIF/h6mMdfA8KRUfO05HUWuwX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnxZfe%2FbtsIpZq0YIF%2Fh6mMdfA8KRUfO05HUWuwX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;613&quot; height=&quot;149&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;159&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;스마트폰에 설치한 &lt;span style=&quot;text-align: start;&quot;&gt;Authen&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;ticator&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt; 앱을 통해 Verification 코드를 입력하면 로그인된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;4. 추가사항&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비밀번호를 Brute Force 공격에 안전할 만큼 길게 입력하고, 2FA를 지정했다면 물리적 접촉이 없는 해커의 공격에 웬만하면 뚫리지 않을것이다. 하지만 여기에 추가로, 만약의 상황을 대비하여 로그 `/var/log/auth.log`를 확인하는 습관을 가지자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;5. Public Key 방식과의 장단점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Public Key 방식으로 SSH를 인증하는 경우도 있는데, 보안상으로는 장단점이 있다. Public Key 방식은 통상적인 비밀번호 입력 과정이 없으므로 원천적으로 Brute Force 공격에 있어 안전하다. 2FA 방식이 정말 낮은 확률로 파훼가 가능한것과는 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 Public Key 방식의 문제점은 Private Key를 누군가가 탈취했을 때 접근을 허용한다는 문제가 존재한다. 때문에 2FA 방식과 Public Key 방식은 서로 장단점이 존재하며, 최고의 보안을 위해서는 Public Key 방식 + 2FA 방식을 동시 운용하는것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 Public Key 방식을 사용했을 때의 편리한 점은 Visual Studio Code 에서 Directory를 변경 할 때 추가적인 비밀번호 입력과정이 필요하지 않기에 편리함을 느꼇다.&lt;/p&gt;</description>
      <category>Operating System/Linux</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/196</guid>
      <comments>https://cypsw.tistory.com/entry/Ubuntu-SSH-2FA-%ED%99%9C%EC%84%B1%ED%99%94-%EB%B0%A9%EB%B2%95#entry196comment</comments>
      <pubDate>Sun, 7 Jul 2024 00:36:56 +0900</pubDate>
    </item>
    <item>
      <title>Docker Desktop 없이 WSL2에 Docker 설치</title>
      <link>https://cypsw.tistory.com/entry/Docker-Desktop-%EC%97%86%EC%9D%B4-WSL2%EC%97%90-Docker-%EC%84%A4%EC%B9%98</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;현재 Docker Desktop은 &lt;a href=&quot;https://devocean.sk.com/blog/techBoardDetail.do?ID=163537&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;상업적 이용시 대기업 유료화 정책&lt;/a&gt;을 채택하고 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 개인적으로 Docker Desktop을 사용하는것을 선호하지 않고,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;개인 작업 환경에서도 WSL2 를 통해 Docker Engine을 사용하는 방식으로 사용하고 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;최근 Ubuntu LTS 버전이 24.04 로 업데이트 되기도 하였고,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;바빳던 개인 작업이 끝나 Docker 저장소를 밀어버리고&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;WSL2 내부에 Docker를 새로 세팅하려고 작업을 준비하는데&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1241&quot; data-origin-height=&quot;574&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IvhDG/btsIpMrFapm/2tFbYtFmsMojbTKXKt6r4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IvhDG/btsIpMrFapm/2tFbYtFmsMojbTKXKt6r4k/img.png&quot; data-alt=&quot;https://docs.docker.com/desktop/wsl/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IvhDG/btsIpMrFapm/2tFbYtFmsMojbTKXKt6r4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIvhDG%2FbtsIpMrFapm%2F2tFbYtFmsMojbTKXKt6r4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;370&quot; data-origin-width=&quot;1241&quot; data-origin-height=&quot;574&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://docs.docker.com/desktop/wsl/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1293&quot; data-origin-height=&quot;473&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zhlzg/btsIpfVrhC5/ZAuPShXvAi7PBCpEurFHrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zhlzg/btsIpfVrhC5/ZAuPShXvAi7PBCpEurFHrK/img.png&quot; data-alt=&quot;https://learn.microsoft.com/ko-kr/windows/wsl/tutorials/wsl-containers&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zhlzg/btsIpfVrhC5/ZAuPShXvAi7PBCpEurFHrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fzhlzg%2FbtsIpfVrhC5%2FZAuPShXvAi7PBCpEurFHrK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;293&quot; data-origin-width=&quot;1293&quot; data-origin-height=&quot;473&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://learn.microsoft.com/ko-kr/windows/wsl/tutorials/wsl-containers&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;최근 Guideline은 Docker Desktop을 통해 작업하도록 되어있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 방법은 대부분의 User에게 보다 편한 방법이기에 권장될만하다 본다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 나는 Docker Engine을 직접 설치해 사용하는것을 선호한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;WSL2 에 Docker Engine을 직접 설치하는 방법은 Docker 사이트 내에 설명되어 있다.&lt;/p&gt;
&lt;figure id=&quot;og_1720213491864&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Install Docker Engine on Ubuntu&quot; data-og-description=&quot;Jumpstart your client-side server applications with Docker Engine on Ubuntu. This guide details prerequisites and multiple methods to install Docker Engine on Ubuntu.&quot; data-og-host=&quot;docs.docker.com&quot; data-og-source-url=&quot;https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository&quot; data-og-url=&quot;https://docs.docker.com/engine/install/ubuntu/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bbXfbY/hyWvIapTB6/SzvkFgL69GRP2jRsVYh2ak/img.jpg?width=2400&amp;amp;height=1260&amp;amp;face=0_0_2400_1260&quot;&gt;&lt;a href=&quot;https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bbXfbY/hyWvIapTB6/SzvkFgL69GRP2jRsVYh2ak/img.jpg?width=2400&amp;amp;height=1260&amp;amp;face=0_0_2400_1260');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Install Docker Engine on Ubuntu&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Jumpstart your client-side server applications with Docker Engine on Ubuntu. This guide details prerequisites and multiple methods to install Docker Engine on Ubuntu.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.docker.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;가능하면 최신방법을 공유하기 위해 굳이 블로그에 중복 기술하지는 않겠다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Ubuntu 기준 curl을 통해 설치하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해당 사이트에 WSL2를 명시하고 있지는 않으나,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;커뮤니티에서 해당 방법을 사용하여서 문제가 없다고 &lt;a href=&quot;https://forums.docker.com/t/running-docker-without-docker-desktop/134922&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;증언&lt;/a&gt;하고 있으며,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;내 의견도 커뮤니티 의견과 같다.&lt;/p&gt;</description>
      <category>Operating System/WSL</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/195</guid>
      <comments>https://cypsw.tistory.com/entry/Docker-Desktop-%EC%97%86%EC%9D%B4-WSL2%EC%97%90-Docker-%EC%84%A4%EC%B9%98#entry195comment</comments>
      <pubDate>Sat, 6 Jul 2024 06:02:51 +0900</pubDate>
    </item>
    <item>
      <title>[C++] 백준 17142 문제 해설</title>
      <link>https://cypsw.tistory.com/entry/C-%EB%B0%B1%EC%A4%80-17142-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EC%84%A4</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/17142&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;해당 문제&lt;/a&gt;는 골드 3 티어이지만, 나는 동의하지 않는다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;골드 2티어에서 골드 1티어까지 부여할만한 문제라고 생각한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;문제 자체를 이해하는 과정이 직관적이지 않기에&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;다른 골드 3 티어 문제보다 난이도가 높다고 생각한다.&lt;/p&gt;
&lt;pre id=&quot;code_1719535167555&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;algorithm&amp;gt;

class baekjoon_17142
{
public:
	int N, M;
	int blank_count{};
	std::vector&amp;lt;std::pair&amp;lt;int, int&amp;gt;&amp;gt; loc_virus; // 바이러스의 위치를 기억할 벡터
	std::vector&amp;lt;std::vector&amp;lt;int&amp;gt;&amp;gt; content;
	int directions[4][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}}; // 동서남북
	const int MAX_INT = 2147483647;

	// 모든 가능한 조합을 저장할 이중 벡터
	std::vector&amp;lt;std::vector&amp;lt;std::pair&amp;lt;int, int&amp;gt;&amp;gt;&amp;gt; combinations;

	// 조합을 생성하는 함수
	void make_combination(int n)
	{
		std::vector&amp;lt;bool&amp;gt; selector(loc_virus.size() - n, false); // loc_virus.size() - n 만큼 false 로 초기화
		selector.resize(loc_virus.size(), true);	// 이후에 selector 를 loc_virus.size() 까지 resize 한 뒤, false 설정되지 않은부분을 true 로 설정.

		do {
			std::vector&amp;lt;std::pair&amp;lt;int, int&amp;gt;&amp;gt; combination; // 임시 조합 변수
			for (size_t i = 0; i &amp;lt; loc_virus.size(); ++i)
			{
				if (selector[i]) // selector[i] 에서 true 로 지정된 변수만
				{
					combination.push_back(loc_virus[i]); // combination 임시변수 할당.
				}
			}
			combinations.push_back(combination); // 최종 저장 변수에 push_back()
		} while (std::next_permutation(selector.begin(), selector.end()));
	}

	// bfs 를 통해서 각 combination 들이 몇 time을 소비하는지 체크해서 반환한다.
	int bfs(std::vector&amp;lt;std::pair&amp;lt;int, int&amp;gt;&amp;gt;&amp;amp; combination)
	{
		std::vector&amp;lt;std::vector&amp;lt;int&amp;gt;&amp;gt; timer(N, std::vector&amp;lt;int&amp;gt;(N, -1)); // 방문 정보와 time 담고있는 vector
		std::queue&amp;lt;std::pair&amp;lt;int, int&amp;gt;&amp;gt; q;	// BFS를 수행하기 위한 queue.
		int remaining_blanks = blank_count;	// 남아있는 빈공간 정보를 체크하기 위한 변수.

		for (auto&amp;amp; i : combination)	// 최초 시작지점을 queue 에 삽입.
		{
			q.push(i);
			timer[i.first][i.second] = 0; // 근원지라는 의미로 0로 시작.
		}

		int time = 0;

		while (!q.empty())
		{
			int cx = q.front().first;
			int cy = q.front().second;
			q.pop();

			for (int i = 0; i &amp;lt; 4; ++i) // 동, 서, 남, 북 진행용.
			{
				int nx = cx + directions[i][0];
				int ny = cy + directions[i][1];

				// 만약 nx, ny가 적절한 범위 내에 존재하면서, 아직 방문하지 않았다면 진입.
				if (nx &amp;gt;= 0 &amp;amp;&amp;amp; ny &amp;gt;= 0 &amp;amp;&amp;amp; nx &amp;lt; N &amp;amp;&amp;amp; ny &amp;lt; N &amp;amp;&amp;amp; timer[nx][ny] == -1)
				{
					// content[nx][ny] 가 0 라면
					if (content[nx][ny] == 0)
					{
						--remaining_blanks;
						timer[nx][ny] = ++timer[cx][cy]; // visited[nx][ny]에 visited[cx][cy] 이후의 값 추가.
						q.push({nx, ny});	// bfs 를 계속 진행하기 위해 queue 에 push().
						time = timer[nx][ny];	// timer[nx][ny] 는 현재 timer 수준과 같음.
					}
					else if (content[nx][ny] == 2) // 2일때 remaining_blanks 는 그대로 두고 queue 에 추가만 하는 형식으로 설정.
					{
						timer[nx][ny] = ++timer[cx][cy];
						q.push({nx, ny});
					}
				}
			}
		}

		return remaining_blanks == 0 ? time : -1;
	}

	void run()
	{
		// N : 연구소 크기
		// M : 활성상태로 변경가능한 바이러스의 수
		std::cin &amp;gt;&amp;gt; N &amp;gt;&amp;gt; M;
		content.resize(N, std::vector&amp;lt;int&amp;gt;(N));

		// 0 : 빈칸
		// 1 : 벽
		// 2 : 비활성 바이러스
		for (int i = 0; i &amp;lt; N; ++i)
		{
			for (int j = 0; j &amp;lt; N; ++j)
			{
				std::cin &amp;gt;&amp;gt; content[i][j];

				if (content[i][j] == 0)
				{
					++blank_count;
				}

				// 추가적인 검색을 막기 위해 virus 위치를 저장해 둔다.
				if (content[i][j] == 2)
				{
					loc_virus.push_back(std::pair&amp;lt;int, int&amp;gt;(i, j));
				}
			}
		}

		// 1초라는 시간에 따라 한칸씩 전진할 수 있으며
		// 연구소를 장악할 수 있는 최소시간을 출력해야 함.
		// 만약 연구소 장악이 불가능한 구조인 경우 -1을 출력해야 함.

		// 이 때 비활성 바이러스는 무시해도 되는듯 함.
		// 기본적으로 BFS 를 통해 진행하되, 무차별대입 방법을 사용해야 할듯 함.

		// make_combination 을 통해 가능한 조합을 생성 -&amp;gt; combinations 변수에 할당.
		make_combination(M);
		int count = MAX_INT;

		// 추후 모든 combinations 중 가장 작은 count 값을 가지는 것을 count 변수에 할당함.
		for (int i = 0; i &amp;lt; combinations.size(); ++i)
		{
			int temp = bfs(combinations[i]);

			if (temp &amp;lt; count &amp;amp;&amp;amp; temp != -1)
			{
				count = temp;
			}
		}

		count = count == MAX_INT ? -1 : count;

		// 최종적으로 count 변수를 출력함.
		std::cout &amp;lt;&amp;lt; count &amp;lt;&amp;lt; std::endl;
	}
};

int main()
{
	baekjoon_17142 bj;
    bj.run();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;문제를 풀기 위해선 BFS, Combination&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(조합)&lt;/span&gt; 알고리즘을 적용하여야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Python 과 같은 언어들에서는 기본 라이브러리에서 조합을 지원하지만, C++ 에서는 지원하지 않는다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 STL 에서 지원해주는 순열 알고리즘을 토대로 조합 알고리즘을 구현하였고,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이를 토대로 모든 조합 경우의 수를 계산한 뒤 가장 적은 시간을 소모하는 바이러스 M 개를 선정하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;75&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CXmNc/btsIfXe0TUV/lMJsxYYRmVNG0KSsu7Qda1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CXmNc/btsIfXe0TUV/lMJsxYYRmVNG0KSsu7Qda1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CXmNc/btsIfXe0TUV/lMJsxYYRmVNG0KSsu7Qda1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCXmNc%2FbtsIfXe0TUV%2FlMJsxYYRmVNG0KSsu7Qda1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;51&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;75&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Algorithm/BACKJOON</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/194</guid>
      <comments>https://cypsw.tistory.com/entry/C-%EB%B0%B1%EC%A4%80-17142-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EC%84%A4#entry194comment</comments>
      <pubDate>Fri, 28 Jun 2024 09:38:10 +0900</pubDate>
    </item>
    <item>
      <title>[C++] 백준 14890 문제 해설</title>
      <link>https://cypsw.tistory.com/entry/C-%EB%B0%B1%EC%A4%80-14890-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EC%84%A4</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14890&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;해당 문제&lt;/a&gt;는 삼성 SW 역량 테스트 에서 출제된 문제로&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;골드 3 티어의 적절한 난이도를 지니고 있는 문제이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nive3/btsH4LUAT9f/mfAQqw6P1DpHwYJxVVjNP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nive3/btsH4LUAT9f/mfAQqw6P1DpHwYJxVVjNP0/img.png&quot; data-alt=&quot;경사로 설치 가능&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nive3/btsH4LUAT9f/mfAQqw6P1DpHwYJxVVjNP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnive3%2FbtsH4LUAT9f%2FmfAQqw6P1DpHwYJxVVjNP0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;124&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;경사로 설치 가능&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;197&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zW8Bs/btsH5NqjKd6/QzK8NEP1nHCKc0LhsAzklk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zW8Bs/btsH5NqjKd6/QzK8NEP1nHCKc0LhsAzklk/img.png&quot; data-alt=&quot;경사로 설치 불가능&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zW8Bs/btsH5NqjKd6/QzK8NEP1nHCKc0LhsAzklk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzW8Bs%2FbtsH5NqjKd6%2FQzK8NEP1nHCKc0LhsAzklk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;123&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;197&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;경사로 설치 불가능&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;2차원 벡터를 기준으로 각 행, 열이&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;경사로를 설치하여 '지나갈 수 있는 길인지' 구하는 문제이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1718834807849&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;cstdlib&amp;gt;

class baekjoon_14890
{
public:
    int N, L;
    
    bool constraint(const std::vector&amp;lt;int&amp;gt;&amp;amp; line)
    {
        int value_before = line[0];
        int limitPoint = 0;

        for (int i = 1; i &amp;lt; line.size(); ++i)
        {
            // diff 는 이전값과 현재값의 차이를 지님.
            int diff = value_before - line[i];

            // 만약 차이가 없다면 검증할것이 없음. continue.
            if (diff == 0)
                continue;

            // 이전값과 현재값과의 차이가 2 이상일 경우 false
            if (abs(diff) &amp;gt;= 2)
                return false;

            // 현재값이 이전 값보다 1 작을 경우.
            if(diff == 1)
            { 
                // 경사로가 지정된 범위 내에 존재하는지 확인.
                if(i + L &amp;gt; line.size())
                    return false;

                // 경사로 limitPoint를 지정함.
                if(i + L * 2 &amp;gt; line.size())
                    limitPoint = static_cast&amp;lt;int&amp;gt;(line.size());
                else
                    limitPoint = i + L * 2;

                // 경사로 point가 line과 같거나 크면 false, 겹치는것임.
                for (int j = i; j &amp;lt; limitPoint; ++j)
                {
                    if(line[j] &amp;gt; line[i])
                        return false;
                }

                // 경사로가 여유 공간을 확보하고 있는지 확인.
                for (int j = i; j &amp;lt; i + L; ++j)
                {
                    if(line[j] &amp;lt; line[i])
                        return false;
                }
            }
            // 현재값이 이전 값보다 1 클 경우.
            else if(diff == -1)
            {
                // 경사로가 지정된 범위 내에 존재하는지 확인.
                if(i - L &amp;lt; 0)
                    return false;

                // 경사로가 여유 공간을 확보하고 있는지 확인.
                for (int j = i-1; j &amp;gt;= i - L; --j)
                {
                    if (line[j] != line[i] - 1)
                        return false;
                }
            }
        
            value_before = line[i];
        }
        return true;
    }

    void run()
    {
        std::cin &amp;gt;&amp;gt; N &amp;gt;&amp;gt; L;
        std::vector&amp;lt;std::vector&amp;lt;int&amp;gt;&amp;gt; content(N, std::vector&amp;lt;int&amp;gt;(N));

        for (int i = 0; i &amp;lt; N; ++i)
        {
            for (int j = 0; j &amp;lt; N; ++j)
            {
                std::cin &amp;gt;&amp;gt; content[i][j];
            }
        }

        int count = 0;

        for (int i = 0; i &amp;lt; N; ++i)
        {
            // 행을 확인
            if (constraint(content[i]))
                count++;

            // 임시 열벡터 생성
            std::vector&amp;lt;int&amp;gt; col(N);
            for (int j = 0; j &amp;lt; N; ++j)
            {
                col[j] = content[j][i];
            }

            // 열을 확인
            if (constraint(col))
            {
                count++;
            }
        }

        std::cout &amp;lt;&amp;lt; count &amp;lt;&amp;lt; std::endl;
    }
};&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1137&quot; data-origin-height=&quot;112&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bm6zqr/btsH5eWgCkj/6iTRsfr3hUV0jrHHQ6H0j1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bm6zqr/btsH5eWgCkj/6iTRsfr3hUV0jrHHQ6H0j1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bm6zqr/btsH5eWgCkj/6iTRsfr3hUV0jrHHQ6H0j1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbm6zqr%2FbtsH5eWgCkj%2F6iTRsfr3hUV0jrHHQ6H0j1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;79&quot; data-origin-width=&quot;1137&quot; data-origin-height=&quot;112&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Algorithm/BACKJOON</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/193</guid>
      <comments>https://cypsw.tistory.com/entry/C-%EB%B0%B1%EC%A4%80-14890-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EC%84%A4#entry193comment</comments>
      <pubDate>Thu, 20 Jun 2024 07:10:16 +0900</pubDate>
    </item>
    <item>
      <title>Surface Pro 8 서멀 그리스 재도포</title>
      <link>https://cypsw.tistory.com/entry/Surface-Pro-8-%EC%84%9C%EB%A9%80-%EA%B7%B8%EB%A6%AC%EC%8A%A4-%EC%9E%AC%EB%8F%84%ED%8F%AC</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;저는 Microsoft 의 Surface 제품군들을 참 좋아합니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;특히 그 중 Surface Pro 8 을 구입해서 2년여 정도 잘 사용하고 있었는데,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;최근 들어 발열로 인한 쓰로틀링이 매우 심하게 느껴졌습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;CPU 클럭이 0.58Ghz 정도까지 다운되는데, 간단한 워드 작업이나,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;웹서핑 등을 할 때도 간헐적으로 발생해서 짜증이 나는 수준입니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;고작 저런 작업을 하는데 CPU 온도가 78도 까지 상승해 버리니;;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아무리 11세대 Intel CPU 가 발열이 심하다고 하지만, 구입 당시에는 이정도가 아니였습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 이놈의 서피스에 서멀 그리스 재도포를 하기로 결심 했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1638&quot; data-origin-height=&quot;978&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chRDOp/btsH1C942Ge/bBFKxofjvyf4St17aQRo2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chRDOp/btsH1C942Ge/bBFKxofjvyf4St17aQRo2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chRDOp/btsH1C942Ge/bBFKxofjvyf4St17aQRo2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchRDOp%2FbtsH1C942Ge%2FbBFKxofjvyf4St17aQRo2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;478&quot; data-origin-width=&quot;1638&quot; data-origin-height=&quot;978&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;서피스와 같은 액정 테블릿을 분해할 때 가장 난이도가 높은 작업은 바로 액정을 분해하는 일입니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;보통 분해시 액정을 깨먹는일이 잦습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20240617_083500.jpg&quot; data-origin-width=&quot;1775&quot; data-origin-height=&quot;1331&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ozlWk/btsH0jKFdB2/gMN8gcjaJb251BsD6k7wg1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ozlWk/btsH0jKFdB2/gMN8gcjaJb251BsD6k7wg1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ozlWk/btsH0jKFdB2/gMN8gcjaJb251BsD6k7wg1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FozlWk%2FbtsH0jKFdB2%2FgMN8gcjaJb251BsD6k7wg1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;600&quot; data-filename=&quot;20240617_083500.jpg&quot; data-origin-width=&quot;1775&quot; data-origin-height=&quot;1331&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;적절한 압력을 토대로 디스플레이의 변형 한도 내에서 진행해야 하는데&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이게 감각적인 부분이라 마땅한 가이드라인이 없습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그나마 최근 MS 측에서는 &lt;a href=&quot;https://www.youtube.com/watch?v=ajDU3SW0XUo&amp;amp;t=361s&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;가이드라인 영상&lt;/a&gt;을 내놓긴 했는데 영상속 도구가 없는 이상 큰 도움은 안됩니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;만약 액정을 깨먹으면 MS 공식 서비스 센터에서 수리가 불가할거고.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;설사 된다고 해도 리퍼처리여서 &lt;a href=&quot;https://support.microsoft.com/en-au/topic/how-much-does-out-of-warranty-service-cost-for-your-surface-device-or-accessory-south-korea-fbba5f65-4470-440e-917c-9cacaa326778&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;엄청난&lt;/a&gt;&amp;nbsp;비용이 지출됩니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;자가수리 하려고 해도&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;AliExpress 의 Surface Pro 8 디스플레이 비용, 20만원 정도가 지출됩니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 수리에 자신이 있지 않다면, 사설수리를 권장 드립니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20240617_045128.jpg&quot; data-origin-width=&quot;1317&quot; data-origin-height=&quot;1756&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EQZBs/btsH0CC6apM/6naFj4agaiGSag1mI7OBN0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EQZBs/btsH0CC6apM/6naFj4agaiGSag1mI7OBN0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EQZBs/btsH0CC6apM/6naFj4agaiGSag1mI7OBN0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEQZBs%2FbtsH0CC6apM%2F6naFj4agaiGSag1mI7OBN0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;1067&quot; data-filename=&quot;20240617_045128.jpg&quot; data-origin-width=&quot;1317&quot; data-origin-height=&quot;1756&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;저는 몇몇 영상을 참고해서 처음에는 커터칼날로 진입각을 째고,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이후에는 숫돌로 날카롭게 갈아낸 플라스틱 유심칩 카드를 통해&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;디스플레이와 본체를 결합한 테이프를 분해 하였습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이때 열풍기가 있다면 좋겠지만, 없어서 드라이어기로 테이프를 살짝 녹여 작업 하였습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;참고로 열풍기나, 드라이어기를 사용할 때 매우높은 온도가 아니여도 됩니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;제 경험상 60도 내외 정도면 충분히 분해할 정도가 됩니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20240617_084014.jpg&quot; data-origin-width=&quot;1755&quot; data-origin-height=&quot;1316&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ex275/btsH0XUxYRj/74DXSPYzzhRdyDu6dVHKX0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ex275/btsH0XUxYRj/74DXSPYzzhRdyDu6dVHKX0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ex275/btsH0XUxYRj/74DXSPYzzhRdyDu6dVHKX0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEx275%2FbtsH0XUxYRj%2F74DXSPYzzhRdyDu6dVHKX0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;600&quot; data-filename=&quot;20240617_084014.jpg&quot; data-origin-width=&quot;1755&quot; data-origin-height=&quot;1316&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;나사는 별나사로 구성되어 있습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;서멀은 역시 꽤 굳은 상태군요.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;여담으로 Surface Pro 시리즈는 Micron 사의 DRAM을 사용 하는군요.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20240617_084515.jpg&quot; data-origin-width=&quot;1671&quot; data-origin-height=&quot;1253&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bo7Ynn/btsH0Ph1JJ9/LZRXFk79biPWR4rnTn1zlK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bo7Ynn/btsH0Ph1JJ9/LZRXFk79biPWR4rnTn1zlK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bo7Ynn/btsH0Ph1JJ9/LZRXFk79biPWR4rnTn1zlK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbo7Ynn%2FbtsH0Ph1JJ9%2FLZRXFk79biPWR4rnTn1zlK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;600&quot; data-filename=&quot;20240617_084515.jpg&quot; data-origin-width=&quot;1671&quot; data-origin-height=&quot;1253&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;기판과 연결된 부분은 마른 휴지나 헝겊으로 닦아주고,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20240617_084826.jpg&quot; data-origin-width=&quot;1511&quot; data-origin-height=&quot;2015&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNTcQ6/btsH02IbLdX/gqYciRDM8pUdlMVvbrFDE0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNTcQ6/btsH02IbLdX/gqYciRDM8pUdlMVvbrFDE0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNTcQ6/btsH02IbLdX/gqYciRDM8pUdlMVvbrFDE0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNTcQ6%2FbtsH02IbLdX%2FgqYciRDM8pUdlMVvbrFDE0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;1067&quot; data-filename=&quot;20240617_084826.jpg&quot; data-origin-width=&quot;1511&quot; data-origin-height=&quot;2015&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;히트파이프에 묻은 서멀은 대충 물티슈로 닦았습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20240617_084924.jpg&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;1877&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1JTBv/btsH1jCSfwx/obhk0esHv4E9UYEx2H7KH0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1JTBv/btsH1jCSfwx/obhk0esHv4E9UYEx2H7KH0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1JTBv/btsH1jCSfwx/obhk0esHv4E9UYEx2H7KH0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1JTBv%2FbtsH1jCSfwx%2Fobhk0esHv4E9UYEx2H7KH0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;1066&quot; data-filename=&quot;20240617_084924.jpg&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;1877&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;서멀은 최근 국내 회사에서 출시한, 저렴하면서도 끝판왕의 성능을 보여주는&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;SGT-4 서멀로 작업 했습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;싼 가격에 덜컥 20g 짜리를 사 봤는데... 3년내에 다 못 쓸듯 한데 뭐 열심히 써야죠;;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해당 서멀은 열전도 성능은 검증 되었어도&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아직 '유지력' 부분에 있어서 검증된 제품은 아니기에 걱정은 됩니다만,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;애초에 서피스를 서멀작업하려고 뜯어제끼는 변태이니&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;문제생기면 또 뜯으면 되겠죠 뭐&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20240617_085127.jpg&quot; data-origin-width=&quot;1480&quot; data-origin-height=&quot;1973&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sULMz/btsH0NdosHT/62NCpkhDBghKLB27Emr5B1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sULMz/btsH0NdosHT/62NCpkhDBghKLB27Emr5B1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sULMz/btsH0NdosHT/62NCpkhDBghKLB27Emr5B1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsULMz%2FbtsH0NdosHT%2F62NCpkhDBghKLB27Emr5B1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;1066&quot; data-filename=&quot;20240617_085127.jpg&quot; data-origin-width=&quot;1480&quot; data-origin-height=&quot;1973&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;퀘존, 쿨앤 등 HW 커뮤니티에서 전달받은 대로 생각보다 MX-4 서멀보다는 점도가 상당히 높습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;예쁘게 펴 바르려고 했는데 힘드네요, 그냥 적당히 펴 발라 줬습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20240617_090324.jpg&quot; data-origin-width=&quot;1813&quot; data-origin-height=&quot;1359&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C7E3A/btsH1CWxLOZ/v6L3a6ja4PCP0S2LULqQf0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C7E3A/btsH1CWxLOZ/v6L3a6ja4PCP0S2LULqQf0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C7E3A/btsH1CWxLOZ/v6L3a6ja4PCP0S2LULqQf0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC7E3A%2FbtsH1CWxLOZ%2Fv6L3a6ja4PCP0S2LULqQf0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;600&quot; data-filename=&quot;20240617_090324.jpg&quot; data-origin-width=&quot;1813&quot; data-origin-height=&quot;1359&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;히트파이프와 쿨러를 재결합 하였습니다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(둘은 연결된 구조입니다.)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;쿨러와 메인보드는 필름형? 결합구조로 되어있는데, 이게 굉장히 잘 빠지는 구조로 되어 있습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;만약 빠지셧다면 당황하지 마시고 원위치에 그냥 밀어 넣어주시면 됩니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;추가로 위 사진에서 재미있는 점을 볼 수 있는데, 히트파이프와 디스플레이가 닿으며,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;열이 디스플레이로 전도되는것을 막기 위해 단열제들이 히트파이프에 붙어있는 모습을 볼 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;마무리로&amp;nbsp;디스플레이와 본체간의 결합은&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;AliExpress 에서 구입한 전자기기용 양면 테이프로 적당히 떼웠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1047&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kGx9m/btsH0PoJVjC/ufUuLi7c4ee39G6OplujGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kGx9m/btsH0PoJVjC/ufUuLi7c4ee39G6OplujGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kGx9m/btsH0PoJVjC/ufUuLi7c4ee39G6OplujGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkGx9m%2FbtsH0PoJVjC%2FufUuLi7c4ee39G6OplujGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;453&quot; data-origin-width=&quot;1047&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;대-충 이런 놈들인데 제가 산건 접착력이 그닥 신통치 않아서&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;전공책급 책 6권을 위에 올려두고 6시간 정도 기다렸습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;주의해야 할 점은, 원래 서피스가 방수, 방진을 지원하는 제품은 아니지만,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;위와 같은 테이프로 마감하게 되면 출고시 테이프보다 보호력이 떨어지게 됩니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 이전보다 더 액체류에 주의를 기울여 주셔야 합니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2880&quot; data-origin-height=&quot;1776&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VsudD/btsHZ41oEpD/XfDhjgCn6YQBcGvWEyvakK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VsudD/btsHZ41oEpD/XfDhjgCn6YQBcGvWEyvakK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VsudD/btsHZ41oEpD/XfDhjgCn6YQBcGvWEyvakK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVsudD%2FbtsHZ41oEpD%2FXfDhjgCn6YQBcGvWEyvakK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;493&quot; data-origin-width=&quot;2880&quot; data-origin-height=&quot;1776&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;작업 후 테스트를 해 보니 노트북 특성상 피크온도가 여전히 78도 수준까지 튀긴 하지만,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;팬이 도는순간 온도가 훨씬 빠르게 낮아지는 모습을 보여줍니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 평균온도는 훨씬 낮은 온도를 유지합니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;전원모드 '권장' 기준&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이전에는 4k 유튜브 + 워드작업시 60도 초반 ~ 70도 초반의 평균 온도를 보여주었는데&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;서멀 재도포 후 동일한 작업 진행시 50도 초반 ~ 60도 초반의 온도를 보여주고 있습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;클럭도 Boost 클럭까지 잘 터져주네요.&lt;/p&gt;</description>
      <category>Miscellaneous/Hardware</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/192</guid>
      <comments>https://cypsw.tistory.com/entry/Surface-Pro-8-%EC%84%9C%EB%A9%80-%EA%B7%B8%EB%A6%AC%EC%8A%A4-%EC%9E%AC%EB%8F%84%ED%8F%AC#entry192comment</comments>
      <pubDate>Mon, 17 Jun 2024 11:49:40 +0900</pubDate>
    </item>
    <item>
      <title>[C++] 백준 1012 문제 해설</title>
      <link>https://cypsw.tistory.com/entry/C-%EB%B0%B1%EC%A4%80-1012-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EC%84%A4</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1012&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;해당 문제&lt;/a&gt;는 BFS, DFS 를 통해 해결할 수 있는 문제이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;난이도는 실버 2 티어이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;연습하기 좋은 문제라고 느껴 BFS, DFS 두가지 유형으로 모두 풀어보았다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;소스코드에 적절한 주석을 작성해 두었으므로, 보면서 이해하면 좋다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;BFS&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1718494196502&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;cstring&amp;gt;

class baekjoon_1012_bfs
{
public:
    static const int MAX = 50;
    int field[MAX][MAX];
    bool visited[MAX][MAX];
    int directions[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // 서, 동, 남, 북 
    int M, N, K;

    // 핵심은 bfs를 통해서 visited를 기록하는것.
    // 이를 통해 wormcount를 통제할 수 있음.
    void bfs(int x, int y) 
    {
        std::queue&amp;lt;std::pair&amp;lt;int, int&amp;gt;&amp;gt; q;
        q.push({x, y});
        visited[x][y] = true;

        while (!q.empty()) 
        {
            x = q.front().first; 
            y = q.front().second;
            q.pop();

            // 서, 동, 남, 북 반복.
            for (int i = 0; i &amp;lt; 4; ++i) 
            {
                int nx = x + directions[i][0];
                int ny = y + directions[i][1];

                if (nx &amp;gt;= 0 &amp;amp;&amp;amp; nx &amp;lt; M &amp;amp;&amp;amp; ny &amp;gt;= 0 &amp;amp;&amp;amp; ny &amp;lt; N &amp;amp;&amp;amp;  // nx, ny 가 지정한 범위 내에 존재하며
                    !visited[nx][ny] &amp;amp;&amp;amp; field[nx][ny] == 1) // 해당 위치가 visited 가 아니며, 동시에 배추가 존재한다면
                {
                    visited[nx][ny] = true;	// visited로 변경후
                    q.push({nx, ny});	// 계속 반복을 위해 queue 에 삽입.
                }
            }
        }
    }

    void run()
    {
        int T;
        std::cin &amp;gt;&amp;gt; T;

        // T 만큼 반복
        while (T--) 
        {
            // 배열 M x N 과 배추개수 K
            std::cin &amp;gt;&amp;gt; M &amp;gt;&amp;gt; N &amp;gt;&amp;gt; K;

            // 반복시 field, visited를 초기화.
            memset(field, 0, sizeof(field));
            memset(visited, 0, sizeof(visited));

            // field 값을 K 만큼 입력받음. field에는 배추 존재 유무가 저장.
            for (int i = 0; i &amp;lt; K; ++i) 
            {
                int x, y;
                std::cin &amp;gt;&amp;gt; x &amp;gt;&amp;gt; y;
                field[x][y] = 1;
            }

            int wormCount = 0;

            for (int i = 0; i &amp;lt; M; ++i) 
            {
                for (int j = 0; j &amp;lt; N; ++j) 
                {
                    // 만약 배추가 존재하며, 방문하지 않았다면 BFS 진입후 wormCount 증가.
                    if (field[i][j] &amp;amp;&amp;amp; !visited[i][j]) 
                    {
                        bfs(i, j);
                        ++wormCount;
                    }
                }
            }

            std::cout &amp;lt;&amp;lt; wormCount &amp;lt;&amp;lt; std::endl;
        }
    }
};

int main()
{
	baekjoon_1012_bfs bfs;
    bfs.run();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;DFS&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1718494306281&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;cstring&amp;gt;

class baekjoon_1012_dfs
{
public:
    static const int MAX = 50;
    int field[MAX][MAX];
    bool visited[MAX][MAX];
    int directions[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // 서, 동, 남, 북
    int M, N, K;

    // 핵심은 dfs 를 통해서 visited를 기록하는것.
    // 이미 dfs를 진입할 때, visited, field를 체크하기에 별도 체크 X.
    void dfs(int x, int y)
    {
        visited[x][y] = true;

        // 서, 동, 남, 북 반복
        for(int i = 0; i &amp;lt; 4; ++i)
        {
            int nx = x + directions[i][0];
            int ny = y + directions[i][1];

            if(nx &amp;gt;= 0 &amp;amp;&amp;amp; nx &amp;lt; M &amp;amp;&amp;amp; ny &amp;gt;= 0 &amp;amp;&amp;amp; ny &amp;lt; N &amp;amp;&amp;amp;  // nx, ny 가 지정한 범위 내에 존재하며
                !visited[nx][ny] &amp;amp;&amp;amp; field[nx][ny]) // 해당 위치가 visited 가 아니며, 동시에 배추가 존재한다면
            {
                dfs(nx, ny); // dfs 를 진입 -&amp;gt; 진입한 즉시 해당 영역의 visited 를 true 로 수정.
            }
        }
    }

    void run()
    {
        int T;
        std::cin &amp;gt;&amp;gt; T;

        // T 만큼 반복
        while(T--)
        {
            // 배열 M x N 과 배추개수 K
            std::cin &amp;gt;&amp;gt; M &amp;gt;&amp;gt; N &amp;gt;&amp;gt; K;

            // 반복시 field, visited를 초기화.
            memset(field, 0, sizeof(field));
            memset(visited, 0, sizeof(visited));

            // field 값을 K 만큼 입력받음. field에는 배추 존재 유무가 저장.
            for(int i = 0; i &amp;lt; K; ++i)
            {
                int x, y;
                std::cin &amp;gt;&amp;gt; x &amp;gt;&amp;gt; y;
                field[x][y] = 1;
            }

            int wormCount = 0;

            for(int i = 0; i &amp;lt; M; ++i)
            {
                for(int j = 0; j &amp;lt; N; ++j)
                {
                    // 만약 배추가 존재하며, 방문하지 않았다면 DFS 진입후 wormCount 증가.
                    if(field[i][j] &amp;amp;&amp;amp; !visited[i][j])
                    {
                        dfs(i, j);
                        ++wormCount;
                    }
                }
            }
            
            std::cout &amp;lt;&amp;lt; wormCount &amp;lt;&amp;lt; std::endl;
        }
    }
};

int main()
{
	baekjoon_1012_dfs dfs;
    dfs.run();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해당 문제에서 BFS 와 DFS 는 queue 를 이용하느냐, 재귀를 이용하느냐의 차이만 존재한다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이는 본질적으로 해당 문제가 연결된 모든 노드를 찾아 그룹화 하기만 하면 되기 때문이다.&lt;/p&gt;</description>
      <category>Algorithm/BACKJOON</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/191</guid>
      <comments>https://cypsw.tistory.com/entry/C-%EB%B0%B1%EC%A4%80-1012-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EC%84%A4#entry191comment</comments>
      <pubDate>Sun, 16 Jun 2024 08:35:48 +0900</pubDate>
    </item>
    <item>
      <title>[리뷰] QWEN TECHNICAL REPORT</title>
      <link>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-QWEN-TECHNICAL-REPORT</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/pdf/2309.16609&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;해당 논문&lt;/a&gt;은 Alibaba Group 내 Alibaba Cloud 가 구축한 Open LLM 인 Qwen 의 기술 리포트 이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이 모델에 관심을 가지게 된 계기는 몇몇 중국 기업, 특히 알리바바에 관심이 있어서가 첫째이고,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;최근 나온 Qwen 2.0 의 성능이 GPT 4 에 근접한 성능지표를 보여주었기 때문이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;실제로 모델을 사용 해 보았을 때 한국어 기준 LLaMA3 보다 더 우수하다고 느꼇다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;더 과감하게 발언하자면,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;24년 6월 기준 모든 Open LLM 기준, Qwen 2.0 의 성능이 가장 우수하다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;모든 LLM 으로 범위를 넓히면, Qwen 2.0 보다 더 우수한 성능을 보유하다고 느낀 모델은 GPT-4o 가 유일하다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;참고로 해당 논문은 Qwen 2.0 모델에 관해 설명하는것이 아닌,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;시초가 된 Qwen 1 모델에 관해 설명하고 있으며&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;설계적인 관점에서 상세하게 설명하고 있지는 않다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;논문 자체도 비교적 쉽게 작성되어 있기에, 한번 직접 읽어보는걸 추천한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해당 리뷰는 가볍게 훑고 요약하는 느낌으로 작성 하였다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 소개&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1370&quot; data-origin-height=&quot;585&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xQvTX/btsHXuMjDJn/vPwMJ04w3rTtoukCZLKP2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xQvTX/btsHXuMjDJn/vPwMJ04w3rTtoukCZLKP2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xQvTX/btsHXuMjDJn/vPwMJ04w3rTtoukCZLKP2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxQvTX%2FbtsHXuMjDJn%2FvPwMJ04w3rTtoukCZLKP2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;342&quot; data-origin-width=&quot;1370&quot; data-origin-height=&quot;585&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Qwen : 수조 개의 토큰이 포함된 대규모 데이터세트로 Pre-Trained 한 모델&lt;/li&gt;
&lt;li&gt;Qwen-Chat : Qwen을&amp;nbsp;기반으로&amp;nbsp;SFT&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Supervised&amp;nbsp;Fine-Tuning)&lt;/span&gt;하여&amp;nbsp;제작된&amp;nbsp;모델&lt;/li&gt;
&lt;li&gt;Qwen-RLHF&amp;nbsp;:&amp;nbsp;Qwen을&amp;nbsp;기반으로&amp;nbsp;RLHF&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Reinforcement&amp;nbsp;Learning&amp;nbsp;from&amp;nbsp;Human&amp;nbsp;Feedback)&lt;/span&gt;하여&amp;nbsp;제작된&amp;nbsp;모델&lt;/li&gt;
&lt;li&gt;Qwen-Code : 코딩관련 데이터를 추가하여 개발된 모델&lt;/li&gt;
&lt;li&gt;Math-Qwen-Chat : 수학관련 데이터를 추가하여 SFT된 모델&lt;/li&gt;
&lt;li&gt;Qwen-VL : multimodal LLM 으로서 학습된 모델&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;여러가지로 요약해서 모델을 설명하고 있다. 전반적으로 GPT-4 대비해서는 성능이 뒤쳐진다는 것을 논문 저자들도 인정하고 있으며, Math-Qwen-Chat 모델의 성능은 GPT-3.5 수준이라고 밝혔다. Qwen-VL, Qwen-VL-Chat 은 당시의 오픈소스 비전 언어 모델보다 성능이 뛰어나다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 사전학습(Pre-Trained)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 기존 연구에서 데이터의 양은 강력한 LLM을 개발하는데에 매우 중요한 요소임이 입증되었다. 따라서 효과적인 사전학습 데이터셋을 구축하기 위해서, 데이터가 다양하고 광범위하게 존재하는지 확인해야 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;1169&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xIknH/btsHXm8Nnq7/4vVdczg04bQ9FPuOyAueKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xIknH/btsHXm8Nnq7/4vVdczg04bQ9FPuOyAueKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xIknH/btsHXm8Nnq7/4vVdczg04bQ9FPuOyAueKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxIknH%2FbtsHXm8Nnq7%2F4vVdczg04bQ9FPuOyAueKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;720&quot; height=&quot;701&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;1169&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위는 Qwen-14B 와 GPT 4, 3.5 간의 성능평가를 진행한 결과이다. 14B 모델인 점을 감안해도 성능적으로 꽤나 떨어지는 모습을 보여진다. 이러한 Qwen 을 학습하는데에 있어 저자들은 데이터세트를 공개된 웹 문서, 백과사전, 책, 코드 등을 중국어와 영어 데이터 위주로 수집하였으며, 수집된 데이터를 여러 전처리 절차를 거쳐 처리하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;698&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/euTRbx/btsHYND3Wk1/cVjbcLVCtKNoq2AVXFrdkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/euTRbx/btsHYND3Wk1/cVjbcLVCtKNoq2AVXFrdkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/euTRbx/btsHYND3Wk1/cVjbcLVCtKNoq2AVXFrdkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeuTRbx%2FbtsHYND3Wk1%2FcVjbcLVCtKNoq2AVXFrdkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;340&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;698&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 인코딩 압축률에 있어서 타 모델대비 큰 개선을 이루었다고 한다. 참고로&amp;nbsp;인코딩 압축률 개선은 GPT 역시 GPT4o 에 와서 큰 개선을 이뤘기에, 이러한 Qwen 의 능력은 현재 기준으로 그다지 '특출난' 수준은 아닐것으로 추측된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더하여 Qwen 의 구조에 관해 설명하고 있다. Qwen은 Transformer 구조를 수정해서 설계되었으며, 특히 LLaMA 를 훈련하는 접근 방식을 채택하였다고 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1438&quot; data-origin-height=&quot;235&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blunLS/btsHZseYEuE/F4cUiQWapbZb4pER2ktgD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blunLS/btsHZseYEuE/F4cUiQWapbZb4pER2ktgD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blunLS/btsHZseYEuE/F4cUiQWapbZb4pER2ktgD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblunLS%2FbtsHZseYEuE%2FF4cUiQWapbZb4pER2ktgD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;131&quot; data-origin-width=&quot;1438&quot; data-origin-height=&quot;235&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Qwen 1 모델은 최대 14B 규모로 학습되었다. 여러 Hyper-Parameters를 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1645&quot; data-origin-height=&quot;1184&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vuuL2/btsHYXGqC0d/vdgcQsaPBqOexlr8ajrux1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vuuL2/btsHYXGqC0d/vdgcQsaPBqOexlr8ajrux1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vuuL2/btsHYXGqC0d/vdgcQsaPBqOexlr8ajrux1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvuuL2%2FbtsHYXGqC0d%2FvdgcQsaPBqOexlr8ajrux1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;576&quot; data-origin-width=&quot;1645&quot; data-origin-height=&quot;1184&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OPEN LLM 기준 비슷한 파라미터를 보유한 Open LLM 기준 성능은 Qwen 1 이 가장 우수하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 정렬(Alignment)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더하여 최초 사전학습된 LLM 은 인간의 행동과 정렬(aligned) 되지 않기에 대부분의 경우 AI 비서 역할을 하기에 부적합하다. 논문 작성 다시 연구에 따르면 SFT 나 RLHF 의 강화 학습과 같은 정렬 기술을 사용하면 언어 모델이 자연스러운 대화에 참여할 수 있는 능력을 크게 상승시킬 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3.1 &amp;nbsp;Supervised Fine-Tuning&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 단계는 SFT를 수행하여 인간의 행동을 이해하고 질의와 응답을 포함한 채팅 스타일의 데이터에 대해 사전 훈련된 LLM을 미세 조정하는 것이다. 이는 대화에 주석을 다는 방식으로 달성되었으며 폭력, 편견, 포르노 등과 같은 안전 문제와 관련된 데이터에도 주석을 달아 모델의 안전성을 우선시하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3.2&amp;nbsp; Reinforcement Learning From Human Feedback&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더하여 SFT가 효과적인 것으로 입증되었지만, SFT의 일반화 및 창의성 능력이 제한적일 수 있고 과적합되기 쉽다. 이 문제를 해결하기 위해 SFT 모델을 인간 선호도와 더욱 일치시키기 위해 RLHF을 구현했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대규모 언어 모델(LLM) 구축과 같은 성공적인 보상 모델을 만들기 위해서는 먼저 Pre-Trained를 거친 다음 미세 조정을 수행하는 것이 중요하다. 이러한 유형의 비교 데이터에 대해서도 미세 조정이 수행되지만 품질 주석이 있기 때문에 더 높은 품질로 수행된다. &lt;br /&gt;&lt;br /&gt;미세&amp;nbsp;조정&amp;nbsp;단계에서는&amp;nbsp;다양한&amp;nbsp;프롬프트를&amp;nbsp;수집하고&amp;nbsp;QWEN&amp;nbsp;모델의&amp;nbsp;응답에&amp;nbsp;대한&amp;nbsp;사람의&amp;nbsp;피드백을&amp;nbsp;기반으로&amp;nbsp;보상&amp;nbsp;모델을&amp;nbsp;조정한다.&amp;nbsp;사용자&amp;nbsp;프롬프트의&amp;nbsp;다양성과&amp;nbsp;복잡성을&amp;nbsp;적절하게&amp;nbsp;고려하기&amp;nbsp;위해&amp;nbsp;약&amp;nbsp;6600개의&amp;nbsp;세부&amp;nbsp;태그로&amp;nbsp;분류&amp;nbsp;시스템을&amp;nbsp;만들고&amp;nbsp;보상&amp;nbsp;모델의&amp;nbsp;주석&amp;nbsp;요청을&amp;nbsp;선택할&amp;nbsp;때&amp;nbsp;다양성과&amp;nbsp;복잡성을&amp;nbsp;모두&amp;nbsp;고려하는&amp;nbsp;균형&amp;nbsp;잡힌&amp;nbsp;샘플링&amp;nbsp;알고리즘을&amp;nbsp;구현했다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1556&quot; data-origin-height=&quot;1045&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diVqQv/btsHXDJftmp/LaKbcE7qPmSgRgJ8JaZ7A1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diVqQv/btsHXDJftmp/LaKbcE7qPmSgRgJ8JaZ7A1/img.png&quot; data-alt=&quot;그림 4: 채팅 모델에 대한 인간 평가 결과입니다. 우리는 Qwen-7B(SFT), Qwen14B(SFT), Qwen-14B(RLHF), 그리고 GPT-4를 GPT-3.5와 비교하였습니다. 각 막대 그래프 세그먼트는 아래에서 부터 승리, 무승부, 패배의 백분율을 나타냅니다. 평균적으로, RLHF 모델이 SFT 모델보다 우수한 성능을 보였습니다. 데이터셋은 300개의 중국어 지시사항들로 구성되어 있습니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diVqQv/btsHXDJftmp/LaKbcE7qPmSgRgJ8JaZ7A1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdiVqQv%2FbtsHXDJftmp%2FLaKbcE7qPmSgRgJ8JaZ7A1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;537&quot; data-origin-width=&quot;1556&quot; data-origin-height=&quot;1045&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 4: 채팅 모델에 대한 인간 평가 결과입니다. 우리는 Qwen-7B(SFT), Qwen14B(SFT), Qwen-14B(RLHF), 그리고 GPT-4를 GPT-3.5와 비교하였습니다. 각 막대 그래프 세그먼트는 아래에서 부터 승리, 무승부, 패배의 백분율을 나타냅니다. 평균적으로, RLHF 모델이 SFT 모델보다 우수한 성능을 보였습니다. 데이터셋은 300개의 중국어 지시사항들로 구성되어 있습니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇게 완성된 채팅 모델에 대한 인간 평과 결과 그래프이다. GPT 3.5 와 각 모델들을 비교하였으며, 지시사항은 중국어로 입력되었다. 평균적을 QWEN 1 은 GPT 3.5 급 으로 보는것이 타당할듯 하다. GPT 4 보다는 확실히 열세라는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 마치며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문 내부에서는 데이터 처리 과정에 대해서 보다 상세히 설명되어 있으며, 요약해서 리뷰한 내용들도 풀어 설명되어 있다. 관심있다면 논문을 직접 보는것을 추천한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무엇보다 놀라운것은 이렇게 시작된 Qwen 1 &amp;rarr; Qwen 1.5 &amp;rarr; Qwen 2 의 성능변화인데, Qwen 2 에 와서는 LLaMA 3 를 확실히 이기는 성능지표를 보여주고 있고, 실제로 내 감상도 동일하다. GPT 4 에 비해서는 미세하게 열세로 보이나, Open LLM 기준해서는 가장 우수한 성능을 보여주는것이 Qwen 2 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접 사용하고 싶다면 Hugging-face 에서 Demo Site 를 운용중이므로 &lt;a href=&quot;https://huggingface.co/spaces/Qwen/Qwen2-72B-Instruct&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;직접 체험&lt;/a&gt;해 보길 바란다. 다만 이 모델의 단점이라면 아무래도 중국 기업, 알리바바에서 학습된 모델이라 시진핑과 관련된 정보를 묻는다면 에러를 뿜는다&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(.....)&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Artificial Intelligence/Paper Review</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/190</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-QWEN-TECHNICAL-REPORT#entry190comment</comments>
      <pubDate>Fri, 14 Jun 2024 03:49:48 +0900</pubDate>
    </item>
    <item>
      <title>[C++] 백준 1343 문제 해설</title>
      <link>https://cypsw.tistory.com/entry/C-%EB%B0%B1%EC%A4%80-1343</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1343&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;백준 1343 문제&lt;/a&gt;는 실버 5티어 정도의 문제로 그다지 어려운 문제는 아니다.&lt;/p&gt;
&lt;pre id=&quot;code_1717915016891&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

class baekjoon_1343
{
public:
    int run()
    {
        std::string input;
        std::cin &amp;gt;&amp;gt; input;

        std::string result;
        int count = 0;

        for (char ch : input)
        {
            if (ch == 'X')
            {
                ++count;
            }
            else if (ch == '.')
            {
                // 짝수가 아닐경우 폴리오미노 제작 불가, 종료.
                if (count % 2 != 0)
                {
                    std::cout &amp;lt;&amp;lt; &quot;-1&quot;;
                    return -1;
                }

                append_polynomials(result, count);
                result += '.';
                count = 0;
            }
        }

        // 위에서는 '.' 을 트리거로 했는데, 마지막에 'XXX' 가 나올수도 있으므로, 루프 종료시 한번 더 걸러봄.
        if (count % 2 != 0)
        {
            std::cout &amp;lt;&amp;lt; &quot;-1&quot;;
            return -1;
        }
        append_polynomials(result, count);

        std::cout &amp;lt;&amp;lt; result;
        return 0;
    }


private:
    // '.' 을 맞닥뜨리거나, loop 종료시 AAAA, BB 를 출력함.
	void append_polynomials(std::string&amp;amp; result, int count)
	{
		int a = count / 4;
		int b = (count % 4) / 2;

        // A 우선이며
		for (int i = 0; i &amp;lt; a; ++i)
		{
			result.append(&quot;AAAA&quot;);
		}

        // B 는 A출력 후 짜투리만
		for (int i = 0; i &amp;lt; b; ++i)
		{
			result.append(&quot;BB&quot;);
		}
	}
};


int main()
{
    baekjoon_1343 bj;
    bj.run();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1382&quot; data-origin-height=&quot;107&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpKNvj/btsHRmuqDPI/YWImFneCqxzJnRe4OIJBNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpKNvj/btsHRmuqDPI/YWImFneCqxzJnRe4OIJBNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpKNvj/btsHRmuqDPI/YWImFneCqxzJnRe4OIJBNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpKNvj%2FbtsHRmuqDPI%2FYWImFneCqxzJnRe4OIJBNk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;62&quot; data-origin-width=&quot;1382&quot; data-origin-height=&quot;107&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Algorithm/BACKJOON</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/189</guid>
      <comments>https://cypsw.tistory.com/entry/C-%EB%B0%B1%EC%A4%80-1343#entry189comment</comments>
      <pubDate>Sun, 9 Jun 2024 10:35:15 +0900</pubDate>
    </item>
    <item>
      <title>Transformer 의 CrossAttention 차이점</title>
      <link>https://cypsw.tistory.com/entry/Transformer-%EC%9D%98-CrossAttention</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/pdf/1706.03762.pdf?&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Attention Is All You Need&lt;/a&gt; 는 Transformer 기술을 소개하는 논문으로서, &lt;a href=&quot;https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-Attention-Is-All-You-Need&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전에 한차례 리뷰&lt;/a&gt;한 바가 있다.&lt;br /&gt;이 중 CrossAttention 에 대한 한국어 포스팅이 많지 않아보여 작성해본다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;910&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JOV0J/btsGO9ozalW/7pUyhlmP35dJ0Fszx1Ft4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JOV0J/btsGO9ozalW/7pUyhlmP35dJ0Fszx1Ft4k/img.png&quot; data-alt=&quot;Figure 1: The Transformer - model architecture.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JOV0J/btsGO9ozalW/7pUyhlmP35dJ0Fszx1Ft4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJOV0J%2FbtsGO9ozalW%2F7pUyhlmP35dJ0Fszx1Ft4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;741&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;910&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 1: The Transformer - model architecture.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Transformer 는 Translation, VC, STT, TTS등 시계열 데이터를 처리하는데에 있어 사용할 수 있다. 즉 Decoder 의 출력은 Text 가 될수도 있고, Mel Spectrogram 형태가 될수도 있으며, 아마 '영상' 쪽으로도 출력을 내는게 가능할 것이다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(여기서는 번역을 기준으로 작성하겠다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;붉은박스로 표시한 CrossAttention 은 좌측의 Encoder 단에서 나오는 출력이, 우측의 Decoder 단으로 들어가는 구조이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 코드를 살펴보자. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;428&quot; data-origin-height=&quot;341&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LpuUo/btsGPQWDgLy/VfIvPKqTLkrPJkynzTQLKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LpuUo/btsGPQWDgLy/VfIvPKqTLkrPJkynzTQLKk/img.png&quot; data-alt=&quot;Cross Attention&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LpuUo/btsGPQWDgLy/VfIvPKqTLkrPJkynzTQLKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLpuUo%2FbtsGPQWDgLy%2FVfIvPKqTLkrPJkynzTQLKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;428&quot; height=&quot;341&quot; data-origin-width=&quot;428&quot; data-origin-height=&quot;341&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Cross Attention&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;Source&amp;nbsp;Code&amp;nbsp;-&amp;nbsp;CrossAttentionLayer &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1718084066853&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class CrossAttention(BaseAttention):
  def call(self, x, context):
    attn_output, attn_scores = self.mha(
        query=x,
        key=context,
        value=context,
        return_attention_scores=True)

    # Cache the attention scores for plotting later.
    self.last_attn_scores = attn_scores

    x = self.add([x, attn_output])
    x = self.layernorm(x)

    return x&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CrossAttention 코드에서 Query 는 Decoder 단의 이전 Layer 로 부터 들어오며, Key 와 Value 는 Encoder 단에서 들어오는 형태이다. &lt;span style=&quot;color: #f89009;&quot;&gt;Key, Value 는 context 라는 같은 변수값을 할당한다는 것&lt;/span&gt;을 알 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;428&quot; data-origin-height=&quot;341&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mc6F3/btsGOfitXyh/c5Sfcko9FQUK6hdanCmd31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mc6F3/btsGOfitXyh/c5Sfcko9FQUK6hdanCmd31/img.png&quot; data-alt=&quot;Global Self-Attention&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mc6F3/btsGOfitXyh/c5Sfcko9FQUK6hdanCmd31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmc6F3%2FbtsGOfitXyh%2Fc5Sfcko9FQUK6hdanCmd31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;428&quot; height=&quot;341&quot; data-origin-width=&quot;428&quot; data-origin-height=&quot;341&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Global Self-Attention&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;Source Code - GlobalSelfAttentionLayer&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1718084090327&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class GlobalSelfAttention(BaseAttention):
  def call(self, x):
    attn_output = self.mha(
        query=x,
        value=x,
        key=x)
    x = self.add([x, attn_output])
    x = self.layernorm(x)
    return x&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 SelfAttention 의 경우 Query, Key, Value 에 모두 같은값을 사용한다는 것을 알 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;CrossAttention 에 값이 어떻게 들어가는지 살펴보면 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/elLels/btsGNP5pYAG/kKsrZ4CofSftu8KepMHkf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/elLels/btsGNP5pYAG/kKsrZ4CofSftu8KepMHkf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/elLels/btsGNP5pYAG/kKsrZ4CofSftu8KepMHkf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FelLels%2FbtsGNP5pYAG%2FkKsrZ4CofSftu8KepMHkf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;794&quot; height=&quot;425&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;SelfAttention 에서는 Query $=$ Key $=$ Value 이지만.&lt;br /&gt;Cross Attention 에서는 Query $\neq$ Key, Value 이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Query - Decoder 의 이전 Layer 에서 전달되며, 현재 번역작업을 어디까지 진행하였는지 데이터를 가지고 있음.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(current context)&lt;/span&gt; target 언어의 토큰값이 들어가게 됨.&lt;/li&gt;
&lt;li&gt;Key - Encoder 에서 Indexing 된 토큰들.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Source 언어의 값을 지님)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Value - Encoder 에서 Indexing 된 토큰들. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Source 언어의 값을 지님)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1030&quot; data-origin-height=&quot;656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rumge/btsGQY08eW6/9KsbTxzPHypQvIkCvYFne1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rumge/btsGQY08eW6/9KsbTxzPHypQvIkCvYFne1/img.png&quot; data-alt=&quot;https://drive.google.com/file/d/1OsDrxOqARZd7R2FRpL0x3GZjFskpEtHU/view?pli=1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rumge/btsGQY08eW6/9KsbTxzPHypQvIkCvYFne1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frumge%2FbtsGQY08eW6%2F9KsbTxzPHypQvIkCvYFne1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;510&quot; data-origin-width=&quot;1030&quot; data-origin-height=&quot;656&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://drive.google.com/file/d/1OsDrxOqARZd7R2FRpL0x3GZjFskpEtHU/view?pli=1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 먼저 Key 와 Value 를 곱함으로서 &lt;span style=&quot;color: #f89009;&quot;&gt;Source 언어에서 단어들간 어떤 관계가 있는지 찾은 뒤&lt;/span&gt;, 해당 결과를 다시 Query 값과 곱한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(이 때 Query 값에는 Target 언어 Token 값이 존재.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정을 통해 &lt;span style=&quot;color: #f89009;&quot;&gt;Target 언어에 해당되는 Token 과 Source 언어에 해당되는 Token 의 연관성을 찾고&lt;/span&gt;, &lt;br /&gt;다음에 올 단어를 예측해서 최종적인 번역 결과를 출력하는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;358&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xMtxf/btsGPqw3ifP/BZhkH8j24yWU1facPKo9HK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xMtxf/btsGPqw3ifP/BZhkH8j24yWU1facPKo9HK/img.png&quot; data-alt=&quot;https://vaclavkosar.com/ml/cross-attention-in-transformer-architecture&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xMtxf/btsGPqw3ifP/BZhkH8j24yWU1facPKo9HK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxMtxf%2FbtsGPqw3ifP%2FBZhkH8j24yWU1facPKo9HK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;716&quot; height=&quot;358&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;358&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://vaclavkosar.com/ml/cross-attention-in-transformer-architecture&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 SelfAttention 과 CrossAttention 은 Input 을 제외하면 차이가 나지 않는다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(동일한 계산 방법)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 Input, 목적에서 차이가 있으며 SelfAttention 은 번역작업 기준 Source 언어의 토큰별 관계를 파악하기 위해 진행한다면, CrossAttention 은 Target 언어와 Source 언어의 Token 간 관계를 파악하기 위해 사용된다.&lt;/p&gt;</description>
      <category>Artificial Intelligence/Fundamentals</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/188</guid>
      <comments>https://cypsw.tistory.com/entry/Transformer-%EC%9D%98-CrossAttention#entry188comment</comments>
      <pubDate>Tue, 23 Apr 2024 08:27:17 +0900</pubDate>
    </item>
    <item>
      <title>Filen 후기</title>
      <link>https://cypsw.tistory.com/entry/Filen-%ED%9B%84%EA%B8%B0</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://filen.io/r/ca32447310fe904e798e1967d5c85c0f&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Filen&lt;/a&gt; 은 독일에서 운용하는 Cloud Storage 서비스로, 몇몇 장단점을 가지고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;642&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/T7Wds/btsGIMmglGm/F1dwduPCzlfax7gKJwL8L1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/T7Wds/btsGIMmglGm/F1dwduPCzlfax7gKJwL8L1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/T7Wds/btsGIMmglGm/F1dwduPCzlfax7gKJwL8L1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FT7Wds%2FbtsGIMmglGm%2FF1dwduPCzlfax7gKJwL8L1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;268&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;642&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 보안&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 Cloud Storage 서비스 제공사들은, 수사기관의 요청에 따라 데이터를 제공해야 할 의무가 있다. &lt;br /&gt;예로 사용자가 아래와 같은 파일을 가지고 있다고 의심되는 경우이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;아동포르노&lt;/li&gt;
&lt;li&gt;마약거래&lt;/li&gt;
&lt;li&gt;스너프필름&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 저런 파일을 공유하는 사용자들을 검거하는건 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 문제는 저런 파일들을 검열하기 위해 &lt;span style=&quot;color: #f89009;&quot;&gt;정상적인 유저들의 파일을 살펴볼 수 있다는 &lt;/span&gt;점이다. &lt;br /&gt;가족사진, 내가 짠 소스코드, 백업용 보안키 등등을 Cloud 측에서 확인할 수 있다는것은 사용자 입장에서 매우 찜찜하다. 이는 내가 아는 거의 모든 Cloud 의 운영 방침이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대표적으로 OneDrive, Google Drive 도 마찬가지이며 MEGA, My Box 등도 전부 유저의 파일을 수사기관 요청에 따라 제공할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;628&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9vNyc/btsGJMFPjOI/a8WTRgPDvwLyoLsLqohDuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9vNyc/btsGJMFPjOI/a8WTRgPDvwLyoLsLqohDuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9vNyc/btsGJMFPjOI/a8WTRgPDvwLyoLsLqohDuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9vNyc%2FbtsGJMFPjOI%2Fa8WTRgPDvwLyoLsLqohDuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;419&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;628&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 &lt;a href=&quot;https://filen.io/r/ca32447310fe904e798e1967d5c85c0f&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Filen&lt;/a&gt; 은 '유럽' 에서 서비스가 제공된다. 개인정보 보호라면 환장하는 유럽에서 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 Filen 은 내가 다른사람에게 '공유' 할 목적으로 공개 링크를 만든 파일이 아니라면, 원천적으로 나를 제외한 그 누구든 내 파일의 정보를 볼 수 없다. 수사기관, 정부, Filen 운영진조차 말이다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(물론 CIA가 출동할만한걸 지니고 있다면 논외이다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Filen 은 영지식 증명과 end-to-end 암호화 기반 하에 운영되는 서비스이며, 그 소재지가 '독일' 에 있기때문에 독일의 데이터보호법에 의하여 독일정부를 포함한 그 누구에게든 사용자의 어떤 데이터도 제공할 의무가 없다.&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1713389340905&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Zero-knowledge proof - Wikipedia&quot; data-og-description=&quot;From Wikipedia, the free encyclopedia Proving validity without revealing other data In cryptography, a zero-knowledge proof or zero-knowledge protocol is a method by which one party (the prover) can prove to another party (the verifier) that a given statem&quot; data-og-host=&quot;en.wikipedia.org&quot; data-og-source-url=&quot;https://en.wikipedia.org/wiki/Zero-knowledge_proof&quot; data-og-url=&quot;https://en.wikipedia.org/wiki/Zero-knowledge_proof&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Zero-knowledge_proof&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://en.wikipedia.org/wiki/Zero-knowledge_proof&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Zero-knowledge proof - Wikipedia&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;From Wikipedia, the free encyclopedia Proving validity without revealing other data In cryptography, a zero-knowledge proof or zero-knowledge protocol is a method by which one party (the prover) can prove to another party (the verifier) that a given statem&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;en.wikipedia.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2. 평생 요금제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연히 의구심을 느낄 수 밖에 없다. '평생요금제' 는 클라우드 운영 입장에서 결코 지속 가능한 운영 방식이 아니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;185&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpvs7N/btsGKbFnhb4/ds3pRUeeo6bYvmCsqO2KG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpvs7N/btsGKbFnhb4/ds3pRUeeo6bYvmCsqO2KG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpvs7N/btsGKbFnhb4/ds3pRUeeo6bYvmCsqO2KG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbpvs7N%2FbtsGKbFnhb4%2Fds3pRUeeo6bYvmCsqO2KG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;104&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;185&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연히 운영진들도 이는 지속가능한 운영 방법이 아니라고 고지하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 평생 요금제 플랜은 회사 운영 상황에 따라 열고 닫기를 반복하는 중이다. 현재는 plan 중 starter 만 열려있고, 이는 100GB 용량을 29.99&amp;euro; 에 제공중이다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(기존에는 무려 2TB 짜리 평생 요금제도 있었다.)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_edited_blob&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;874&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c3iRbL/btsGHFOChuh/hYAuCUIudrYIB9Zg2bNPb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c3iRbL/btsGHFOChuh/hYAuCUIudrYIB9Zg2bNPb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c3iRbL/btsGHFOChuh/hYAuCUIudrYIB9Zg2bNPb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc3iRbL%2FbtsGHFOChuh%2FhYAuCUIudrYIB9Zg2bNPb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;543&quot; data-filename=&quot;edited_edited_blob&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;874&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Filen&amp;nbsp; 사용할 생각이라면 평생 요금제를 추천한다. 다른건 가성비가 좀 떨어지는 편이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;823&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y4lLC/btsGIeJ2NB4/b4mniAJsFnMs9LRmHaSDt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y4lLC/btsGIeJ2NB4/b4mniAJsFnMs9LRmHaSDt0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y4lLC/btsGIeJ2NB4/b4mniAJsFnMs9LRmHaSDt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy4lLC%2FbtsGIeJ2NB4%2Fb4mniAJsFnMs9LRmHaSDt0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;658&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;823&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;금일 기준 유로화가 미쳐 날뛰고 있어서, 일반적인 정액 요금제로 비교하면 보통 Naver My Box 가 더 싼편이다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(물론 나는 첫글자로 '.' 가 허용되지 않기에 My Box 는 사용하지 않는다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평생 요금제 기준으로는 약 4만원이 좀 넘는 가격인데, 3년만 사용하더라도 충분히 이득이며 Filen은 2021년부터 운영된 회사로, 이미 3년이 넘었다. 스타트업 클라우드 서비스 치고는 어느정도 고비는 넘긴 셈이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3. 넉넉한 무료 사용량&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 현재 내가 아는 클라우드 서비스중 무료 사용량을 가장 많이 주는곳은 네이버의 My Box 이다. 아마 메일이나, 다른 서비스와 스토리지를 공유하는 방식이긴 하지만 30GB 나 되는 넉넉한 용량을 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Filen 도 기본적으로 아래 링크를 통해 가입하면 20GB의 용량을 준다.&lt;/p&gt;
&lt;figure id=&quot;og_1713390337410&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Filen &amp;ndash; Next Generation End-To-End Encrypted Cloud Storage&quot; data-og-description=&quot;Filen &amp;ndash; Next Generation End-To-End Encrypted Cloud Storage. Get started with 10 GB of free space.&quot; data-og-host=&quot;filen.io&quot; data-og-source-url=&quot;https://filen.io/r/ca32447310fe904e798e1967d5c85c0f&quot; data-og-url=&quot;https://filen.io/r/ca32447310fe904e798e1967d5c85c0f&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://filen.io/r/ca32447310fe904e798e1967d5c85c0f&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://filen.io/r/ca32447310fe904e798e1967d5c85c0f&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Filen &amp;ndash; Next Generation End-To-End Encrypted Cloud Storage&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Filen &amp;ndash; Next Generation End-To-End Encrypted Cloud Storage. Get started with 10 GB of free space.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;filen.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로, 다른사람을 초대링크를 통해 가입시킨다면 1인당 10GB 씩 최대 50GB 까지 용량을 늘릴 수 있다. 3명 초대라는 조건이 붙지만 50GB는 내가 아는 그 어떤 Cloud 에서도 제공하지 않는 압도적인 무료 용량이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 느린 Mounting 시스템&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과거 Filen 은 무조건적으로 로컬폴더에 파일/폴더 복사본을 위치시키고, 변경사항을 감지하여 Cloud에 업로드 하는 &lt;span style=&quot;color: #ee2323;&quot;&gt;'동기화'&lt;/span&gt; 방식으로만 운용되었었다. 때문에 작업속도는 매우 빠를지 몰라도 다른 Cloud들 처럼 Local 저장소의 용량을 아끼면서도 실시간적인 작업이 어려웠는데, 24년 11월 네트워크 드라이브 마운팅 시스템이 생겼다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1277&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vZ1LQ/btsK259hQVM/KSB0e8e3BWhygMilJgHUY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vZ1LQ/btsK259hQVM/KSB0e8e3BWhygMilJgHUY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vZ1LQ/btsK259hQVM/KSB0e8e3BWhygMilJgHUY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvZ1LQ%2FbtsK259hQVM%2FKSB0e8e3BWhygMilJgHUY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;532&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1277&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만, 해당 마운팅 시스템은 다른 클라우드 서비스들보다 좀... 많이 느리다.&lt;br /&gt;Electron 으로 제작된 앱과의 연동 문제인지&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(아마 이건 문제가 아닐것 같은데..)&lt;/span&gt;&lt;br /&gt;아직 플랫폼별 최적화가 덜 되어서 생기는 문제인지는 모르겠으나,&lt;br /&gt;일단 Windows 기준으로는 Caching을 활성화 시켜도 끔찍하게 느린 속도를 보여준다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 나는 사실상 여전히 이전과 같이 &lt;span style=&quot;color: #ee2323;&quot;&gt;'동기화'&lt;/span&gt; 옵션을 메인으로 사용하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;외에 소소한점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 클라우드가 제공해야될 것은 모두 제공한다. 특히 나는 클라우드에서 반드시 존재해야되는 기능이 '버전별 파일 기록 기능' 이라고 생각한다. 해당 기능이 있어야 랜섬웨어에 감염되어도 Cloud에 저장된 파일을 안전히 지킬 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Filen은 이 기능을 완벽히 지원한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;개인적인 추천&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무료용량을 많이줘서 좋고&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(50GB)&lt;/span&gt;, 속도도 준수한 편이다. Cloud 를 수백 GB, TB 단위로 업로드 시켜놓고 쓰는 스타일은 아니여서 하드한 테스트는 해 보지 않았지만, 수십 GB 수준에서 속도가 느리다는 느낌은 받아보지 못했다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(나는 Google Drive 대비 훨신 빠르다고 느꼈다.)&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1713390929608&quot; data-og-image=&quot;&quot; data-og-url=&quot;https://filen.io/r/ca32447310fe904e798e1967d5c85c0f&quot; data-og-source-url=&quot;https://filen.io/r/ca32447310fe904e798e1967d5c85c0f&quot; data-og-host=&quot;filen.io&quot; data-og-description=&quot;Filen &amp;ndash; Next Generation End-To-End Encrypted Cloud Storage. Get started with 10 GB of free space.&quot; data-og-title=&quot;Filen &amp;ndash; Next Generation End-To-End Encrypted Cloud Storage&quot; data-og-type=&quot;website&quot; data-ke-align=&quot;alignCenter&quot; data-ke-type=&quot;opengraph&quot;&gt;&lt;a href=&quot;https://filen.io/r/ca32447310fe904e798e1967d5c85c0f&quot; data-source-url=&quot;https://filen.io/r/ca32447310fe904e798e1967d5c85c0f&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('&amp;quot;&amp;quot;');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Filen &amp;ndash; Next Generation End-To-End Encrypted Cloud Storage&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Filen &amp;ndash; Next Generation End-To-End Encrypted Cloud Storage. Get started with 10 GB of free space.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;filen.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 OneDrive 를 사용하다가 여러 장점들이 마음에 들어 Filen 을 주력으로 사용하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한국인 사용자들도 꽤 있는지 앱까지 한국어로 완벽에 가깝게 번역되어 제공되고, 기본 정액요금이 비싸긴 하지만 평생 요금제를 지원하며, 추가로 타 클라우드들 대비 뚜렷한 장점들이 있기에, Cloud Storage 를 고민중이라면 한번쯤 사용해 보는걸 추천한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;끝&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Tools/Etc</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/187</guid>
      <comments>https://cypsw.tistory.com/entry/Filen-%ED%9B%84%EA%B8%B0#entry187comment</comments>
      <pubDate>Thu, 18 Apr 2024 07:03:01 +0900</pubDate>
    </item>
    <item>
      <title>행렬 기초</title>
      <link>https://cypsw.tistory.com/entry/%ED%96%89%EB%A0%AC-%EA%B8%B0%EC%B4%88</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-AdaLoRA-Adaptive-Budget-Allocation-for-Parameter-Efficient-Fine-Tuning&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 포스팅의 주제인 AdaLoRA&lt;/a&gt;&amp;nbsp;는 행렬에 대해 잘 알지 못하면 그 원리를 근본까지 이해하기 힘든 구성을 지니고 있다. 최종적으로 이해는 했지만 이를 정리해 두지 않으면 한달만 지나면 다 까먹을 것이기 때문에 기록해 둔다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&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;span style=&quot;color: #9d9d9d;&quot;&gt;(단위행렬)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;대각행렬&lt;/li&gt;
&lt;li&gt;직교행렬&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;및 행렬연산 특성에 관해서 설명한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 행렬(matrix)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&lt;br /&gt;\begin{equation} &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\begin{bmatrix}&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;a_{11}&amp;nbsp;&amp;amp;&amp;nbsp;a_{12}&amp;nbsp;&amp;amp;&amp;nbsp;a_{13}&amp;nbsp;&amp;nbsp;\\ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;a_{21}&amp;nbsp;&amp;amp;&amp;nbsp;a_{22}&amp;nbsp;&amp;amp;&amp;nbsp;a_{23}&amp;nbsp;&amp;nbsp;\\ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;a_{31}&amp;nbsp;&amp;amp;&amp;nbsp;a_{32}&amp;nbsp;&amp;amp;&amp;nbsp;a_{33}&amp;nbsp;&amp;nbsp;\\ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\end{bmatrix}&amp;nbsp; &lt;br /&gt;\end{equation}&lt;br /&gt;$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행렬에 관해서 모르는 사람은 없으리라 본다. Excel 을 다뤄본 경험이 있다면 행렬이란 개념을 추상적으로 잡아둔것과 다름없다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;벡터와 행렬의 차이에 관해 모르고 있었다면, 아래 글을 살펴보라.&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1713272848376&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Can anyone please explain the the difference between a vector and a matrix?&quot; data-og-description=&quot;I just took Calculus 3 last semester at my University and got comfortable with the idea of vectors, vector-valued functions, and basic vector operations like the dot and cross products. This semes...&quot; data-og-host=&quot;math.stackexchange.com&quot; data-og-source-url=&quot;https://math.stackexchange.com/questions/1536855/can-anyone-please-explain-the-the-difference-between-a-vector-and-a-matrix&quot; data-og-url=&quot;https://math.stackexchange.com/questions/1536855/can-anyone-please-explain-the-the-difference-between-a-vector-and-a-matrix&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/uakmK/hyVPKN06b4/17xtKKfq4MRuvKvQGUgYvK/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://math.stackexchange.com/questions/1536855/can-anyone-please-explain-the-the-difference-between-a-vector-and-a-matrix&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://math.stackexchange.com/questions/1536855/can-anyone-please-explain-the-the-difference-between-a-vector-and-a-matrix&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/uakmK/hyVPKN06b4/17xtKKfq4MRuvKvQGUgYvK/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Can anyone please explain the the difference between a vector and a matrix?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I just took Calculus 3 last semester at my University and got comfortable with the idea of vectors, vector-valued functions, and basic vector operations like the dot and cross products. This semes...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;math.stackexchange.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1-1. 행렬의 덧셈, 뺄셈&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;행렬의 덧셈과 뺄셈은 따로 설명이 필요하지 않을 정도로 간단하다. &lt;br /&gt;같은 크기를 지닌 행렬끼리만 덧셈, 뺄셈 연산이 가능하다.&lt;/p&gt;
&lt;pre id=&quot;code_1713337577759&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import numpy as np

matrix_a = np.array([[1,2,3],
                   [4,5,6],
                   [7,8,9]])

matrix_b = np.array([[9,8,7],
                   [6,5,4],
                   [3,2,1]])


print(matrix_a + matrix_b)
print(matrix_a - matrix_b)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&lt;br /&gt;A+B = &lt;br /&gt;\begin{equation}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\begin{bmatrix}&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;10 &amp;amp; 10 &amp;amp; 10&amp;nbsp; \\&lt;br /&gt;&amp;nbsp; &amp;nbsp;10 &amp;amp; 10 &amp;amp; 10&amp;nbsp; \\&lt;br /&gt;&amp;nbsp; &amp;nbsp;10 &amp;amp; 10 &amp;amp; 10&amp;nbsp; \\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\end{bmatrix}&amp;nbsp;&lt;br /&gt;\end{equation} &lt;br /&gt;$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&lt;br /&gt;A-B =&amp;nbsp;&lt;br /&gt;\begin{equation} &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\begin{bmatrix}&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;-8 &amp;amp; -6 &amp;amp; -4&amp;nbsp; \\&lt;br /&gt;&amp;nbsp; &amp;nbsp;-2 &amp;amp; 0 &amp;amp; 2&amp;nbsp; \\&lt;br /&gt;&amp;nbsp; &amp;nbsp;4 &amp;amp; 6 &amp;amp; 8&amp;nbsp; \\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\end{bmatrix}&amp;nbsp; &lt;br /&gt;\end{equation}&lt;br /&gt;$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1-2. 행렬의 곱셈&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행렬곱 역시 특정 조건을 갖춘 행렬간에만 수행할 수 있다.&lt;br /&gt;예로, 두 행렬 $A, B$가 각각 $m \times n, n \times r$일 때 진행할 수 있다.&lt;br /&gt;앞쪽에 위치하는 행렬 $A$의 열의 수와, 뒤쪽에 위치하는 행렬 $B$의 행의 수가 같아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행렬끼리 곱셈 연산을 수행하면 행렬의 크기는 $m \times r$이 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1713338260412&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import numpy as np

matrix_a = np.array([[80,90,60],
                   [75,80,90],
                   [90,95,65],
                   [99,70,70]])

matrix_b = np.array([[3,1],
                   [3,8],
                   [4,1]])


print(np.dot(matrix_a, matrix_b))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예로, 위와 같은 코드가 있다면 아래와 같이 계산된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ &lt;br /&gt;AB&amp;nbsp;=&amp;nbsp; &lt;br /&gt;\begin{equation} &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\begin{bmatrix}&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;80&amp;nbsp;\cdot&amp;nbsp;3&amp;nbsp;+&amp;nbsp;90&amp;nbsp;\cdot&amp;nbsp;3&amp;nbsp;+&amp;nbsp;60&amp;nbsp;\cdot&amp;nbsp;4&amp;nbsp;&amp;amp;&amp;nbsp;80&amp;nbsp;\cdot&amp;nbsp;1&amp;nbsp;+&amp;nbsp;90&amp;nbsp;\cdot&amp;nbsp;8&amp;nbsp;+&amp;nbsp;60&amp;nbsp;\cdot&amp;nbsp;8&amp;nbsp;\\ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;75&amp;nbsp;\cdot&amp;nbsp;3&amp;nbsp;+&amp;nbsp;80&amp;nbsp;\cdot&amp;nbsp;3&amp;nbsp;+&amp;nbsp;90&amp;nbsp;\cdot&amp;nbsp;4&amp;nbsp;&amp;amp;&amp;nbsp;75&amp;nbsp;\cdot&amp;nbsp;1&amp;nbsp;+&amp;nbsp;80&amp;nbsp;\cdot&amp;nbsp;8&amp;nbsp;+&amp;nbsp;90&amp;nbsp;\cdot&amp;nbsp;8&amp;nbsp;\\ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;90&amp;nbsp;\cdot&amp;nbsp;3&amp;nbsp;+&amp;nbsp;95&amp;nbsp;\cdot&amp;nbsp;3&amp;nbsp;+&amp;nbsp;65&amp;nbsp;\cdot&amp;nbsp;4&amp;nbsp;&amp;amp;&amp;nbsp;90&amp;nbsp;\cdot&amp;nbsp;1&amp;nbsp;+&amp;nbsp;95&amp;nbsp;\cdot&amp;nbsp;8&amp;nbsp;+&amp;nbsp;65&amp;nbsp;\cdot&amp;nbsp;8&amp;nbsp;\\ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;99&amp;nbsp;\cdot&amp;nbsp;3&amp;nbsp;+&amp;nbsp;70&amp;nbsp;\cdot&amp;nbsp;3&amp;nbsp;+&amp;nbsp;70&amp;nbsp;\cdot&amp;nbsp;4&amp;nbsp;&amp;amp;&amp;nbsp;99&amp;nbsp;\cdot&amp;nbsp;1&amp;nbsp;+&amp;nbsp;70&amp;nbsp;\cdot&amp;nbsp;8&amp;nbsp;+&amp;nbsp;70&amp;nbsp;\cdot&amp;nbsp;8&amp;nbsp;\\ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\end{bmatrix}&amp;nbsp; &lt;br /&gt;= &lt;br /&gt;\begin{bmatrix} &lt;br /&gt;750&amp;nbsp;&amp;amp;&amp;nbsp;860&amp;nbsp;\\ &lt;br /&gt;825&amp;nbsp;&amp;amp;&amp;nbsp;805&amp;nbsp;\\ &lt;br /&gt;815&amp;nbsp;&amp;amp;&amp;nbsp;915&amp;nbsp;\\ &lt;br /&gt;787&amp;nbsp;&amp;amp;&amp;nbsp;729&amp;nbsp;\\ &lt;br /&gt;\end{bmatrix}&amp;nbsp; &lt;br /&gt;\end{equation} &lt;br /&gt;$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몇번 보다보면 계산법을 쉽게 찾을 수 있다. 앞 행렬에 해당하는 $A$의 행과, 뒷 행렬에 해당하는 $B$의 열과 곱하면 된다. 이 때 행, 열의 요소가 여러개일 때에는 각 곱 계산을 더한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 행렬곱에서 교환법칙은 대부분 성립하지 않는다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(특수한 경우 성립하나, 일반적으로 성립 X)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ AB \neq BA $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 역행렬(inverse matrix)&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역행렬&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(inverse matrix)&lt;/span&gt; 는 행렬 $A$가 있다고 할 때 $A^{-1}$로 표기되며, 아래가 성립된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ A^{-1}A = AA^{-1} = I $$&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;여기서 $I$는 '단위 행렬(unit matrix)' 혹은 '항등 행렬(identity matrix)' 이라고 불리며, &lt;a href=&quot;https://cypsw.tistory.com/entry/%ED%96%89%EB%A0%AC-%EA%B8%B0%EC%B4%88#5.%20%ED%95%AD%EB%93%B1%ED%96%89%EB%A0%AC(unit%20matrix)-1&quot;&gt;아래에서&lt;/a&gt; 설명하겠다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역행렬은 항등행렬을 구하기 위해 사용된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 전치행렬(transposed matrix)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행렬 $A$의 전치행렬을 표기할 때 $A^T$ 혹은 $A^\top$ 으로 표기된다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(나는 $A^\top$표기를 선호한다.)&lt;br /&gt;&lt;/span&gt;전치행렬은 행렬내의 원소를 대각선축을 기준으로 서로 위치를 바꾼것을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, $A$가 $m \times n$ 이라면 $A^{\top}$은 $n \times m$ 이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1&quot; data-origin-height=&quot;1&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/F46p2/btsGHusKnFJ/MDtwTBUIuhDoMzhi5WANb0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/F46p2/btsGHusKnFJ/MDtwTBUIuhDoMzhi5WANb0/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/F46p2/btsGHusKnFJ/MDtwTBUIuhDoMzhi5WANb0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/F46p2/btsGHusKnFJ/MDtwTBUIuhDoMzhi5WANb0/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1&quot; height=&quot;1&quot; data-origin-width=&quot;1&quot; data-origin-height=&quot;1&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전치행렬은 아래 특성이 성립된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$A^{\top\top} = A$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 대칭행렬(symmetric matrix)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행렬 $A$가 아래 조건을 만족한다면 대칭행렬 이라고 지칭한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ A = A^T $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 $ A_{ij} = A_{ji} $ 역시 성립한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 아래의 성질도 보유하고 있다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;($n$차 정사각행렬 이라면)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ \text{대칭행렬} = A A^\top = A^\top A $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예로, 아래는 대칭행렬이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&lt;br /&gt;\begin{equation}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\begin{bmatrix}&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;1 &amp;amp; 2 &amp;amp; 4&amp;nbsp; \\&lt;br /&gt;&amp;nbsp; &amp;nbsp;2 &amp;amp; 3 &amp;amp; 5&amp;nbsp; \\&lt;br /&gt;&amp;nbsp; &amp;nbsp;4 &amp;amp; 5 &amp;amp; 6&amp;nbsp; \\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\end{bmatrix}&amp;nbsp;&lt;br /&gt;\end{equation}&lt;br /&gt;$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1, 3, 6 이 위치한 대각선축을 따라 전치해도 같은 행렬이 된다는 것을 알 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 항등행렬(unit matrix)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;항등행렬&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(단위행렬)&lt;/span&gt; 은 &lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%A3%BC%EB%8C%80%EA%B0%81%EC%84%A0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;주대각선&lt;/a&gt;의 원소가 모두 1이며, 나머지 원소는 모두 0인 정사각 행렬을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&lt;br /&gt;\begin{equation}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\begin{bmatrix}&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;1 &amp;amp; 0 &amp;amp; 0&amp;nbsp; \\&lt;br /&gt;&amp;nbsp; &amp;nbsp;0 &amp;amp; 1 &amp;amp; 0&amp;nbsp; \\&lt;br /&gt;&amp;nbsp; &amp;nbsp;0 &amp;amp; 0 &amp;amp; 1&amp;nbsp; \\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\end{bmatrix}&amp;nbsp;&lt;br /&gt;\end{equation}&lt;br /&gt;$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6. 대각행렬(main diagonal)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%A3%BC%EB%8C%80%EA%B0%81%EC%84%A0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;주대각선&lt;/a&gt;에 위치한 행렬을 제외한 모든 성분이 0인 정사각 행렬을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ &lt;br /&gt;\begin{equation} &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\begin{bmatrix}&amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp;1 &amp;amp; 0 &amp;amp; 0&amp;nbsp;&amp;nbsp;\\ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;0 &amp;amp; 8 &amp;amp; 0&amp;nbsp;&amp;nbsp;\\ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;0 &amp;amp; 0 &amp;amp; 3&amp;nbsp; \\ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\end{bmatrix}&amp;nbsp; &lt;br /&gt;\end{equation}&lt;br /&gt;$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7. 직교행렬(orthogonal matrix)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직교행렬은 아래와 같은 특성을 지닌다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$A^\top = A^{-1}$&lt;/li&gt;
&lt;li&gt;$A^\top A = A A^\top = I$&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cypsw.tistory.com/entry/%ED%96%89%EB%A0%AC-%EA%B8%B0%EC%B4%88#2.%20%EC%97%AD%ED%96%89%EB%A0%AC(inverse%20matrix)-1&quot;&gt;위에서&lt;/a&gt; 역행렬과 원본행렬을 곱하면 항등행렬이 된다고 언급했었다. 하지만 직교행렬의 경우 역행렬과 전치행렬이 개념상 같으므로, 전치행렬과 행렬원본을 곱해도 항등행렬이 도출된다. 즉 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;$A^\top A = A^{-1} A$&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 예제를 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&lt;br /&gt;A =&lt;br /&gt;\begin{equation}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\begin{bmatrix}&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;\cos(x) &amp;amp; \sin(x)&amp;nbsp; \\&lt;br /&gt;&amp;nbsp; &amp;nbsp;-\sin(x) &amp;amp; \cos(x)&amp;nbsp; \\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\end{bmatrix}&amp;nbsp;&lt;br /&gt;\end{equation}&lt;br /&gt;$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&lt;br /&gt;A^\top=&lt;br /&gt;\begin{equation}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\begin{bmatrix}&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;\cos(x) &amp;amp; -\sin(x)&amp;nbsp; \\&lt;br /&gt;&amp;nbsp; &amp;nbsp;\sin(x) &amp;amp; \cos(x)&amp;nbsp; \\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\end{bmatrix}&amp;nbsp;&lt;br /&gt;\end{equation}&lt;br /&gt;$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&lt;br /&gt;A A^\top=&lt;br /&gt;\begin{equation}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\begin{bmatrix}&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;\cos^2(x) + \sin^2(x) &amp;amp; -\cos(x) \sin(x) + \sin(x) \cos(x)&amp;nbsp; \\&lt;br /&gt;&amp;nbsp; &amp;nbsp;- \sin(x) \cos(x) + \cos(x) \sin(x) &amp;amp; \sin^2(x) + \cos^2(x) \\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\end{bmatrix}&amp;nbsp;&lt;br /&gt;= &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\begin{bmatrix}&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;1 &amp;amp; 0 \\&lt;br /&gt;&amp;nbsp; &amp;nbsp;0 &amp;amp; 1\\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\end{bmatrix}&amp;nbsp;&lt;br /&gt;=&lt;br /&gt;I&lt;br /&gt;\end{equation}&lt;br /&gt;$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬 예제 코드를 통해 위 예제의 출력값을 확인해 보자.&lt;/p&gt;
&lt;pre id=&quot;code_1718559561740&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import numpy as np
import math

x = 3.141592

A = np.array([[math.cos(x),      math.sin(x)],
			  [math.sin(x) * -1, math.cos(x)]])

At = np.array([[math.cos(x),    math.sin(x) * -1],
              [math.sin(x),    math.cos(x)]])

print(np.dot(A, At))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&lt;br /&gt;A&amp;nbsp;A^\top&amp;nbsp;=&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;\begin{equation}&lt;br /&gt;\begin{bmatrix}&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;1.00000000e+00&amp;nbsp;&amp;amp;&amp;nbsp;-4.32611126e-23&amp;nbsp;&amp;nbsp;\\ &lt;br /&gt;&amp;nbsp;&amp;nbsp;-4.32611126e-23&amp;nbsp;&amp;amp;&amp;nbsp;1.00000000e+00&amp;nbsp;&amp;nbsp;\\ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;\end{bmatrix}&amp;nbsp; &lt;br /&gt;\end{equation}&lt;br /&gt;$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그래밍 언어 특성상 부동소수점 오차 문제로 완벽히 0이 도출되진 않으나, 항등행렬을 띔을 알 수 있다.&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Artificial Intelligence/Fundamentals</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/186</guid>
      <comments>https://cypsw.tistory.com/entry/%ED%96%89%EB%A0%AC-%EA%B8%B0%EC%B4%88#entry186comment</comments>
      <pubDate>Wed, 17 Apr 2024 20:22:02 +0900</pubDate>
    </item>
    <item>
      <title>[리뷰] AdaLoRA: Adaptive Budget Allocation for Parameter-Efficient Fine-Tuning</title>
      <link>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-AdaLoRA-Adaptive-Budget-Allocation-for-Parameter-Efficient-Fine-Tuning</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2303.10512&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;해당 논문&lt;/a&gt;은 LoRA 를 개선한 버전인 AdaLoRA 에 대해 제안하는 논문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 서론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 Full Fine-Tuning, LoRA 는 NLP 에서 중요한 패러다임이 되었으나, 일반적으로 '모든' parameter 를 미세 조정하기에 최적의 조정을 수행할 수 없다는 단점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 문제를 해결하기 위해 가중치 행렬 간 parameter 자원&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(budget)&lt;/span&gt; 을 중요도 점수에 따라 적응적으로 할당하는 AdaLoRA 를 제안한다. 특히 AdaLoRa 는 특이값 분해&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Singular Value Decomposition, SVD)&lt;/span&gt;의 형태로 증분 업데이트를 parameter 화 한다. 이러한 접근 방식을 통해 중요하지 않은 업데이트의 특이값을 효과적으로 가지치기할 수 있으며, 이는 본질적으로 parameter 의 필요 자원을 줄이는 역할을 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 논문에서는 AdaLoRA 의 효과를 검증하기 위해 여러 광범위한 실험을 수행한다. 특히 AdaLoRA 가 저예산 환경에서 매우 큰 개선을 보여준다는 점을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 소개&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문 저자들은 모든 가중치 행렬을 업데이트 하는 것 보다 일부 가중치 행렬만 수정하는것이 더 높은 성능을 달성한다는것을 발견하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;389&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dNBGmO/btsGCvLdSm0/OAD9xRWfiUjKBjVKsMBmS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dNBGmO/btsGCvLdSm0/OAD9xRWfiUjKBjVKsMBmS0/img.png&quot; data-alt=&quot;그림 1: 학습 가능한 총 매개 변수가 0.28M인 경우 DeBERTaV3 기반의 선택된 가중치 행렬(왼쪽) 또는 선택된 레이어(오른쪽)에만 LoRA를 적용하고 MNLI-m의 미세 조정 성능을 비교한다. 그림 (a): 쿼리/키/값 투영($W_q$, $W_k$, $W_v$), self-attention 출력 투영($W_o$), 2 layer FFN의 두 가중치 행렬($W_{f1}$, $W_{f2}$)을 포함하여 모든 Transformer 레이어의 선택된 유형의 가중치 행렬만 미세 조정한다. 그림 (b)에서는 선택된 레이어의 모든 가중치 행렬에 LoRA를 적용한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dNBGmO/btsGCvLdSm0/OAD9xRWfiUjKBjVKsMBmS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdNBGmO%2FbtsGCvLdSm0%2FOAD9xRWfiUjKBjVKsMBmS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;311&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;389&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 1: 학습 가능한 총 매개 변수가 0.28M인 경우 DeBERTaV3 기반의 선택된 가중치 행렬(왼쪽) 또는 선택된 레이어(오른쪽)에만 LoRA를 적용하고 MNLI-m의 미세 조정 성능을 비교한다. 그림 (a): 쿼리/키/값 투영($W_q$, $W_k$, $W_v$), self-attention 출력 투영($W_o$), 2 layer FFN의 두 가중치 행렬($W_{f1}$, $W_{f2}$)을 포함하여 모든 Transformer 레이어의 선택된 유형의 가중치 행렬만 미세 조정한다. 그림 (b)에서는 선택된 레이어의 모든 가중치 행렬에 LoRA를 적용한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 모든 가중치 행렬을 조정하는것이 최적이지 않다는 것을 의미한다. 즉 optimal 하지 않다. 그렇다면 어떤 가중치 행렬, 어떤 레이어를 선택해야지 가장 optimal 한 업데이트를 수행할 수 있을까?&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;즉.&lt;/p&gt;
&lt;center&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;어떻게 PEFT 의 성능을 향상시키기 위해, &lt;br /&gt;모듈의 중요도에 따라 parameter 의 자원을 적응적으로 할당 할 수 있을까?&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/center&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 질문에 대한 답으로 저자들은 AdaLoRA 를 제안한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;AdaLoRA 는 자원을 제어하기 위해 incremental matrices&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(증분행렬)&lt;/span&gt; 의 rank 를 조절한다. 중요한 증분행렬이라면 보다 세분화된 작업별 정보를 잘 캐치할 수 있도록 높은 rank 로 할당된다. 반면 덜 중요하다면 과적합 예방, 및 예산을 절약하기 위해서 낮은 rank로 할당할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;421&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uUmRe/btsGDCbXQ9J/DEuOPzHjTzzKVx6ZMmK5CK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uUmRe/btsGDCbXQ9J/DEuOPzHjTzzKVx6ZMmK5CK/img.png&quot; data-alt=&quot;그림 3: AdaLoRA로 MNLI를 기반으로 DeBERTaV3 기반 미세 조정 시 각 증분 행렬의 결과 순위. 여기서 x축은 레이어 인덱스이고 y축은 다양한 유형의 적응된 가중치 행렬을 나타낸다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uUmRe/btsGDCbXQ9J/DEuOPzHjTzzKVx6ZMmK5CK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuUmRe%2FbtsGDCbXQ9J%2FDEuOPzHjTzzKVx6ZMmK5CK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;384&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;421&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 3: AdaLoRA로 MNLI를 기반으로 DeBERTaV3 기반 미세 조정 시 각 증분 행렬의 결과 순위. 여기서 x축은 레이어 인덱스이고 y축은 다양한 유형의 적응된 가중치 행렬을 나타낸다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;기존 연구에서는 행렬의 rank를 제어하는 여러 방법들이 제안되었으며, 대부분은 행렬의 특이값 분해&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(SVD)&lt;/span&gt;를 직접 계산하여 가장 작은 특이값을 가지치기한다. 이러한 연산은 rank를 명시적으로 조작할 수 있게 만들며, 결과 행렬과 원래 행렬 간의 차이를 최소화한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 대규모 모델을 미세 조정할 때는 이러한 연산이 고차원 가중치 행렬에 대해 반복적으로 SVD를 적용하는 것이 매우 비효율적이다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(SVD의 연산량은 정사각 행렬일 경우 $O(n^3)$ 이다.)&lt;/span&gt; 그래서 AdaLoRA는 실제 SVD를 계산하는 대신에 $A = P \Lambda Q$ 로 행렬 $A$ 를 파라미터화 하여 SVD 를 모방한다. 여기서 대각행렬 $\Lambda$ 는 특이값을 포함하고, 직교하는 행렬 $P$ 와 $Q$는 $A$의 좌우 특이 벡터를 대표한다.&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 파라미터화를 통해 SVD의 계산량이 많은 부분을 피할 수 있고, 또 다른 이점으로 중요하지 않은 특이값을 감소시키면서도, 그렇지 않은 벡터는 유지시킬 수 있기에 전체적인 훈련과정을 안정화 시킬 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 AdaLoRA 는 SVD를 모방한 방식을 기반으로한 새로운 LoRA 방법으로, 가중치 행렬 $A$ 의 rank 를 중요도에 따라 동적으로 조정한다. 증분행렬 $P \Lambda Q$ 를 &lt;span style=&quot;color: #f89009;&quot;&gt;중요도 점수에 의해 세 개의 그룹으로 나누고, 이러한 중요도는 모델 성능에 기여하는 정도에 따라 측정된다. 중요도가 낮은 특이값은 가지치기되어 계산 절약, 과적합 방지에 기여하며, 중요한 특이값은 미세 조정을 위해 보존&lt;/span&gt;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2-1. SVD&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SVD는 선형대수학에서 중요한 개념중 하나이다. 임의의 행렬을 특정 구조의 세가지 행렬의 곱으로 분해하는것을 말한다. 이는 $A = U \Sigma V^\top$ 로 표현되는데,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$A$ : $m \times n$ rectangular matrix&lt;/li&gt;
&lt;li&gt;$U$ : $m \times m$ orthogonal matrix&lt;/li&gt;
&lt;li&gt;$\Sigma$ : $m \times n$ diagonal matrix&lt;/li&gt;
&lt;li&gt;$V$ : $n \times n$ orthogonal matrix&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;477&quot; data-origin-height=&quot;210&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o2OFY/btsGIMzMdvo/rOiBbveB0P4CP8SMi6O2D0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o2OFY/btsGIMzMdvo/rOiBbveB0P4CP8SMi6O2D0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o2OFY/btsGIMzMdvo/rOiBbveB0P4CP8SMi6O2D0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo2OFY%2FbtsGIMzMdvo%2FrOiBbveB0P4CP8SMi6O2D0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;477&quot; height=&quot;210&quot; data-origin-width=&quot;477&quot; data-origin-height=&quot;210&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 여기서 중요하게 여겨지는 성질이 아래와 같다. $U$ 가 행렬이라고 할 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&lt;br /&gt;\begin{gather} &lt;br /&gt;UU^\top = U^\top U = I\\&lt;br /&gt;U^{-1} = U^\top&lt;br /&gt;\end{gather}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 성립한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt; (이 원리를 이용해 AdaLoRA 에 핵심적인 원리가 구동된다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 SVD 기술을 사용함으로서 AI 분야에서는 아래와 같은 장점을 얻을 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&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;figure id=&quot;og_1711849946107&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;특이값 분해(SVD) - 공돌이의 수학정리노트 (Angelo's Math Notes)&quot; data-og-description=&quot;&quot; data-og-host=&quot;angeloyeo.github.io&quot; data-og-source-url=&quot;https://angeloyeo.github.io/2019/08/01/SVD.html&quot; data-og-url=&quot;https://angeloyeo.github.io/2019/08/01/SVD.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://angeloyeo.github.io/2019/08/01/SVD.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://angeloyeo.github.io/2019/08/01/SVD.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;특이값 분해(SVD) - 공돌이의 수학정리노트 (Angelo's Math Notes)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;angeloyeo.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;최종적으로&lt;span style=&quot;color: #f89009;&quot;&gt; SVD는 임의의 행렬 A를 정보량에 따라 여러 layer로 분할하기 위해서 사용&lt;/span&gt;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. AdaLoRA Method&lt;/b&gt;&lt;/h2&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3-1. SVD-Based Adaptation&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 언급된 바와 같이, AdaLoRA 는 pre-trained 가중치 행렬의 증분 업데이트를, 특이값 분해 형태로 매개변수화 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\large {W = W^{(0)} + \Delta + W^{(0)} + P \Lambda Q}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$P\in\mathbb{R}^{d_1\times r}, Q\in\mathbb{R}^{r\times d_2}$는 각각 left, right singular vector 를 나타내고, $\Lambda\in\mathbb{R}^{r\times r}$ 는 singular value 를 대각행렬로 가지며, 대각행렬 $\Lambda$는 특이값 $\{\lambda_i\}_{1\leq i\leq r}$ 를 포함하며, rank $r$ 은 $r\ll min(d_1,d_2)$ 값을 지닌다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(즉 $d_1, d_2$ 의 최소값보다 작다)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 LoRA와 비교시 $\Lambda$ 의 $r$ 차원의 벡터만 추가된 것이다. 예로, &lt;a href=&quot;https://arxiv.org/pdf/2106.09685.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;LoRA 논문&lt;/a&gt;의 &lt;i&gt;4.1 Low-Rank-Parametrized Update Matrices&lt;/i&gt; 를 살펴보면 아래와 같은 내용을 살펴볼 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;사전 훈련된 가중치 행렬 $W_0 \in \mathcal{R}^{d \times k}$ 의 업데이트를 제한하기 위해, row-rank 분해를 $W_0 + \Delta W = W_0 + BA$ 로 표현한다. 여기서 각 기호는 다음과 같은 의미를 지닌다. $B \in \mathcal{R}^{d \times k}$, $A \in \mathcal{R}^{r \times k}$, 그리고 rank $r$ 은 $r \ll min(d, k)$ 값을 가진다.&lt;br /&gt;&lt;br /&gt;훈련중 $W_0$ 는 동결되며, 기울기 업데이트를 받지 않는다. 반면 $A, B$ 는 trainable parameters 이다. $W_0$ 와 $\Delta W = BA$ 는 모두 동일한 입력값으로 곱해진다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 LoRA 는 아래와 같은 수식을 지닌다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;0_VHra-HtzSwDJeOyt.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;439&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yED7e/dJMcafG7jgk/EOQ2aurZqvV8iGIbkmr92k/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yED7e/dJMcafG7jgk/EOQ2aurZqvV8iGIbkmr92k/img.gif&quot; data-alt=&quot;https://medium.com/@lokeshtodwal/demystifying-lora-q-lora-ea267abff48&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yED7e/dJMcafG7jgk/EOQ2aurZqvV8iGIbkmr92k/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/yED7e/dJMcafG7jgk/EOQ2aurZqvV8iGIbkmr92k/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;439&quot; data-filename=&quot;0_VHra-HtzSwDJeOyt.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;439&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://medium.com/@lokeshtodwal/demystifying-lora-q-lora-ea267abff48&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$h = W_0x + \Delta W x = W_0 x + BA x$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 $A \in \mathbb{R}^{r \times k}$, $B \in \mathbb{R}^{d \times r}$ 이므로, AdaLoRA 와 비교하면 $P \Lambda Q$ 와 비교해야 하는데, $P\in\mathbb{R}^{d_1\times r}, Q\in\mathbb{R}^{r\times d_2}$ 로 상쇄되고, 결국 $\Lambda$ 만 남으로므로 $r$ 차원의 벡터만 하나 추가됨 셈이다. 때문에 이런 의문을 가질 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;그냥 고전적인 LoRA 에서 $A$, $B$ 를 가지치기 하면 되는거 아닌가? AdaLoRA 가 이것과 무슨 차이가 있는데?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 질문에 대해서 저자들은 아래와 같이 답변한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;만약 $A,B$ 를 제거 하였을 때, 그것을 다시 활성화 하는것은 불가능하다.&lt;br /&gt;반면 AdaLoRA 는 $\Lambda$ 중 하나를 0으로 변경만 하는것이기에 원래 rank 를 얼마든지 활용 가능하다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(0으로 곱해서 제거하는 방식이기에 충분히 복구할 수 있는 방식.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;$A, B$는 서로 직교하지 않으므로, 이를 수정한다면 다른 영역에 영향을 줄 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더하여 SVD를 계산하기 위해 모든 $\Delta$ 에 SVD 를 직접 계산할 수 있으나, 위에서 언급하였듯 계산 복잡성은 $O(min(d_1, d_2)d_1 d_2)$ 이다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(정사각 행렬일 경우 $O(n^3)$)&lt;/span&gt; 여기서 $d_1$ 과 $d_2$ 는 행렬이므로, 커질수록 계산 비용이 크게 늘어난다. 때문에 아래와 같은 수식을 사용하여 $P$&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(왼쪽 특이 벡터)&lt;/span&gt;와 $Q$&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(오른쪽 특이 벡터)&lt;/span&gt; 가 얼마나 직교행렬에 가까운지 체크하며&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(SVD의 특징을 모방하기 위해)&lt;/span&gt;, 동시에 아래와 같은 정규화를 사용한다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;$$ \large{R(P, Q) = ||P^\top P - I||_F^2 + ||QQ^\top - I||_F^2} $$&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$R$&lt;/span&gt; : 정규화 항으로서 $P, Q$ 가 직교행렬이 되도록 하는 역할을 한다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$F$&lt;/span&gt; : Frobenius Norm &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(벡터의 L2 lorm 을 행렬로 확장한 것으로 볼 수 있다.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$\top$&lt;/span&gt; :&amp;nbsp;&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%A0%84%EC%B9%98_%ED%96%89%EB%A0%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;전치 행렬&lt;/a&gt;로서, 행렬의 행과 열이 서로 바뀐 행렬을 의미한다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$P^\top P$ 및 $QQ^\top$&lt;/span&gt; : 이런식으로 각 행렬의 전치를 곱한다는 의미는 &lt;a href=&quot;https://namu.wiki/w/%EC%A0%84%EC%B9%98%ED%96%89%EB%A0%AC#s-3.2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;대칭행렬을 만든다는 의미&lt;/a&gt;이다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$I$&lt;/span&gt; :&amp;nbsp;&lt;a href=&quot;https://en.wikipedia.org/wiki/Identity_matrix&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;항등행렬&lt;/a&gt;을 의미한다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$P^\top P - I$ 와 $QQ^\top - I$&lt;/span&gt; : 이를 수행함으로서 항등행렬 $I$ 에 더 가깝게 되도록 만든다. 이를 통해 $P, Q$를 직교행렬이 되도록 유도한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이를 통해 점진적으로 업데이트 해 가며 SVD와 비슷한 효과를 낼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직교 행렬은 전치 행렬과 곱하였을때 항등행렬인 $I$를 생성한다. 결국 위 수식에서 $P^\top$, $P$ 그리고 $Q^\top$, $Q$가 각각 항등행렬에서 얼마나 차이가 나는지를 제곱함으로서 측정한다. 이 최종 값이 더 작아질수록 $P$와 $Q$는 더 직교에 가까워진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직교행렬의 전치행렬은 역행렬과 같다. 따라서 $P^{\top} = P^{-1}$ 그리고 $Q^{\top} = Q^{-1}$ 이다. 때문에 직교행렬을 자신의 전치행렬과 곱하면 항등행렬 $I$가 된다. 결국 $Q$ 가 직교행렬일때, $Q \times Q^\top = I$ 가 성립한다. &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;따라서 AdaLoRA 에서 $P^\top P$ 와 $QQ^\top$ 이 항등행렬 $I$ 에 가깝게 만드는것은 $P$와 $Q$ 가 직교행렬이 되도록 유도한다는 것과 같은 의미가 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더하여 '더 작아질수록' 이라는 말에 집중해 보면, 결국 필요없는 부분을 '점진적으로' 제거해가며 이 최종 값을 작아지도록 만들 수 있는 것이다. $P^\top P$, $QQ^\top$ 값이 항등행렬 $I$ 에 가까워질수록 0에 가까워진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-2. Importance-aware Rank Allocation&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 $P$와 $Q$ 에 대해서 어떻게 최적의 값을 찾는지 알아 보았다면, 해당 섹션에서는 $\Lambda$ 값을 어떻게 조정하는지 알아본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LoRA 와 비교해서 $\Lambda$ 에 해당되는 $r$차원의 벡터의 차이가 바로 AdaLoRA 의 차이였다. 때문에 &lt;span style=&quot;color: #f89009;&quot;&gt;$\Lambda$ 값은 AdaLoRA 에 있어서 핵심이라고 할 수 있으며, $\Lambda$를 통해 어떤 가중치 행렬을 얼마나 더 업데이트할지 정한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자들은 $W_q, W_k, W_v, W_{f1}, W_{f2}$ 를 포함한 모든 transformer 가중치 행렬에 SVD기반 adaptation&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(어떤걸 냅두고, 어떤걸 가지치기 할 것인지 조정하는것을 뜻함)&lt;/span&gt; 적용하였다. 이때 명확한 참조를 위해 증분행렬 $k$를 색인&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(index)&lt;/span&gt; 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;$$ \large{\Delta k = P_k \Lambda_k Q_k \quad \text{for} \, k = 1, \cdots n}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$P_k, \Lambda_k, Q_k$ 는 각각 왼쪽 특이벡터, 특이값, 오른쪽 특이 벡터이며, $n$ 은 adapted weight matrices 의 수이다.&lt;br /&gt;최종적으로 아래와 같은 수식을 통해 스탭$t$에 대해 stochastic gradient 를 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\tilde\Lambda_k^{(t)}=\Lambda_k^{(t)}-\eta\nabla_{\Lambda_k}\mathcal{L(P,E,Q)}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아래는 수식에 대한 직접적인 설명이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$\tilde\Lambda_k^{(t)}$&lt;/span&gt; : 시간단계 $t$에서의 증분행렬 $k$&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(특이값이 수정된 상태)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$\Lambda_k^{(t)}$&lt;/span&gt; : 시간단계 $t$에서의 증분행렬 $k$&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(특이값이 수정되지 않은 상태)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$\nabla_{\Lambda_k}\mathcal{L(P,E,Q)}$&lt;/span&gt; : training objective&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(손실함수의 대분류)&lt;/span&gt;&amp;nbsp;$\mathcal{L(P,E,Q)}$ 에 대한 $\nabla_{\Lambda_k}$ 의 기울기&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$\eta$&lt;/span&gt; : learning-rate&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아래는 수식에 대한 참고 내용이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$\Delta k$의 $i$번째 트리플렛을 $\mathcal{G}_{k,i} = {P_{k, *i}, \lambda_{k,i}, Q_{k,i*}}$ 로 표시&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(&lt;span style=&quot;text-align: left;&quot;&gt;증분행렬 $k$에서&amp;nbsp;&lt;/span&gt; $P_{k, *i}$는 $i$번째 왼쪽 특이벡터, &lt;span style=&quot;text-align: left;&quot;&gt;&amp;nbsp;$\lambda_{k,i}$&lt;/span&gt;는 $i$번째 특이값, &lt;span style=&quot;text-align: left;&quot;&gt;&amp;nbsp;$Q_{k,i*}$&lt;/span&gt;는 $i$번째 오른쪽 특이 벡터)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;중요도 점수를 $S_{k,i}$ 로 표시.&lt;/li&gt;
&lt;li&gt;매개변수 집합 $\mathcal{P}=\{{P_k}\}_{k=1}^{n}, \mathcal{E} = \{\Lambda_k\}^n_{k=1}, \mathcal{Q} = \{ Q_k \}^n_{k=1}$ 의 훈련비용을 $\mathcal{C(P, E, Q)}$ 로 표기.&lt;/li&gt;
&lt;li&gt;정규화과정&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($R(P, Q)$)&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;의 경우, 훈련 목표는 $\mathcal{L(P, E, Q) = C(P, E, Q)} + \mathcal{\gamma \Sigma^n_{k=1}} R(P_k, Q_k)$&lt;/span&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($\gamma &amp;gt; 0$는 정규화 계수)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 수식은 특이값 분해에서 행렬 $\Lambda_k^{(t+1)}$ 을 계산하는 과정을 나타낸다. $\mathcal{T}$ 는 임계값 함수로, 중요도 점수 $S_k^{t}$ 에 따라 가장 중요한 상위 $b^{(t)}$ 개의 특이값을 유지하고, 나머지는 0로 설정하는 역할을 수행한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$${\Lambda}_k^{(t+1)} = \mathcal{T}(\tilde{\Lambda}_k^{(t)}, S_k^{(t)}), \text{ with } \mathcal{T}(\tilde{\Lambda}_k^{(t)}, S_k^{(t)})_{ii} =&amp;nbsp; &lt;br /&gt;\begin{cases}&amp;nbsp; &lt;br /&gt;\tilde{\Lambda}_{k,ii}^{(t)} &amp;amp; \text{if } S_{k,i}^{(t)} \text{ is in the top-}b^{(t)} \text{of } S^{(t)}, \\ &lt;br /&gt;0&amp;nbsp;&amp;amp;&amp;nbsp;\text{otherwise}. &lt;br /&gt;\end{cases} &lt;br /&gt;$$&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이하 수식에 대한 설명은 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$t$&lt;/span&gt; : 시간단계&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$b$&lt;/span&gt; : 가지치기 단계에서 특이값 중 중요도가 높은 상위 몇 개를 유지할지 결정하는 값. 즉 특정 시간단계&lt;span style=&quot;color: #9d9d9d;&quot;&gt;$(t)$&lt;/span&gt; 에 대한 limit 값, 예산&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(budget)&lt;/span&gt;, 자원을 의미한다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$k$&lt;/span&gt; : 각 트랜스포머 레이어의 가중치 행렬, $1 \sim n$ 값을 가지며, $n$은 레이어에 있는 가중치 행렬의 총 수임.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$i$&lt;/span&gt; : 특정 가중치 행렬 $\Delta$k 의 특이값 중 하나를 나타내는 인덱스.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$S_{k, i}^{(t)}$&lt;/span&gt; : 특정 시간단계 $t$에서 증 행렬 $k$의, $i$번째 트리플렛의 중요도.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$\tilde{\Lambda}_k^{(t)}$&lt;/span&gt; : 특정 시간단계$t$에서 $k$번째 증분 행렬에 대한 저차원 근사치에서 파생된 특이값을 포함하는 행렬. 해당 행렬은 SVD를 통해 얻은 결과의 일부이며, 가중치 행렬 $W$를 저차원 공간으로 근사하는데 이용.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$\tilde{\Lambda}_{k,ii}^{(t)}$&lt;/span&gt; : $k$ 번째 증분 행렬의 $i$ 번째 특이값에 해당행렬에 대한 정보를 담고있음. 중요도에 기반해 가지치기 과정을 통하여, 해당 특이값중 일부는 다음 시간 단계에서 유지되거나, 아예 제거될 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 중요도가 낮은 정보는 제하고, 중요한 특성을 갖는 특이값을만 보존하여 다음 단계의 훈련에 사용함으로서, 계산 효율성을 높이는데 도움을 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;최종적으로 AdaLoRA 는 아래와 같은 과정을 따른다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1476&quot; data-origin-height=&quot;571&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EMXm8/btsGewqLrMW/RlyF5gKkHTzXmL5W7ESCoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EMXm8/btsGewqLrMW/RlyF5gKkHTzXmL5W7ESCoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EMXm8/btsGewqLrMW/RlyF5gKkHTzXmL5W7ESCoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEMXm8%2FbtsGewqLrMW%2FRlyF5gKkHTzXmL5W7ESCoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;309&quot; data-origin-width=&quot;1476&quot; data-origin-height=&quot;571&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단히 요약하면 아래와 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;$\bar{I}^{(t)}$, $\bar{U}^{(t)}$ 는 각각 민감도&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(파라미터가 얼마나 민감한가, 작은 변화가 얼마나 큰 영향을 미치는가(다만 지수이동 평균을 통해 smoothing 되어있음))&lt;/span&gt;와, 정량화된 불확실성&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($I^{(t)}$와 $\bar{I}^{(t)}$ 사이의 국부적 변동에 의해 정량화된 불확실성, 민감도의 추정치가 얼마나 정확한가, 불확실성이 높다면 민감도 추정치를 조심히 다뤄야함)&lt;/span&gt;을 의미함.&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터셋에서 미니배치 샘플링, 해당 배치에 대한 기울기를 계산.&lt;/li&gt;
&lt;li&gt;파라미터에 대해 민감도, 중요도를 갱신한다.&lt;/li&gt;
&lt;li&gt;이를 통해 $P, Q$ 와 특이값 $\Lambda$ 를 업데이트한다.&lt;/li&gt;
&lt;li&gt;이를 반복-파라미터를 조절한다.&lt;/li&gt;
&lt;li&gt;최종적으로 미세 조정된 파라미터를 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #f89009;&quot;&gt;&lt;b&gt;결국, LoRA 와 AdaLoRA 의 차이는&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AdaLoRA 는 중요도를 기반으로 가중치를 업데이트 할 수 있다. LoRA 는 모든 파라미터에 대해 동일 업데이트 적용하지만 AdaLoRA 는 특이값의 중요도를 평가하기에, 더 중요한 파라미터에 더 많은 '자원&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(budget)&lt;/span&gt;'&amp;nbsp; 을 할당할 수 있으며, 상대적으로 중요하지 않은 파라미터의 가중치 행렬을 점진적으로 제거하여 과적합 방지, 일반화 성능 향상 등에 기여한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3-3. Global Budget Scheduler&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rank 를 조정하는 이유는, low-rank adaptive 맥락에서 매개변수의 예산을 제어하기 위해서이다.&amp;nbsp;이러한 예산의 조절은 미세 조정중 반복적으로 수행되며, 논문 내에서는 교육을 용이하게 하기 위해 Global Budget Scheduler 를 제안한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목표 예산 $b^{(T)}$ 보다 약간 높은 초기 예산 $b^{(0)}$ 에서 시작하며, 증분 행렬의 초기 rank 값을 $r={b^{(0)} \over n}$ 으로 설정한다. 추가로 각 단계 $t_i$ 에 대한 교육을 warm up 한 뒤 $b^{(T)}$ 에 도달할 때까지 예산 $b^{(T)}$ 를 줄이기 위해 cubic schedule 을 따른다. 이러한 방식으로 $t_f$ 단계에 대해 모델을 미세 조정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 방식을 통해 AdaLoRA 는 먼저 매개변수 공간을 탐색한 다음, 나중에는 가장 중요한 가중치에 집중할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. Experiments&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 구현된 AdaLoRA 에 대한 테스트 결과를 보여주는 섹션이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1032&quot; data-origin-height=&quot;472&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pMSnO/btsGupy8DTO/G7kMm71SFTKoYokKyXCsK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pMSnO/btsGupy8DTO/G7kMm71SFTKoYokKyXCsK0/img.png&quot; data-alt=&quot;표 1: GLUE development set에 대한 DeBERTaV3 기반의 결과. 각 데이터 세트에 대한 최상의 결과는 굵은 글씨로 표시된다. 우리는 STS-B에 대한 평균 상관 관계를 보고한다. 전체 FT, HA 어댑터 및 PA 어댑터는 각각 전체 미세 조정, Houlsby 어댑터 및 Piffer 어댑터를 나타낸다. 우리는 서로 다른 무작위 시드를 사용하여 5번 실행의 평균을 보고한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pMSnO/btsGupy8DTO/G7kMm71SFTKoYokKyXCsK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpMSnO%2FbtsGupy8DTO%2FG7kMm71SFTKoYokKyXCsK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;366&quot; data-origin-width=&quot;1032&quot; data-origin-height=&quot;472&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 1: GLUE development set에 대한 DeBERTaV3 기반의 결과. 각 데이터 세트에 대한 최상의 결과는 굵은 글씨로 표시된다. 우리는 STS-B에 대한 평균 상관 관계를 보고한다. 전체 FT, HA 어댑터 및 PA 어댑터는 각각 전체 미세 조정, Houlsby 어댑터 및 Piffer 어댑터를 나타낸다. 우리는 서로 다른 무작위 시드를 사용하여 5번 실행의 평균을 보고한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 표에서 중요한건 Full FT 와 LoRA, 그리고 AdaLoRA 간의 성능 비교이다. 단발적으로 테스트한것이 아닌 무작위 seed 의 5번 실행의 평균을 보고하고 있다. 전반적으로 거의 모든 경우에서 AdaLoRA 가 가장 우수한 결과를 보여주는 모습을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;299&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZBltI/btsGwMNjvES/jODJMSoYpEEFvtZtFKY9Nk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZBltI/btsGwMNjvES/jODJMSoYpEEFvtZtFKY9Nk/img.png&quot; data-alt=&quot;표 2: SQuAD v1.1 및 SQuADv2.0을 기반으로 한 DeBERTaV3 기반 결과. 여기서 #Params는 전체 미세 조정 시와 비교하여 훈련 가능한 매개 변수의 수이다. 우리는 EM/F1을 보고한다. 각 설정에서 최상의 결과는 굵게 표시된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZBltI/btsGwMNjvES/jODJMSoYpEEFvtZtFKY9Nk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZBltI%2FbtsGwMNjvES%2FjODJMSoYpEEFvtZtFKY9Nk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;233&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;299&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 2: SQuAD v1.1 및 SQuADv2.0을 기반으로 한 DeBERTaV3 기반 결과. 여기서 #Params는 전체 미세 조정 시와 비교하여 훈련 가능한 매개 변수의 수이다. 우리는 EM/F1을 보고한다. 각 설정에서 최상의 결과는 굵게 표시된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 Params 를 늘린다고 극적인 성능변화는 존재하지 않지만, 그래도 미세하게 성능이 상승하긴 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더하여 모든 params 에서 Adapter, LoRA 대비 항상 우수한 성능을 보여준다는 것도 확인할 수 있으며, Fine-Tuning 대비 우수한것도 마찬가지이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 마치며&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;421&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uUmRe/btsGDCbXQ9J/DEuOPzHjTzzKVx6ZMmK5CK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uUmRe/btsGDCbXQ9J/DEuOPzHjTzzKVx6ZMmK5CK/img.png&quot; data-alt=&quot;그림 3: AdaLoRA로 MNLI를 기반으로 DeBERTaV3 기반 미세 조정 시 각 증분 행렬의 결과 순위. 여기서 x축은 레이어 인덱스이고 y축은 다양한 유형의 적응된 가중치 행렬을 나타낸다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uUmRe/btsGDCbXQ9J/DEuOPzHjTzzKVx6ZMmK5CK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuUmRe%2FbtsGDCbXQ9J%2FDEuOPzHjTzzKVx6ZMmK5CK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;384&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;421&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 3: AdaLoRA로 MNLI를 기반으로 DeBERTaV3 기반 미세 조정 시 각 증분 행렬의 결과 순위. 여기서 x축은 레이어 인덱스이고 y축은 다양한 유형의 적응된 가중치 행렬을 나타낸다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AdaLoRA 는 아마 또다른 혁명이 되지 않을까? 한다. 아쉽게도 나의 수학적인 지식이 부족해 원리를 근본까지 이해하진 못 했지만, 그 효과는 충분히 체감할 수 있었다. 개인적으로 진행하는 연구에 적용해 본 결과, 성능이 Fine-Tuning 은 물론이고 LoRA 를 상회하였으며, 저자들이 논문에서 지나가듯 언급한 '과적합 예방' 효과도 확인해 볼 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전반적으로 Fine-Tuning 대비 성능도 높게 뽑히고, 메모리도 적게 먹고... 대단히 좋은 기술이 아닌가 한다.&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Artificial Intelligence/Paper Review</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/185</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-AdaLoRA-Adaptive-Budget-Allocation-for-Parameter-Efficient-Fine-Tuning#entry185comment</comments>
      <pubDate>Sun, 31 Mar 2024 11:08:46 +0900</pubDate>
    </item>
    <item>
      <title>[C++] 백준 2002 문제 해설</title>
      <link>https://cypsw.tistory.com/entry/C-%EB%B0%B1%EC%A4%80-2002-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EC%84%A4</link>
      <description>&lt;figure id=&quot;og_1711604127577&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;2002번: 추월&quot; data-og-description=&quot;입력은 총 2N+1개의 줄로 이루어져 있다. 첫 줄에는 차의 대수 N(1 &amp;le; N &amp;le; 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 대근이가 적은 차량 번호 목록이 주어지고, N+2째 줄부터 N개의 줄에는 영식이&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/2002&quot; data-og-url=&quot;https://www.acmicpc.net/problem/2002&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Xd6li/hyVGKfiaN6/yT305wiJhJgKZY0PQhF1l1/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2002&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/2002&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Xd6li/hyVGKfiaN6/yT305wiJhJgKZY0PQhF1l1/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;2002번: 추월&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;입력은 총 2N+1개의 줄로 이루어져 있다. 첫 줄에는 차의 대수 N(1 &amp;le; N &amp;le; 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 대근이가 적은 차량 번호 목록이 주어지고, N+2째 줄부터 N개의 줄에는 영식이&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 별생각없이 풀었고, 나중에 다들 map 을 쓴다는걸 알게되어서 추가하였다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;두가지 버전 모두 첨부한다.&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;map(X)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1711604111536&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;

int main()
{
	int N;
	bool visited[1000] = {false, };
	std::vector&amp;lt;std::string&amp;gt; input;
	std::vector&amp;lt;std::string&amp;gt; output;

	std::cin &amp;gt;&amp;gt; N;
	std::string temp;

	// 입력 로직
	for(int i = 0; i &amp;lt; N; ++i)
	{
		std::cin &amp;gt;&amp;gt; temp;
		input.push_back(temp);
	}

	for(int i = 0; i &amp;lt; N; ++i)
	{
		std::cin &amp;gt;&amp;gt; temp;
		output.push_back(temp);
	}
	
	// 최종 출력될 count
	int count = 0;

	// index_output 은 output vector 를 뒤에서부터 진입함.
	int index_output = N-1;

	for(int index_input = N-1; index_input &amp;gt;= 0; --index_input)
	{
		while(visited[index_output] == true)
		{
			index_output -= 1;
		}

		if(input[index_input] != output[index_output] &amp;amp;&amp;amp; visited[index_output] == false)
		{
			++count;

			for(int z = index_output; z &amp;gt;= 0; --z)
			{
				if(input[index_input] == output[z])
				{
					visited[z] = true;
					break;
				}
			}
		}
		else
		{
			visited[index_output] = true;
			index_output -= 1;
		}
	}

	std::cout &amp;lt;&amp;lt; count;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;예를들어 아래와 같은 입력이 있다고 생각 해 보자, 왼쪽은 input 이고, 오른쪽은 output 이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;총 20개의 예제이며, 정답은 16이다.&lt;/p&gt;
&lt;pre id=&quot;code_1711671629741&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 20 / 16
# 66G776P8  24446M23
# 361517    66G776P8
# X20G2M    X20G2M
# AO6C4D    AO6C4D
# V8O717LM  47B6322B
# 47B6322B  V8O717LM
# 1280DH03  E75828
# 4AI1AC7   4AI1AC7
# A3G550    A3G550
# 38586T25  465HQ54
# E75828    G1288Y1
# 3M200VPN  3M200VPN
# 7M02R0G0  7M02R0G0
# 877F43    877F43
# 24446M23  361517
# 465HQ54   38586T25
# 5013DC12  5013DC12
# 525745    525745
# G1288Y1   1280DH03
# 7005B8    7005B8&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;어떤 차가 추월했는지 쉽게 파악이 가능하다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;좌측&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(input)&lt;/span&gt;과 우측&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(output)&lt;/span&gt;을 비교하며 나아가는 방식이다.&lt;/p&gt;
&lt;pre id=&quot;code_1718168848830&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for(int z = index_output; z &amp;gt;= 0; --z)
{
	if(input[index_input] == output[z])
	{
		visited[z] = true;
		break;
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;만약 N의 사이즈가 커진다면, 해당 코드에서 시간제한 문제가 생길 가능성이 크다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;물론 문제에서 주어진 1000개 분량에서는 문제가 생기지 않았다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 문제를 예방하고자 map 을 사용할 수 있고,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아래와 같이 수정하였다.&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;map(O)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1718168874092&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;map&amp;gt;

int main()
{
	int N;
	std::cin &amp;gt;&amp;gt; N;

	std::vector&amp;lt;std::string&amp;gt; input;
	std::vector&amp;lt;std::string&amp;gt; output;
	std::map&amp;lt;std::string, bool&amp;gt; visited;

	std::string temp;

	// 입력 로직
	for(int i = 0; i &amp;lt; N; ++i)
	{
		std::cin &amp;gt;&amp;gt; temp;
		input.push_back(temp);
		visited.insert(std::pair&amp;lt;std::string, bool&amp;gt;(temp, false));
	}

	for(int i = 0; i &amp;lt; N; ++i)
	{
		std::cin &amp;gt;&amp;gt; temp;
		output.push_back(temp);
	}
	
	// 최종 출력될 count
	int count = 0;

	// index_output 은 output vector 를 뒤에서부터 진입함.
	int index_output = N-1;

	for(int index_input = N-1; index_input &amp;gt;= 0; --index_input)
	{
		while(visited[output[index_output]])
		{
			--index_output;
		}

		visited[input[index_input]] = true;
		
		if(input[index_input] == output[index_output])
		{
			--index_output;
		}
		else
		{
			++count;
		}
	}

	std::cout &amp;lt;&amp;lt; count;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Algorithm/BACKJOON</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/184</guid>
      <comments>https://cypsw.tistory.com/entry/C-%EB%B0%B1%EC%A4%80-2002-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EC%84%A4#entry184comment</comments>
      <pubDate>Thu, 28 Mar 2024 15:07:18 +0900</pubDate>
    </item>
    <item>
      <title>[C++] 백준 14501 문제 해설</title>
      <link>https://cypsw.tistory.com/entry/C-%EB%B0%B1%EC%A4%80-14501-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EC%84%A4</link>
      <description>&lt;figure id=&quot;og_1711519719630&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;14501번: 퇴사&quot; data-og-description=&quot;첫째 줄에 백준이가 얻을 수 있는 최대 이익을 출력한다.&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/14501&quot; data-og-url=&quot;https://www.acmicpc.net/problem/14501&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/4DnHN/hyVDudX1X6/EaXAwvOuhAQQwxY0x2kNo0/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14501&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/14501&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/4DnHN/hyVDudX1X6/EaXAwvOuhAQQwxY0x2kNo0/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;14501번: 퇴사&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 백준이가 얻을 수 있는 최대 이익을 출력한다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해당 문제에 대해서 여러 풀이가 존재하지만,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이 풀이가 가장 좋아보이기에 주석을 달아 포스팅 해 본다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해당문제에서 명심해야 할 점은 그냥 최고 급여만 출력하면 된다는 점이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;날짜는 기록할 필요도 없다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;힌트는 '거꾸로' 계산하는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2298&quot; data-origin-height=&quot;260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDI22o/btsF7wdPvng/7LjuabSui5ZwzhhkbjOxFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDI22o/btsF7wdPvng/7LjuabSui5ZwzhhkbjOxFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDI22o/btsF7wdPvng/7LjuabSui5ZwzhhkbjOxFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDI22o%2FbtsF7wdPvng%2F7LjuabSui5ZwzhhkbjOxFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;91&quot; data-origin-width=&quot;2298&quot; data-origin-height=&quot;260&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;예로 문제 내용을 보면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;7일과 6일은 근무일을 넘어가기에 계산에 포함시켜야될 필요도 없다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;5일 = 15&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;O&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;4일 = 20 + 15&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;O&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;3일 = 10 + 20 + 15&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;O&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;2일 = 20 &amp;lt; (10 + 20 + 15)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;X&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;1일 = (10 + 20 + 15) == (10 + 20 + 15)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;O&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 최고로 나올 수 있는 값은 45 이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;위 지식을 기반으로 아래 코드를 살펴보자.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1711519688935&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

#define MAX 16

int N; // 퇴사일
int Ti[MAX] = {
	0,
}; // 상담일
int Pi[MAX] = {
	0,
}; // 급여
int arr[MAX] = {
	0,
}; // 평가 배열

int max(int a, int b)
{
	return a &amp;gt; b ? a : b;
}

int main()
{
	// 입력으로 퇴사일자 받음.
	std::cin &amp;gt;&amp;gt; N;

	// 입력으로 상담일, 급여를 받음.
	for (int i = 1; i &amp;lt;= N; i++)
	{
		std::cin &amp;gt;&amp;gt; Ti[i] &amp;gt;&amp;gt; Pi[i];
	}

	int deadline;

	for (int i = N; i &amp;gt; 0; i--)
	{
		// deadline 은 현재날짜(i)와 상담일(Ti[i])을 더함.
		// deadline 은 엄밀히 말해, 오늘 근무를 포함시키고 있지 않음.
		// 위 예제에서 i가 7이고, Ti[i] 가 1일경우 8이 됨.
		deadline = i + Ti[i];
		// 하지만 N + 1 을 통해 퇴사일과 보정되므로 상관없음.
		// 더하여 이런 deadline 특성을 이용해 arr 을 더 잘 이용할 수 있음.

		// 만약 deadline 날짜가 퇴사일을 초과하면 상담이 불가함.
		if (deadline &amp;gt; N + 1)
		{
			// 상담이 불가할 시 행하는 구간.
			// 그냥 뒤에서 계산했던 최고치를 현재위치에 재할당함.
			arr[i] = arr[i + 1];
		}
		else
		{
			// 상담이 가능할 시 행하는 구간.
			// arr[i+1] 은 이전에 계산했던 최고치가 삽입되어 있음. 하지만 만약 그 최고치보다.
			// 오늘 받을 수 있는 급여 + 데드라인 후에 받을 수 있는 최고 급여가 더 크다면 해당 값을 max 로 사용.
			// 만약 상담일(i)이 1 이라면 최고치와, 오늘 급여까지 더해 최고치를 갱신함.
			arr[i] = max(arr[i + 1], arr[deadline] + Pi[i]);

			// 결론적으로 arr[1] 값에는 현재로서 받을 수 있는 최고치가 누적되어 있음.
		}
	}

	std::cout &amp;lt;&amp;lt; arr[1] &amp;lt;&amp;lt; std::endl;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;예로 아래와 같은 입력값이 주어지면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;161&quot; data-origin-height=&quot;334&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqG8fz/btsF9LggI6l/XNpjkuZ9N5IwFFyeLD1iJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqG8fz/btsF9LggI6l/XNpjkuZ9N5IwFFyeLD1iJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqG8fz/btsF9LggI6l/XNpjkuZ9N5IwFFyeLD1iJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqG8fz%2FbtsF9LggI6l%2FXNpjkuZ9N5IwFFyeLD1iJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;161&quot; height=&quot;334&quot; data-origin-width=&quot;161&quot; data-origin-height=&quot;334&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;최종 arr 은 아래와 같이 설정된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;256&quot; data-origin-height=&quot;395&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DbvcV/btsF9NZseWm/YUQNVfKPxaZ77g8xOqgZJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DbvcV/btsF9NZseWm/YUQNVfKPxaZ77g8xOqgZJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DbvcV/btsF9NZseWm/YUQNVfKPxaZ77g8xOqgZJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDbvcV%2FbtsF9NZseWm%2FYUQNVfKPxaZ77g8xOqgZJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;256&quot; height=&quot;395&quot; data-origin-width=&quot;256&quot; data-origin-height=&quot;395&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 매 진행상황간에 arr[i] 는 항상 최고치일 수 밖에 없으며,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;arr[1] 은 전체 프로세스에서 최고값이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해당 문제는 여러곳에서 응용이 가능하기에, 곱씹어볼만한 필요성이 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;정말 군더더기 없이 깔끔하게 작성된 알고리즘이다.&lt;/p&gt;</description>
      <category>Algorithm/BACKJOON</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/183</guid>
      <comments>https://cypsw.tistory.com/entry/C-%EB%B0%B1%EC%A4%80-14501-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EC%84%A4#entry183comment</comments>
      <pubDate>Wed, 27 Mar 2024 15:11:50 +0900</pubDate>
    </item>
    <item>
      <title>[C++] 백준 1260번 문제 해설</title>
      <link>https://cypsw.tistory.com/entry/C-%EB%B0%B1%EC%A4%80-1260%EB%B2%88-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EC%84%A4</link>
      <description>&lt;figure id=&quot;og_1711506786402&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;1260번: DFS와 BFS&quot; data-og-description=&quot;첫째 줄에 정점의 개수 N(1 &amp;le; N &amp;le; 1,000), 간선의 개수 M(1 &amp;le; M &amp;le; 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/1260&quot; data-og-url=&quot;https://www.acmicpc.net/problem/1260&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1260&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/1260&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;1260번: DFS와 BFS&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 정점의 개수 N(1 &amp;le; N &amp;le; 1,000), 간선의 개수 M(1 &amp;le; M &amp;le; 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;DFS, BFS 관련된 문제로 간단한 문제이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해석은 주석으로 기재 해 두었으며&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;코드의 흐름따라 주석과 함께 코드를 읽어보면 쉽게 이해가 될 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1711506762311&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;queue&amp;gt;

// 이론상 정점의 개수는 1,000 개 이며 1 &amp;lt; N &amp;lt; 1000 이므로 1001 지정.
// 간선의 개수는 10,000 개 미만임.
// map 을 기준으로 1,000 x 1,000 = 1,000,000 의 간선 지정이 가능.
#define MAX 1001
 
int N, M, V; // 정점 개수, 간선 개수, 시작정점
int map[MAX][MAX]; // 정점간 연결 확인
bool visited[MAX]; // 정점 방문 여부
 
void reset() 
{
    for (int i = 1; i &amp;lt;= N; i++) 
    {
        visited[i] = 0;
    }
}
 
// 깊이 우선 탐색 시작
void DFS(int v) 
{
    // 첫 정점 visited 를 True 로 지정.
    visited[v] = true;
    std::cout &amp;lt;&amp;lt; v &amp;lt;&amp;lt; &quot; &quot;;
    
    // [DFS 핵심 로직 시작]
    // map[v][0] 는 자기 자신이므로 1 부터 검색
    // map[v][i] 가 1 이라면 정점과 정점간 '연결된 것'으로 간주.
    for (int i = 1; i &amp;lt;= N; i++) 
    {
        // 현재 정점과 연결되어있고 방문되지 않았으면 &amp;rarr; 방문처리.
        if (map[v][i] == 1 &amp;amp;&amp;amp; visited[i] == 0) 
        {
            // 진입하는 순간 재귀적으로 i 가 출력됨.
            // 다시 '방문한 정점' 을 기준으로 깊이 파 내려감
            DFS(i);
            // 계속 연결여부와, visited 를 체크하면서 반복.
        }
    }
}


std::queue&amp;lt;int&amp;gt; q;

// 너비 우선 탐색 시작, 너비 우선 탐색은 재귀적으로 작동하지 않음.
void BFS(int v) 
{
    // queue 에 시작 정점 정보를 삽입하고, 바로 visited 처리, 출력
    q.push(v);
    visited[v] = true;
    std::cout &amp;lt;&amp;lt; v &amp;lt;&amp;lt; &quot; &quot;;

    // queue 가 차있다면 계속 while.
    while (!q.empty()) 
    {
        v = q.front();
        q.pop();
        
        // 1부터 정점의 개수(N) 까지 반복함. 정점의 개수만큼 출력.
        for (int w = 1; w &amp;lt;= N; w++) 
        {
            // 현재 정점과, 연결되어 있으며, 방문하지 않은 정점을 찾을때 까지 반복
            // 만약 없다면 그대로 종료 (연결된 그래프가 아님.)
            if (map[v][w] == 1 &amp;amp;&amp;amp; visited[w] == 0) 
            {
                q.push(w);
                visited[w] = true;
                std::cout &amp;lt;&amp;lt; w &amp;lt;&amp;lt; &quot; &quot;;

                // 이 후에 v 기준 연결된 모든 정점을 찾아 출력함.
                // v와 연결된 정점들은 queue 에 들어있음.
                // queue 를 기반으로 다시 반복.
            }
        }
    }
}
 
int main() {
    std::cin &amp;gt;&amp;gt; N &amp;gt;&amp;gt; M &amp;gt;&amp;gt; V;

    // 입력을 받음과 동시에 map 을 설정함.
    // 정점 연결 정보를 map[a][b] 로 바로 접근 가능.
    // 메모리가 소폭 낭비되나, search 를 하지 않아도 되기에 속도면에서 빠름.
    for (int i = 0; i &amp;lt; M; i++) 
    {
        int a, b;
        std::cin &amp;gt;&amp;gt; a &amp;gt;&amp;gt; b;
        map[a][b] = 1;
        map[b][a] = 1;
    }

    // reset() 은 visit 정보를 초기화.
    reset();
    DFS(V);
    
    std::cout &amp;lt;&amp;lt; '\n';
    
    reset();
    BFS(V);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;기본적인 알고리즘 문제고, 대부분 시간을 들이면 풀 수 있지만.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;문제는 항상 '갑자기' 풀라고 주어졌을때다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;검색없이 풀려면 몇시간 해메게 될 수 있으므로,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;원리와 코드 구현을 머릿속에 추상화 시켜 놓으면 좋다.&lt;/p&gt;</description>
      <category>Algorithm/BACKJOON</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/182</guid>
      <comments>https://cypsw.tistory.com/entry/C-%EB%B0%B1%EC%A4%80-1260%EB%B2%88-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EC%84%A4#entry182comment</comments>
      <pubDate>Wed, 27 Mar 2024 11:39:15 +0900</pubDate>
    </item>
    <item>
      <title>[리뷰] LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS</title>
      <link>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-LORA-LOW-RANK-ADAPTATION-OF-LARGE-LANGUAGE-MODELS</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 서론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자연어 처리는 시간이 가면 갈수록 중요해지고 있다. Text to Speech, Speech to Text, Translation, GPT 에 이르기까지 그 발전 가능성은 무궁무진 하다. 특히 핵심적인 혁신은 모델 자체를 수정하는 데에서 오는 경우가 많지만, 그럼에도 불구하고 fine-tuning 은 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 모델의 사이즈가 점점 커져감에 따라 전체 fine-tuning은 매우 버거운 작업이 되었다. 예로 GPT-3 의 한 모델은 175B 개의 parameter가 존재하는데, 이런 무지막지한 모델을 fine-tuning 하는것은 어지간한 대규모 연구소 수준이 아니면 버거운 일이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 저자들은 pre-trainied 모델의 가중치를 'freeze' 하고 transformer 아키텍처의 각 계층에 훈련 가능한 행렬을 주입하여 down stream 작업에 대한 훈련 가능한 매개변수의 수를 크게 줄이는, LoRA를 제안한다. 예로 GPT-3 175B fine-tuning 에 비해 LoRA 는 훈련 가능한 parameter 의 수를 10,000배, GPU 메모리 요구사항을 3배 가까이 줄일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LoRA 는 RoBERTa, DeBERTa, GPT-2, GPT-3에서 모델 품질 면에서 미세 조정과 동등하거나 더 나은 성능을 보이며, 학습 가능한 파라미터가 적음에도 불구하고, 높은 학습 처리량을 달성하고 어댑터와 달리 추가적인 추론&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(inference)&lt;/span&gt; 지연 시간 없이 작동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 소개&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자연어 처리의 많은 응용 프로그램들은 하나의 대규모 pre-trained 모델을 이용해 여러 다운스트림 응용 프로그램에 적응시키는데 의존한다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(실제 현재의 GPT가 그렇다. Python 코드 분석 특화용, 요리 특화용, 소설 시나리오 특화용 등등..)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 '적응' 과정은 일반적으로 pre-trained 모델의 모든 parameter 를 업데이트하는, 즉 fine-tuning 을 통해서 이뤄진다. 하지만 fine-tuning 모든 parameter 를 업데이트 하여야 한다는 단점이 있다. 더 큰 모델이 계속해서 훈련됨에 따라 이러한 작업은 점점 힘들어 졌다. 예로, 위에서 언급했듯이 GPT-3 의 경우 1,750 억개의 파라미터가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 문제점으로 인해 과거에 일부 parameter만 조정하거나, 외부 모듈을 학습시켜 이러한 점을 완화하려고 하였다. 이로인해 소수의 parameter만 저장, 로드하면 되므로 배포 운영의 효율성이 크게 향상되었다. 하지만 이러한 방법이 종종 fine-tuning 기준선과 일치하지 못해 모델의 품질 저하가 발생한다는 문제점이 있다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(즉 fine-tuning 과는 같은 수준의 성능을 달성하지 못한다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 모델의 크기나 복잡도를 줄이기 위해 일부 파라미터만 조정하거나, 외부 모듈을 추가하는 방법은 운영상의 효율성을 향상시킬 수 있으나, 이러한 접근방식이 모델의 전반적인 성능이나 작업 수행 능력을 저하시킬 수 있다. 때문에 결국 모델의 효율성과 품질 사이에서 균형을 찾아야 한다는 선택의 문제로 이어진다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;455&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uunIL/btsF2wYq3Np/GYLRJirKGQqg6YGrd9bxRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uunIL/btsF2wYq3Np/GYLRJirKGQqg6YGrd9bxRk/img.png&quot; data-alt=&quot;Figure 1: Our re-parametrization. We only train A and B.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uunIL/btsF2wYq3Np/GYLRJirKGQqg6YGrd9bxRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuunIL%2FbtsF2wYq3Np%2FGYLRJirKGQqg6YGrd9bxRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;504&quot; height=&quot;455&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;455&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 1: Our re-parametrization. We only train A and B.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지의 변수들에 대한 설명은 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$h$ : hidden state&lt;/li&gt;
&lt;li&gt;$x$ : input data&lt;/li&gt;
&lt;li&gt;$W \in \mathbb{R^{d \times d}}$ : pre-trained 모델의 가중치 행렬, 해당 가중치는 '고정' 되어있고 업데이트 되지 않는다.&lt;/li&gt;
&lt;li&gt;$A, B$ : LoRA에 의해 도입된 새로운 행렬, $A$는 정규분포 $\mathcal{N}(0, \sigma^2)$ 을 사용해 초기화되며, $B$ 는 0 로 초기화된다. 해당 행렬들은 각각 $r$ 차원의 낮은 랭크를 가지며, 해당 차원은 모델의 본래 차원인 $d$에 비해 낮다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;보다 쉽게 설명하면 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;538&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ir8p4/btsFUECvMVS/rMv7bgBEg95qDAwdksEZ6k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ir8p4/btsFUECvMVS/rMv7bgBEg95qDAwdksEZ6k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ir8p4/btsFUECvMVS/rMv7bgBEg95qDAwdksEZ6k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIr8p4%2FbtsFUECvMVS%2FrMv7bgBEg95qDAwdksEZ6k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;336&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;538&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fine-tuning 방식은 왼쪽과 같다. Weight update 를 수행하는데, 만약 $\Delta W$ 에 10,000 개의 행과, 20,000 개의 열이 있다면, 200,000,000 개의 parameter 가 저장된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 만약 $r = 8$ 인 $A$와 $B$를 선택한다면 $A$ 는 10,000 개의 행 8개의 열을 가지고, $B$ 8개의 행 20,000 개의 열을 가진다. 이는 곧 $10,000 \times 8 + 8 \times 20,000 = 240,000$ 개의 매개변수를 지니며, 이는 본래 매개변수인 0.2B 와는 830배 작은 수준이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;결론적으로 LoRA 는 아래와 같은 특징을 지닌다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;pre-trained 모델을 공유하여 다양한 작업을 위한 많은 작은 LoRA 모듈을 구축할 수 있다. $\Delta W$ 를 행렬 $A$와 $B$를 로 대체하여 공유 모델을 동결하고 효율적으로 작업을 전환할 수 있어 저장 요구 사항과 작업 전환 오버헤드를 크게 줄일 수 있다.&lt;/li&gt;
&lt;li&gt;LoRA는 대부분의 매개변수에 대해 기울기를 계산하거나 옵티마이저 상태를 유지할 필요가 없기 때문에 적응형 옵티마이저를 사용할 때 훈련을 더 효율적으로 만들고 하드웨어 요구사항을 최대 3배까지 낮춘다.&lt;/li&gt;
&lt;li&gt;간단한 선형 설계를 통해 배포 시 &lt;span style=&quot;color: #f89009;&quot;&gt;학습 가능한 행렬과 동결 가중치를 병합&lt;/span&gt;할 수 있으며, 구성에 따라 완전히 미세 조정된 모델에 비해 추론 지연 시간&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(어댑터 레이어를 사용하는 경우, 이들의 추가적인 계산이 모델의 전체 추론 속도를 느리게 만들 수 있다.)&lt;/span&gt;이 도입되지 않는다&lt;/li&gt;
&lt;li&gt;LoRA는 이전의 많은 방법들과 직교하며, prefix-tuning 과 같은 많은 방법들과 결합될 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대규모 신경망은 지연시간을 낮게 유지하기 위해 하드웨어 병렬처리에 의존하지만, 어댑터 계층은 순차적으로 처리되어야 한다. 이로 인해서 배치 크기가 1과 같이 작은 경우나, GPU 같은 하드웨어가 병렬처리를 충분히 활용하지 못하는 설정에서는 이러한 지연 시간이 특히 문제가 될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 추론 성능을 극대화하고 싶을 때는 어댑터 레이어의 사용이 지연시간을 증가시킬 수 있다는 점을 고려하여야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. LoRA 의 설계 및 장점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사전 학습된 가중치 행렬 $W_0 \in \mathbb{R^{d \times k}}$ 의 경우, 후자를 낮은 순위 분해. $W_0 + \Delta W = W_0 + BA$ 로 업데이트를 제한하며, 여기서 $B \in \mathbb{R}^{d \times r}, A \in \mathbb{R}^{r \times k}$ 및 rank $r \ll min(d,k)$ 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;훈련중에 $W_0$ 는 기울기 업데이트를 수신하지 못하는 반면, $A, B$ 는 업데이트 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$W_0$ 와 $\Delta W = BA$ 는 모두 동일한 입력으로 곱해지고, 각각의 출력벡터는 좌표 단위로 합산된다. $h = W_0 x$ 의 경우 forward pass 는 다음과 같이 산출된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ h = W_0 x + \Delta W x = W_0 x + BA_x $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 코드에서 살펴볼 수 있는 $\alpha$ 에 관한 내용이 여기서 나온다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;178&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/G0kIq/btsFR0NnoLr/5iBQiaYkf6dwPOJlBssfx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/G0kIq/btsFR0NnoLr/5iBQiaYkf6dwPOJlBssfx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/G0kIq/btsFR0NnoLr/5iBQiaYkf6dwPOJlBssfx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FG0kIq%2FbtsFR0NnoLr%2F5iBQiaYkf6dwPOJlBssfx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;682&quot; height=&quot;133&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;178&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;훈련과정을 시작할 때 $\Delta W$ 를 스케일링 하기 위해 스케일 인자 $\alpha$ 를 사용하며, 이는 가중치 변화의 크기를 조절하며, rank $r$ 에 따라 조정된다. Adam 옵티마이저를 사용할 때 $\alpha$ 를 조정하는것은 learning rate 를 조정하는 것과 같은 효과를 얻을 수 있다.&lt;/p&gt;
&lt;figure id=&quot;og_1710844406660&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Understanding alpha parameter tuning in LORA paper&quot; data-og-description=&quot;I was reading the LORA paper https://arxiv.org/pdf/2106.09685.pdf a thing I don&amp;rsquo;t understand is section 4.1, where the updates are updated by alpha, where alpha is a constant in r. It is said that ...&quot; data-og-host=&quot;datascience.stackexchange.com&quot; data-og-source-url=&quot;https://datascience.stackexchange.com/a/123630&quot; data-og-url=&quot;https://datascience.stackexchange.com/questions/123229/understanding-alpha-parameter-tuning-in-lora-paper&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mh7bw/hyVDF5JxP3/LeT4273iEscluyctDduRa1/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://datascience.stackexchange.com/a/123630&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://datascience.stackexchange.com/a/123630&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mh7bw/hyVDF5JxP3/LeT4273iEscluyctDduRa1/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Understanding alpha parameter tuning in LORA paper&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I was reading the LORA paper https://arxiv.org/pdf/2106.09685.pdf a thing I don&amp;rsquo;t understand is section 4.1, where the updates are updated by alpha, where alpha is a constant in r. It is said that ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;datascience.stackexchange.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 LoRA 는 기존 $\Delta W$ 와 병렬로 훈련 가능한 소규모 행렬을 추가하는 기법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 실험.&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자들은 이러한 설계를 검증하기 위해서 여러 테스트를 진행했다. NVIDIA Tesla V100 을 사용하였다고 언급한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1447&quot; data-origin-height=&quot;728&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xUYZ1/btsFUHGjKhF/rOsd9kYgUZkiiubHdLRE2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xUYZ1/btsFUHGjKhF/rOsd9kYgUZkiiubHdLRE2k/img.png&quot; data-alt=&quot;표 2: GLUE 벤치마크에서 다른 적응 방법을 사용하는 $RoBERTa_{base}$, $RoBERTa_{large}$ 및 $DeBERTa_{XXL}$입니다. MNLI에 대한 전반적인 (일치 및 일치하지 않는) 정확도, CoLA에 대한 Matthew의 상관 관계, STS-B에 대한 Pearson 상관 관계 및 다른 작업에 대한 정확도를 보고합니다. 모든 메트릭에 대해 높은 값이 더 좋습니다. $*$는 이전 작업에서 발표된 숫자를 나타냅니다. $\dagger$는 공정한 비교를 위해 Houlsby et al. (2019)과 유사한 설정에서 구성된 실행을 나타냅니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xUYZ1/btsFUHGjKhF/rOsd9kYgUZkiiubHdLRE2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxUYZ1%2FbtsFUHGjKhF%2FrOsd9kYgUZkiiubHdLRE2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;402&quot; data-origin-width=&quot;1447&quot; data-origin-height=&quot;728&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 2: GLUE 벤치마크에서 다른 적응 방법을 사용하는 $RoBERTa_{base}$, $RoBERTa_{large}$ 및 $DeBERTa_{XXL}$입니다. MNLI에 대한 전반적인 (일치 및 일치하지 않는) 정확도, CoLA에 대한 Matthew의 상관 관계, STS-B에 대한 Pearson 상관 관계 및 다른 작업에 대한 정확도를 보고합니다. 모든 메트릭에 대해 높은 값이 더 좋습니다. $*$는 이전 작업에서 발표된 숫자를 나타냅니다. $\dagger$는 공정한 비교를 위해 Houlsby et al. (2019)과 유사한 설정에서 구성된 실행을 나타냅니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체적인 지표를 보면 Fine-tuning 보다 LoRA 가 더 좋은 지표를 보이는것이 많다. Fine-Tuning 과 유사하거나, 더 우수하다고도 평할 만 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1073&quot; data-origin-height=&quot;503&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJQkRR/btsFWLt8Aal/Da5FDp1k8OWIRyQMvK3Zw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJQkRR/btsFWLt8Aal/Da5FDp1k8OWIRyQMvK3Zw1/img.png&quot; data-alt=&quot;표 3: E2E NLG 챌린지에서 적응 방법이 다른 GPT-2 매체(M) 및 대형(L). 모든 메트릭에 대해 더 높은 것이 좋습니다. LoRA는 비슷하거나 더 적은 훈련 가능한 파라미터로 여러 기준선을 능가합니다. 우리가 실행한 실험에 대한 신뢰 구간이 표시됩니다. *는 이전 작업에서 발표된 숫자를 나타냅니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJQkRR/btsFWLt8Aal/Da5FDp1k8OWIRyQMvK3Zw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJQkRR%2FbtsFWLt8Aal%2FDa5FDp1k8OWIRyQMvK3Zw1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;375&quot; data-origin-width=&quot;1073&quot; data-origin-height=&quot;503&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 3: E2E NLG 챌린지에서 적응 방법이 다른 GPT-2 매체(M) 및 대형(L). 모든 메트릭에 대해 더 높은 것이 좋습니다. LoRA는 비슷하거나 더 적은 훈련 가능한 파라미터로 여러 기준선을 능가합니다. 우리가 실행한 실험에 대한 신뢰 구간이 표시됩니다. *는 이전 작업에서 발표된 숫자를 나타냅니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPT-2 테스트에서도 비슷한 결과를 보여준다. LoRA 는 더 적은 Trainable-Parameters 를 가지고 더 우수한 성능을 보여준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외에도 저자들은 여러 테스트를 거쳐 어떤 옵션을 조절하는것이 가장 좋은 성능을 내는지 기재하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1150&quot; data-origin-height=&quot;229&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/laChv/btsFVsWoVUJ/PSCSjDZ8KUUQWQvszaasvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/laChv/btsFVsWoVUJ/PSCSjDZ8KUUQWQvszaasvK/img.png&quot; data-alt=&quot;표 5: 동일한 수의 훈련 가능한 매개 변수가 주어졌을 때, GPT-3의 다양한 유형의 주의 가중치에 LoRA를 적용한 후 WikiSQL 및 MultiNLI에 대한 검증 정확도. $W_q$와 $W_v$를 모두 적용하면 전반적으로 최상의 성능을 얻을 수 있다. 우리는 주어진 데이터 세트에 대해 무작위 시드에 대한 표준 편차가 일관됨을 발견하고, 첫 번째 열에 보고한다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/laChv/btsFVsWoVUJ/PSCSjDZ8KUUQWQvszaasvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlaChv%2FbtsFVsWoVUJ%2FPSCSjDZ8KUUQWQvszaasvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;159&quot; data-origin-width=&quot;1150&quot; data-origin-height=&quot;229&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 5: 동일한 수의 훈련 가능한 매개 변수가 주어졌을 때, GPT-3의 다양한 유형의 주의 가중치에 LoRA를 적용한 후 WikiSQL 및 MultiNLI에 대한 검증 정확도. $W_q$와 $W_v$를 모두 적용하면 전반적으로 최상의 성능을 얻을 수 있다. 우리는 주어진 데이터 세트에 대해 무작위 시드에 대한 표준 편차가 일관됨을 발견하고, 첫 번째 열에 보고한다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$W_q, W_v$ 를 모두 적용하면 전반적으로 최고의 성능을 얻을 수 있다고 언급한다. 물론 말이 그렇다는것이고, 엄밀히 보면 $W_q, W_k, W_v, W_o$ 를 모두 적용하는것이 평균적인 성능은 가장 좋을것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;305&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/de7BJ0/btsFVR9t9gb/QRGkJwmpjKJTtHmLqbt7d0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/de7BJ0/btsFVR9t9gb/QRGkJwmpjKJTtHmLqbt7d0/img.png&quot; data-alt=&quot;표 6: rank $r$이 다른 WikiSQL 및 MultiNLI에서의 검증 정확도. 놀랍게도, $W_q$를 훈련하는 동안 $W_q$와 $W_v$를 모두 이 데이터 세트에 적용하기에는 하나의 rank로 충분하지만, $W_q$만 더 큰 r이 필요하다. 우리는 섹션 H.2에서 GPT-2에 대해 유사한 실험을 수행한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/de7BJ0/btsFVR9t9gb/QRGkJwmpjKJTtHmLqbt7d0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fde7BJ0%2FbtsFVR9t9gb%2FQRGkJwmpjKJTtHmLqbt7d0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;228&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;305&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 6: rank $r$이 다른 WikiSQL 및 MultiNLI에서의 검증 정확도. 놀랍게도, $W_q$를 훈련하는 동안 $W_q$와 $W_v$를 모두 이 데이터 세트에 적용하기에는 하나의 rank로 충분하지만, $W_q$만 더 큰 r이 필요하다. 우리는 섹션 H.2에서 GPT-2에 대해 유사한 실험을 수행한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대충 보면 알겠지만 $r$ 값을 증가시킨다고 해서 극적인 성능변화는 발생하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$r$ 과 $W_q, W_k, W_v, W_o$ 간의 관계를 한눈에 파악할 수 있어서 유용한 표이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 여담.&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1711049126093&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;LoRA-PEFT - HuggingFace examples - LoRA does not train faster/nor does it allow a bigger batch size (essentially no improvement)&quot; data-og-description=&quot;System Info Platform system: Windows-10-10.0.22621-SP0 Python version: 3.9.13 Available RAM : 31.872 GB CPU count: 20 CPU model: Intel(R) Core(TM) i9-10900K CPU @ 3.70GHz GPU count: 1 GPU model: 1 ...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/huggingface/transformers/issues/25760#issuecomment-1698976640&quot; data-og-url=&quot;https://github.com/huggingface/transformers/issues/25760&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/beLudh/hyVAyHHRQ4/qZiS5Xn3kKHcqyMOcZhTA0/img.png?width=1200&amp;amp;height=600&amp;amp;face=990_133_1080_232&quot;&gt;&lt;a href=&quot;https://github.com/huggingface/transformers/issues/25760#issuecomment-1698976640&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/huggingface/transformers/issues/25760#issuecomment-1698976640&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/beLudh/hyVAyHHRQ4/qZiS5Xn3kKHcqyMOcZhTA0/img.png?width=1200&amp;amp;height=600&amp;amp;face=990_133_1080_232');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;LoRA-PEFT - HuggingFace examples - LoRA does not train faster/nor does it allow a bigger batch size (essentially no improvement)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;System Info Platform system: Windows-10-10.0.22621-SP0 Python version: 3.9.13 Available RAM : 31.872 GB CPU count: 20 CPU model: Intel(R) Core(TM) i9-10900K CPU @ 3.70GHz GPU count: 1 GPU model: 1 ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 LoRA 를 테스트 해 보는데 여러 궁금증이 있어서 찾아보았고, 해당 답변에서 재미있는 내용을 들을 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문에서 말하는 '효율성' 과 같은 단어들은 'training time' 단축을 의미하지 않는다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;따라서 계산 측면에서 고정되지 않은 모델과 비교할 때 차이가 거의 없습니다. 실제 절약되는 유일한 자원은 메모리입니다(고정된 가중치에 대해 grads+optim 상태를 할당할 필요가 없기 때문입니다). 따라서 훈련 속도 향상은 많은 요인에 따라 달라지며 이는&lt;b&gt; PEFT가 개선하겠다고 약속하는 것이 아닙니다.&lt;/b&gt; 이를 통해 기존 하드웨어에 대규모 모델을 맞추거나 더 큰 배치를 맞추는 동시에 전체 미세 조정과 비슷한 성능을 얻으려고 노력할 수 있습니다. 양자화 기술과 그래디언트 체크포인트는 메모리 요구 사항을 더욱 낮춥니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 LoRA 와 같은 PEFT 는 '메모리 절약' 관점에서 이점이 있고, &lt;span style=&quot;color: #f89009;&quot;&gt;기존 가중치를 유지&lt;/span&gt;하는데에서 의의를 찾을 수 있다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(무엇보다 fine-tuning 대비 성능저하가 거의 없다시피 한 것이 특징이다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 크게 느끼는 점이, 사실 ASR 이던, 일반적인 LLM 이던, AI 분야의 뭐든 최근에 등장한 모델들은 parameter 를 많이 때려박고, 대용량의 데이터를 있는대로 다때려박으면 성능은 얼마든지 올라갈 수 있다. 실제로 많은 예제들을 살펴보면 알 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 안타깝게도 전력과 데이터의 양에는 한계가 있다. 얼핏 무한 해 보일수 있지만 그렇지 않다는것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1041&quot; data-origin-height=&quot;406&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ChRdJ/btsF2CXXET3/EbDNNzZDNoQ6MP6E62mA3K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ChRdJ/btsF2CXXET3/EbDNNzZDNoQ6MP6E62mA3K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ChRdJ/btsF2CXXET3/EbDNNzZDNoQ6MP6E62mA3K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FChRdJ%2FbtsF2CXXET3%2FEbDNNzZDNoQ6MP6E62mA3K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;312&quot; data-origin-width=&quot;1041&quot; data-origin-height=&quot;406&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;AMD 의 CEO 인 리사 수 박사는 최근 관련 프레젠테이션에서 이 문제점에 대해 언급했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;715&quot; data-origin-height=&quot;397&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KLo8V/btsF0tuFMys/JvoYEyGGtEEbYskBPxl1nk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KLo8V/btsF0tuFMys/JvoYEyGGtEEbYskBPxl1nk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KLo8V/btsF0tuFMys/JvoYEyGGtEEbYskBPxl1nk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKLo8V%2FbtsF0tuFMys%2FJvoYEyGGtEEbYskBPxl1nk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;444&quot; data-origin-width=&quot;715&quot; data-origin-height=&quot;397&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 발전 속도라면 2035년에 슈퍼컴퓨터를 구동하는데 원자력 발전소 한기와 맞먹는 전력이 필요할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마찬가지로, AI 기술에서 중요한점은 '얼마나 좋은 성능을 낼 수 있느냐? 따위가 아니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'좋은 성능을, 얼마나 적당한 전력 선에서&amp;nbsp;낼 수 있는가?' 이다.&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(이는 training, inference 관점에서 모두 포함된다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LoRA는 그 중 Training 전력 소모 관점에서 충분히 이점을 제공할 수 있는 기술이다.&lt;br /&gt;추후 저전력 HW, AI 등의 발전이 더욱 크게 일어나서 휴대폰에서도 GPT 5 최고 파라미터를 구동하는 날이 오기를 기대한다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(아마 20년은 걸릴듯 싶다.)&lt;/span&gt;&lt;/p&gt;</description>
      <category>Artificial Intelligence/Paper Review</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/181</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-LORA-LOW-RANK-ADAPTATION-OF-LARGE-LANGUAGE-MODELS#entry181comment</comments>
      <pubDate>Tue, 19 Mar 2024 21:44:11 +0900</pubDate>
    </item>
    <item>
      <title>모델 훈련시 Epoch 와 Steps 의 차이</title>
      <link>https://cypsw.tistory.com/entry/%EB%AA%A8%EB%8D%B8-%ED%9B%88%EB%A0%A8%EC%8B%9C-Epoch-%EC%99%80-Steps-%EC%9D%98-%EC%B0%A8%EC%9D%B4</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델을 훈련할때 평가과정은 보통 epoch 로 진행하는데, 간혹 특정 예제들은 steps 로 진행되기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예로 &lt;a href=&quot;https://huggingface.co/docs/transformers/v4.38.2/en/main_classes/trainer#transformers.Seq2SeqTrainingArguments&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Seq2SeqTrainingArguments&lt;/a&gt; 의 설정 옵션을 살펴보면&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;evaluation_strategy&amp;nbsp;(str&amp;nbsp;or&amp;nbsp;IntervalStrategy,&amp;nbsp;optional,&amp;nbsp;defaults&amp;nbsp;to&amp;nbsp;&quot;no&quot;)&lt;/span&gt; - The evaluation strategy to adopt during training. Possible values are:
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&quot;no&quot;&lt;/span&gt;: No evaluation is done during training.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&quot;steps&quot;&lt;/span&gt;: Evaluation is done (and logged) every eval_steps.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&quot;epoch&quot;&lt;/span&gt;:&amp;nbsp;Evaluation&amp;nbsp;is&amp;nbsp;done&amp;nbsp;at&amp;nbsp;the&amp;nbsp;end&amp;nbsp;of&amp;nbsp;each&amp;nbsp;epoch.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라고 기재되어 있는 모습을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 steps 와 epoch 는 어떤 차이가 존재할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 배경지식&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 이러한 steps 와 epoch 의 차이를 알기 위해서는 batch_size 에 관해서 알아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 아래 포스팅을 참고하길 바란다.&lt;/p&gt;
&lt;figure id=&quot;og_1709603844797&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;batch_size 란?&quot; data-og-description=&quot;여러 모델을 학습시키는데에는 batch_size 옵션을 지정해 주어야 한다. 나의 경우 Transformer 를 학습시킬때 사용되는 Seq2SeqTrainingArguments 의 batch_size 옵션을 지정하기 위해 batch_size 의 계념에 관해 살&quot; data-og-host=&quot;cypsw.tistory.com&quot; data-og-source-url=&quot;https://cypsw.tistory.com/entry/batchsize-%EB%9E%80&quot; data-og-url=&quot;https://cypsw.tistory.com/entry/batchsize-%EB%9E%80&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/uPlla/hyVumzIJLo/ABItD1v4RrlrSAIJ4daSI1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/Ig54p/hyVuoYAtS1/JRKksHoWVlzf2fEIL7Pe41/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://cypsw.tistory.com/entry/batchsize-%EB%9E%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cypsw.tistory.com/entry/batchsize-%EB%9E%80&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/uPlla/hyVumzIJLo/ABItD1v4RrlrSAIJ4daSI1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/Ig54p/hyVuoYAtS1/JRKksHoWVlzf2fEIL7Pe41/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;batch_size 란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;여러 모델을 학습시키는데에는 batch_size 옵션을 지정해 주어야 한다. 나의 경우 Transformer 를 학습시킬때 사용되는 Seq2SeqTrainingArguments 의 batch_size 옵션을 지정하기 위해 batch_size 의 개념에 관해 살&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;cypsw.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Epoch&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;epoch 는 '전체 훈련 데이터' 를 통해서 신경망을 한번 학습시키는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다고 해서 batch_size 가 의미 없는것은 아닌것이. 전체 데이터가 100개의 sample 이고, 10의 batch_size 를 가진다면 총 10번에 걸쳐 1 epoch 이 진행되기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Steps&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 '10번에 걸쳐' 1 epoch 가 진행된다고 하지 않았나? 그런데 이 '10번' 을 steps 라고 지칭한다.&amp;nbsp;따라서 만약 내가 100개의 sample 을 지니고 있고, 10의 batch_size 를 지닐 때, '5 스탭' 만 진행한다고 하면 50개의 샘플만 신경망에 학습되는 원리이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 steps 를 키워서 epoch 기준으로는 3.5 epoch 만큼 학습시킬 수 있는 등 다양하게 지정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 수식&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;E : Epoch&lt;/li&gt;
&lt;li&gt;S : Steps&lt;/li&gt;
&lt;li&gt;B : batch_size&lt;/li&gt;
&lt;li&gt;C : data sample count&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;steps 를 epoch 로 변환할 수 있는 수식은 아래와 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;$$ E = {B * S \over C} $$&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;한 epoch 가 완료되기 위해 필요한 steps 의 총 수는 아래와 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;$$ S = {C \over B} $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Artificial Intelligence/Fundamentals</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/179</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%AA%A8%EB%8D%B8-%ED%9B%88%EB%A0%A8%EC%8B%9C-Epoch-%EC%99%80-Steps-%EC%9D%98-%EC%B0%A8%EC%9D%B4#entry179comment</comments>
      <pubDate>Tue, 5 Mar 2024 11:16:20 +0900</pubDate>
    </item>
    <item>
      <title>batch_size 란?</title>
      <link>https://cypsw.tistory.com/entry/batchsize-%EB%9E%80</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;여러 모델을 학습시키는데에는 batch_size 옵션을 지정해 주어야 한다. 나의 경우 Transformer 를 학습시킬때 사용되는 &lt;a href=&quot;https://huggingface.co/docs/transformers/v4.38.2/en/main_classes/trainer#transformers.Seq2SeqTrainingArguments&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Seq2SeqTrainingArguments&lt;/a&gt; 의 batch_size 옵션을 지정하기 위해 batch_size 의 개념에 관해 살펴보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Seq2SeqTrainingArguments 에서 batch_size 옵션은&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;per_device_train_batch_size (int, optional, defaults to 8)&lt;/span&gt; : The&amp;nbsp;batch size per GPU/XPU/TPU/MPS/NPU core/CPU for training.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로서, 이는 &lt;span style=&quot;color: #f89009;&quot;&gt;'모델이&amp;nbsp;한번에&amp;nbsp;학습하는&amp;nbsp;데이터&amp;nbsp;샘플수'&lt;/span&gt;&amp;nbsp;이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 batch_size 를 지정하는데는 아래와 같은 장, 단점이 존재한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;큰 batch_size 의 장점&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(거꾸로 작은 batch_size 의 단점)&lt;/span&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;일반적으로 학습 속도가 더 빨라진다&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(HW의 병렬 처리 능력을 최대한 활용 가능)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;한 번의 업데이트에 더 많은 샘플 데이터를 반영하기에, 경사 하강법의 변동성을 줄여 보다 안정적인 학습과 수렴이 가능하다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(발산 가능성 낮아짐)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;큰 batch_size 의 단점&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(거꾸로 작은 batch_size 의 장점)&lt;/span&gt;&amp;nbsp;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://stats.stackexchange.com/a/236393/256867&quot;&gt;일반화 성능을 저하시킬 수 있다.&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이는 큰 배치가 소규모 배치에 비해 경사 하강법의 탐색 과정에서 덜 다양한 경로를 탐색하게 만들기 때문이다.&lt;/li&gt;
&lt;li&gt;여러 샘플들을 통해 평균치를 내므로 local minimum 을 탈출할 수 있는 예제가 주어짐에도 탈출하지 못 할 가능성이 작은 batch_size 보다 높다.&lt;/li&gt;
&lt;li&gt;학습 시 더 많은 메모리를 소모한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 적절한 batch_size 를 찾는것은 노가다와, 경험적인 영역이다. 모든 경우에 최적값으로 사용할 수 있는 batch_size 는 존재하지 않다&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(사용하는 데이터, 모델, learning_rate 의 값에 따라, 변동될 수 있기에 매우 복잡하다.)&lt;/span&gt;&lt;/p&gt;</description>
      <category>Artificial Intelligence/Fundamentals</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/178</guid>
      <comments>https://cypsw.tistory.com/entry/batchsize-%EB%9E%80#entry178comment</comments>
      <pubDate>Tue, 5 Mar 2024 10:46:03 +0900</pubDate>
    </item>
    <item>
      <title>[리뷰] TRIAAN-VC</title>
      <link>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-TRIAAN-VC</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2303.09057&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;TRIAAN-VC&lt;/a&gt; &lt;a href=&quot;https://ieeexplore.ieee.org/document/10096642&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;논문&lt;/a&gt;은 any-to-any voice conversion 을 수행하는 모델이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 IEEE 에서 여러 VC 논문들을 찾아보았다. 특히 2020년 이후에 제작된 any-to-any 모델들을 중점적으로 살펴보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그간 VC 관련 논문들을 꽤 많이 읽어보았고, 그에 따른 결론은 '구조가 어떻게 되든 일단 성능이 최고인 것을 찾자' 였다. Speech 데이터를 생성하는 모델은 성능을 평가하기가 '까다롭다'.&amp;nbsp; 보통 많은 청취자를 동원해서 직접 사람이 통계적으로 평가를 하는 MOS 지표를 토대로 평가한다. 좀 비 과학적으로 보일 수 있어도, MOS 점수가 내가 주관적으로 느끼는 모델의 실제 성능과 엇나간 적은 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어쨋든 IEEE 에서 여러 논문들을 검색해 본 결과, 일부 모델들은 MOS 점수를 제공하지 않고, demo 조차도 제공하지 않아 모델의 직접적인 성능을 가늠하기 어려운 것들이 많았고, 기존 방법 대비 유의미하게 성능이 증대되지 않는것들도 꽤 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러던 도중 발견한것이 바로 이 TRIAAN-VC 논문인데, 정말 뛰어난 성능을 보여준다. &lt;a href=&quot;https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-HiFi-VC-High-Quality-ASR-Based-Voice-Conversion&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 HiFi-VC 논문&lt;/a&gt;에서 말했던 여러 any-to-any 모델은 content 발화의 문제는 없었지만, 유사성에서 문제가 있었는데, 해당 모델은 content 의 발화 부분은 물론이고 VC 된 음성의 유사성 마저도 크게 개선되었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://winddori2002.github.io/vc-demo.github.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;데모&lt;/a&gt;를 들어보길 바란다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;1. INTRODUCTION&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;VC는 source speaker 가 말하는 음성내용&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(content)&lt;/span&gt;을 유지한 채, target speaker 의 음성으로 변환하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문에서 제시되는 모델은 any-to-any 변환이 가능하며, 훈련중 겪어보지 않은 speaker&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(unseen speakers)&lt;/span&gt;에 대해서도 적용할 수 있는 기술이다. 동시에 모델은 &lt;a href=&quot;https://www.ncbi.nlm.nih.gov/pmc/articles/PMC10417535/#:~:text=One-shot%20voice%20conversion%20(VC,task%20that%20still%20remains%20challenging.&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;one-shot&lt;/a&gt; 기술이 적용되어 몇 초 분량의 target 음성만으로도 올바르게 변환될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자들이 제안하는 방법과는 달리, 이전 방법들은 여러 문제가 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최초에 VC는&amp;nbsp;&lt;a href=&quot;https://zerojsh00.github.io/posts/Vector-Quantization/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;vector quantization&lt;/a&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(벡터 양자화)&lt;/span&gt; 방법을 통해 discrete codes 를 content 로, discrete features 와 continuous features 의 차이를 speaker 표현으로 사용하였다. 그러나 discrete codes 로 content 를 표현하면 시간 관계&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(time relationships)&lt;/span&gt; 가 손상되어 content 가 망가지는 문제점을 시작으로 여러 문제를 해결하기 위해 아래와 같은 과정이 있었다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;vector quantization 사용함 &amp;rarr; 시간 관계가 손상되어 content 손상되는 결과가 나타남.&lt;/li&gt;
&lt;li&gt;그래서 attention-based conversion 으로 바꿈 &amp;rarr; speaker 특성과 유사하게 잘 바뀌는데, 너무 결과가 'speaker 유사성' 에만 편향됨.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(특정 speaker 에 집중되는 문제 및 content 쪽이 깨지는듯?)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;그래서 &lt;a href=&quot;https://www.notion.so/AdaIN-Arbitrary-Style-Transfer-in-Real-Time-With-Adaptive-Instance-Normalization-9fe8b5fb60154380b6fbe3147e0afe9e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;AdaIN&lt;/a&gt; 도입함 &amp;rarr; 높은 수준의 speaker 특징만 사용해서 결과가 speaker 유사성에 편향되게 만듬.&lt;/li&gt;
&lt;li&gt;근데 AdaIN 은 충분한 speaker 특성을 나타낼 수 없다는 문제점이 존재함.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 이전의 방법들은 any-to-any VC 에서 상당한 개선을 이뤘지만, source content 의 유지나, target 의 유사성만을 만족하는 결과를 가져왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 저자들은 Triple Adaptive Attention Normalization VC&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(TriAAN-VC)&lt;/span&gt; for non-parallel A2A&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(any-to-any)&lt;/span&gt; VC 를 제안한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;encoder-decoder 구조를 기반으로 하는 TriAAN-VC 는 content 와 speaker의 특징을 분리하며, TriAAN Block 은 세부 및 전역 speaker features 를 추출하며, conversion 을 위한 정규화&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(normalization)&lt;/span&gt;를 사용한다. 추가로&amp;nbsp;source content 를 최대한 유지하기 위해 시간 마스킹을 갖는 &lt;a href=&quot;https://tyami.github.io/deep%20learning/Siamese-neural-networks/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;샴&lt;/a&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(siamese)&lt;/span&gt; 손실이 적용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 TriAAN-VC 는 source content 의 유지, target speaker 와의 유사성 부분에서 모두 우수한 성능을 달성했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;2. METHOD&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1289&quot; data-origin-height=&quot;354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qKo1u/btsFeSHxsmN/kRkZNBRMRLoazIF6YSKeZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qKo1u/btsFeSHxsmN/kRkZNBRMRLoazIF6YSKeZ0/img.png&quot; data-alt=&quot;그림 1. TriAAN-VC 의 전체 아키텍처.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qKo1u/btsFeSHxsmN/kRkZNBRMRLoazIF6YSKeZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqKo1u%2FbtsFeSHxsmN%2FkRkZNBRMRLoazIF6YSKeZ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;220&quot; data-origin-width=&quot;1289&quot; data-origin-height=&quot;354&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 1. TriAAN-VC 의 전체 아키텍처.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/pdf/2104.02901.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;S2VC&lt;/a&gt; 에서 제안한 CPC 특징이 VC 성능 향상에 기여하기에, TriAAN-VC 는 모델의 입력으로 이를 사용하며, 사전 훈련된 모델을 사용하여 원시 오디오 $x_{raw} \in \mathbb{R}^{t}$ 에서 CPC 특징 $x \in \mathbb{R}^{H \times T}$ 를 추출한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$H, T$&lt;/span&gt; : $x_{raw}$ 의 hidden size 및 세그먼트 길이&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$t$&lt;/span&gt; : $x_{raw}$ 의 신호길이&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 DIO 알고리즘을 $x_{raw}$에 적용하여 소스 스피커의 피치 정보를 표현하기 위해 $\log F0$&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($x_{f0} \in \mathbb{R}^T$)&lt;/span&gt; 를 추출한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;* &lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://kaen2891.tistory.com/77&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;CPC&lt;/a&gt; : Unsupervised Learing 방법론 중 데이터에 있는 Shared information을 추출하는 방법으로. Target Class를 직접적으로 추정하지 않고 Target 위치의 벡터와 다른 위치의 벡터를 비교하는 방식으로 학습한다. 또한 두 벡터 내에 공유정보인 shared information을 직접적으로 추출하는 함수를 구성하고 이를 최대화 할 수 있는 InfoNCE Loss를 제시한다. 이를 통해 비교적 짧은 시간동안 효율적으로 모델을 학습할 수 있으며, 모델로부터 다양한 용도에 활용할 수 있는 좋은 Representation Vector를 추출할 수 있다. 해당 방법론은 다양한 분야(이미지, 텍스트, 음성 등)에 활용이 가능하며 기존 Unsupervised 방법론과 비교했을 때 더 좋은 representation을 생성하는 것을 실험적으로 증명하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림과 같이 TriAAN-VC 는 두개의 encoder 와 decoder 로 구성되어 있다. encoder 는 각각 content와 speaker 정보를 추출하는 encoder 로 구성되어 있으며, encoder-decoder 는 botteneck layer 를 통해서 연결되고, 각각 $L$ 개의 layer 로 구성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;encoder 이전에 $x_{c,s} \in \mathbb{R}_{c,s}^{H \times T}$ 에 Convolution layer 를 적용하여 $H$ 를 채널 크기 $C$ 로 확장한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($\mathbb{R}_{c,s}^{H&amp;nbsp;\times&amp;nbsp;T}$&amp;nbsp;-&amp;nbsp;$c,&amp;nbsp;s$&amp;nbsp;에&amp;nbsp;대한&amp;nbsp;$H&amp;nbsp;\times&amp;nbsp;T$&amp;nbsp;크기의&amp;nbsp;행렬)&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$x_{c,s}$&lt;/span&gt; : 특징이 추출된 후 &lt;span style=&quot;color: #ee2323;&quot;&gt;c&lt;/span&gt;ontent, &lt;span style=&quot;color: #ee2323;&quot;&gt;s&lt;/span&gt;peaker 를 나타낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;Encoder&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1192&quot; data-origin-height=&quot;339&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZX2wx/btsFcjGDMRv/xCXkIpwUE7mM2e2b1nFGC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZX2wx/btsFcjGDMRv/xCXkIpwUE7mM2e2b1nFGC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZX2wx/btsFcjGDMRv/xCXkIpwUE7mM2e2b1nFGC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZX2wx%2FbtsFcjGDMRv%2FxCXkIpwUE7mM2e2b1nFGC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;228&quot; data-origin-width=&quot;1192&quot; data-origin-height=&quot;339&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;encoder 에서 각 encoder layer 는 convolution block 과 인스턴스 정규화로 구성되며, speaker encoder 에만 speaker attention 이 적용된다. 추가로 convolution block 은 kernel size - 3, stride - 1 인 두 개의 convolution layer 를 포함하는 residual block 으로 설계되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;Bottleneck Layer&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1192&quot; data-origin-height=&quot;339&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcZjAu/btsFdD5MrpP/SGALm6yNAhEmKCJTjmfkJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcZjAu/btsFdD5MrpP/SGALm6yNAhEmKCJTjmfkJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcZjAu/btsFdD5MrpP/SGALm6yNAhEmKCJTjmfkJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcZjAu%2FbtsFdD5MrpP%2FSGALm6yNAhEmKCJTjmfkJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;228&quot; data-origin-width=&quot;1192&quot; data-origin-height=&quot;339&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;병목계층&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(bottlenect layer)&lt;/span&gt;는 인코더 프로세스 이후에 source speaker $x_{f0} \in \mathbb{R}^{T}$의 f0 pitch 를 표현하는데 사용된다. 만약 $x_c^{'} \in \mathbb{R}^{C \times T}$ 가 content encoder 의 출력이라고 할 때, $x_c^{'}$ 와 $x_{f0}$ 사이에 연결된 출력들이 GRU 계층에 들어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더하여 decoder 이전에 DuAN&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Dual Adaptive Normalization)&lt;/span&gt; 을 콘텐츠 및 스피커 표현들에 적용함으로서 초기 변환 표현이 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;Decoder&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1192&quot; data-origin-height=&quot;339&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOfBHb/btsFdn261Bq/YA7o6riiebzmMGm6wA39Ak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOfBHb/btsFdn261Bq/YA7o6riiebzmMGm6wA39Ak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOfBHb/btsFdn261Bq/YA7o6riiebzmMGm6wA39Ak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOfBHb%2FbtsFdn261Bq%2FYA7o6riiebzmMGm6wA39Ak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;228&quot; data-origin-width=&quot;1192&quot; data-origin-height=&quot;339&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 decoder layer 는 encoder 가 가진 conv block 과 동일하게 conv block 을 가지고, TriAAN Block 을 포함한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TriAAN Block 은 이전 layer 의 content feature 를 사용하여 변환을 수행하고, speaker encoder 계층으로부터 수집된 feature map 을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종적으로 docder 의 출력은 GRU 계층과 PostNet 에 의해 정제되어 log mel-spectrogram 을 예측한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;추가로 아래서는 해당 모델의 핵심적인 부분인 Speaker Attention 과 TriAAN block 에 대해 간단히 설명한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;2-1. Speaker Attention&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AdaIN을 TIN&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Time-wise IN)&lt;/span&gt; 으로 개선하고 TIN 기반 SA&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Speaker Attention)&lt;/span&gt; 을 설계하였다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(AdaIN의 핵심적인 부분인 인스턴스 정규화(IN)을 시간 차원 정규화(TIN)으로 수정.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TIN 의 경우 IN 과 달리 시간별로 평균 및 표준 편차로 정규화 되어 채널 관계를 보존할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&amp;nbsp;\begin{flalign} &lt;br /&gt;Q=TIN(x_s)W_q,\quad&amp;nbsp;K=x_sW_k,\quad&amp;nbsp;V=x_s&amp;nbsp;W_v&amp;nbsp;\\ &lt;br /&gt;Attention(Q,K,V) = softmax(QK^\top / \sqrt{d})V \\ &lt;br /&gt;\end{flalign} &lt;br /&gt;$$&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$x_s \in \mathbb{R}^{T \times C}$&lt;/span&gt; : 화자 특징&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$W_{q, k, v} \in \mathbb{R}^{C \times C}$&lt;/span&gt; : 가중치&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(SA 도 Attention 이므로 Q, K, V 가 사용된다.)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 Speaker Attention 은 쿼리정보를 Time-wise IN&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(TIN)&lt;/span&gt;의 결과로 사용하여, Speaker Attention&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(SA)&lt;/span&gt;를 통해 확대하고 변환에 사용된 스피커 특성의 채널 관계를 강조하고 보존한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;2-2. TriAAN block&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1192&quot; data-origin-height=&quot;339&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOfBHb/btsFdn261Bq/YA7o6riiebzmMGm6wA39Ak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOfBHb/btsFdn261Bq/YA7o6riiebzmMGm6wA39Ak/img.png&quot; data-alt=&quot;Decoder&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOfBHb/btsFdn261Bq/YA7o6riiebzmMGm6wA39Ak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOfBHb%2FbtsFdn261Bq%2FYA7o6riiebzmMGm6wA39Ak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;228&quot; data-origin-width=&quot;1192&quot; data-origin-height=&quot;339&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Decoder&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;decoder 내부에 존재하는 TriAAN Block 의 구조는 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1109&quot; data-origin-height=&quot;591&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Tswjk/btsFf2jo6QZ/wn1PGsSycNI6Ac6Ut9lBS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Tswjk/btsFf2jo6QZ/wn1PGsSycNI6Ac6Ut9lBS0/img.png&quot; data-alt=&quot;그림 2. TriAAN Block 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Tswjk/btsFf2jo6QZ/wn1PGsSycNI6Ac6Ut9lBS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTswjk%2FbtsFf2jo6QZ%2Fwn1PGsSycNI6Ac6Ut9lBS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;320&quot; data-origin-width=&quot;1109&quot; data-origin-height=&quot;591&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 2. TriAAN Block 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TriAAN Block 은 DuAN 과 GLAN 으로 구성되어 있다. 해당 블록은 각 $I$번째 speaker encoder layer 에서 수집된 feature map 을 사용하며, DuAN 은 이중 뷰&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(time, channel)&lt;/span&gt; $F_s^l$&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(speaker s의 l번째 레이어에서 추출한 특성 맵)&lt;/span&gt; 에서 layer 별 세부 speaker 특징을 추출하고 적응형 정규화를 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 DuAN 은 이미지 스타일 전송에서 adaptive attention normalization 에서 영감을 받아 제작한 것으로, layer 별 화자 특징 $F_s^l$ 에 대한 통계를 만들어 낸다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(attention 기반) &lt;/span&gt;이 때 지나치게 세부적인 화자의 특징으로 편향된 결과를 방지하기 위한 기법들 역시 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 GLAN 은 speaker encoder 의 모든&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($F_s^{1:L}$)&lt;/span&gt; feature map 을 사용하여 global speaker 정보를 추출한다. 이는 추측하기론, 하나의 특정한 스피커 뿐만 아니라, 다양한 스피커들에 공통적으로 적용될 수 있는 목소리 특징을 포괄적으로 파악하는 것이라 생각한다. 이를 통해 특정 speaker 의 목소리 변환 뿐만 아니라, 보다 범용적인 다양한 speaker 에 적용 가능한 목소리 변환 모델 구축이 가능해 진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외에도 논문 2,3 페이지에서는 DuAN과 GLAN의 동작 원리를 상세하게 설명하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.&amp;nbsp;EXPERIMENTS&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-1. Experimental setup&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;dataset&lt;/span&gt; : VCTK&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;train, validation, test&lt;/span&gt; : 6:2:2&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변환 시나리오는 20명의 speaker 를 선택하고 See-to-Seen&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(S2S)&lt;/span&gt; Unseen-to-Unseen&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(U2U)&lt;/span&gt; 시나리오당 600쌍을 생성한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Seen-to-Seen&lt;/span&gt; : 모델은 훈련 과정에서 두 스피커의 목소리를 모두 접했기 때문에 변환을 비교적 쉽게 수행할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Unseen-to-Unseen&lt;/span&gt; : 모델은 훈련 과정에서 변환 대상인 두 스피커의 목소리를 전혀 접해보지 않은 상태이기에, 변환의 난이도가 매우 높다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오디오 샘플링은 16kHz, 25ms 의 프레임 크기, 10ms 의 홉 크기, 80멜빈을 기반으로 한 CPC, f0, mel-spectrogram feature 를 추출한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;훈련 세부사항
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;batch size&lt;/span&gt; : 64&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;epoch&lt;/span&gt; : 400&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;optimizer&lt;/span&gt; : Adam&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;learning rate&lt;/span&gt; : $10^{-5}$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;모델 파라미터
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$H$&lt;/span&gt; : 256&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$C$&lt;/span&gt; : 512&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$L$&lt;/span&gt; : 6&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 log mel-spectrogram 을 waveform 으로 변환하기 위해 VCTC 데이터 세트에서 사전 훈련된 parallel WaveGAN vocoder 를 사용한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-2. Evaluation metrics&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 논문에서는 평가를 위해 objective&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(객관적인)&lt;/span&gt; 방식과 subjective&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(주관적인)&lt;/span&gt; 방법을 모두 사용한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;objective 한 방법으로는 WER와 CER을 통해 테스트한다. pre-trained 된 wav2vec 2.0 을 사용한다고 하는걸 보니, VC한 결과를 ASR 을 통해 다시 체크하는 방식이며, 화자 검증 모델&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Speaker Verification)&lt;/span&gt; 에 기반하여 자체적인 합격률을 계산한다. 합격률은 변환된 음성과 target 음성간의 코사인 유사성, SV모델에 의해 추출된 임계값, VCTK 데이터 세트의 동일한 오류율을 기반으로 계산된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1751&quot; data-origin-height=&quot;458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rrcZS/btsFdHucCnK/gkbOEGtp6lTcaU8WwDREs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rrcZS/btsFdHucCnK/gkbOEGtp6lTcaU8WwDREs0/img.png&quot; data-alt=&quot;표 1. 샘플당 하나의 목표 발화를 사용하는 any-to-any의 one-shot 변환을 위한 VCTK 데이터 세트에 대한 객관적인 평가 결과. SV는 데이터 세트에서 동일한 오류율에 의해 결정된 임계값 이상의 수락율을 나타낸다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rrcZS/btsFdHucCnK/gkbOEGtp6lTcaU8WwDREs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrrcZS%2FbtsFdHucCnK%2FgkbOEGtp6lTcaU8WwDREs0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;209&quot; data-origin-width=&quot;1751&quot; data-origin-height=&quot;458&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 1. 샘플당 하나의 목표 발화를 사용하는 any-to-any의 one-shot 변환을 위한 VCTK 데이터 세트에 대한 객관적인 평가 결과. SV는 데이터 세트에서 동일한 오류율에 의해 결정된 임계값 이상의 수락율을 나타낸다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;subjective 한 방법에서는 자연스러움, 유사성에 대해서 MOS 테스트를 실시한다. S2S 및 U2U 에 대해 무작위로 선택된 20쌍의 발화를 사용하여 테스트한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;858&quot; data-origin-height=&quot;386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q3HMs/btsFgqdJGi0/GCk9kY6q4GCtYeYzFU8OAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q3HMs/btsFgqdJGi0/GCk9kY6q4GCtYeYzFU8OAK/img.png&quot; data-alt=&quot;그림 3. MOS는 자연스러움과 유사성에 대해 95% 신뢰 구간을 갖는 결과이다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q3HMs/btsFgqdJGi0/GCk9kY6q4GCtYeYzFU8OAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq3HMs%2FbtsFgqdJGi0%2FGCk9kY6q4GCtYeYzFU8OAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;270&quot; data-origin-width=&quot;858&quot; data-origin-height=&quot;386&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 3. MOS는 자연스러움과 유사성에 대해 95% 신뢰 구간을 갖는 결과이다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MOS 기준 자연스러움 - 3.45, 유사도 - 4.16 이라는 뛰어난 지표를 보여준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객관적인 평가 방법에서도 기존 모델들 대비해서 많은 성능 향상을 보여준다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1020&quot; data-origin-height=&quot;507&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yPv5N/btsFgLoDKdx/9vhvmU8guYxmHOu0K8tTBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yPv5N/btsFgLoDKdx/9vhvmU8guYxmHOu0K8tTBk/img.png&quot; data-alt=&quot;표 2. 절제 연구 및 다중 발화 시나리오의 결과. $\dagger$는 샴 손실이 없는 TriAAN-VC를 나타낸다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yPv5N/btsFgLoDKdx/9vhvmU8guYxmHOu0K8tTBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyPv5N%2FbtsFgLoDKdx%2F9vhvmU8guYxmHOu0K8tTBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;298&quot; data-origin-width=&quot;1020&quot; data-origin-height=&quot;507&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 2. 절제 연구 및 다중 발화 시나리오의 결과. $\dagger$는 샴 손실이 없는 TriAAN-VC를 나타낸다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 제공된 표 2 에서는 샴 손실이 얼마나 영향을 미치는지 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4. 실제 모델 테스트 및 느낀점.&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;전반적인 테스트 결과는 아래와 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;한국어 기준이던, 영어 기준이던 미리 준비된 Vocoder 와 CPC 를 사용하는것 만으로 우수한 변환 성능을 보여준다. 하지만 기본적으로 '잡음 저항' 이 낮다. 한국어나 영어 음성 데이터를 제공하는 AI Hub, common-voice 데이터셋에는 가정 내 IOT 기기들로 녹음되어 제공된 음성들이 다수 존재하여 잡음이 섞인 경우가 잦다.&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;해당하는 데이터셋에서 잡음이 없고, 상대적으로 깔끔한 음성들은 성공적으로 변환되나, 그렇지 못한 음성들은 잘 변환되지 못하는 경향을 보여준다. 여기서 잡음은 정말 사람이 듣지 못할정도의 심각한 잡음이 아니라, 상대적으로 작은 노이즈,&amp;nbsp; 음성이 다소 불분명하게 들리는 특정구간에 해당된다. 이는 이 모델의 가장 치명적인 문제점이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;결국 현실적으로 충분히 사용할만 하지만, target 데이터의 잡음 여부에 매우 민감하기 때문에 신중히 데이터를 선정할 필요성이 있겠다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;위에서 저자들이 제시한 MOS, WER, CER 지표도 잡음이 거의 완벽에 가깝게 제거된 데이터로부터 나오는 지표이다.&lt;/p&gt;</description>
      <category>Artificial Intelligence/Paper Review</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/177</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-TRIAAN-VC#entry177comment</comments>
      <pubDate>Fri, 23 Feb 2024 19:52:46 +0900</pubDate>
    </item>
    <item>
      <title>[리뷰] HiFi-VC: High Quality ASR-Based Voice Conversion</title>
      <link>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-HiFi-VC-High-Quality-ASR-Based-Voice-Conversion</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/pdf/2203.16937.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;해당 논문&lt;/a&gt;은 Voice Conversion 모델중 하나인 HiFi-VC 를 제안하는 논문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HiFi-GAN 을 기반으로 제작된 이 모델은 이전에 리뷰한 StarGANv2-VC 와 다르게 any-to-any 가 가능하다. m&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;any-to-many 의 경우 반드시 학습된 음성만 Target 으로 둘 수 있다.&lt;/span&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(학습되지 않은 target 으로 변환할 경우 품질이 심각하게 저하된다.)&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt; 반면&lt;/span&gt; any-to-any 의 경우 훈련중 학습되지 않은 '모든' 화자로의 음성 변환을 목적으로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 &lt;span style=&quot;text-align: start;&quot;&gt;any-to-any&lt;/span&gt; 는 모델 학습적인 관점에서 many-to-many 보다 어렵지만 실제로 사용할 때는 더 유용하게 사용할 수 있다. Hifi-VC 모델은 이러한 any-to-any 가 가능한 모델로서 활용성이 높다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Introduce&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VC 의 경우 텍스트 정보와 운율을 유지하면서 한 화자의 음성을 다른 화자의 음성으로 변환한다. VC를 구현하는 가장 간단한 방법은 ASR과 TTS를 결합하는 것이다. 그러나 이러한 접근 방식을 사용하면 텍스트 병목 현상이 발생하여 &lt;span style=&quot;color: #f89009;&quot;&gt;운율에 대한 중요한 정보를 잃을 수 있다&lt;/span&gt;. 이러한 문제를 해결하기 위해 여러&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(entertainment, speakingaid systems, data augmentation, &lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://www.media.mit.edu/projects/voice-anonymization/overview/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;anonymization&lt;/a&gt;)&lt;/span&gt; 특수한 VC 알고리즘들이 제안되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt; * 병목 특징(bottlenect feature)&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;: ASR, VC 과정 중간에, 다양한 음향학적, 언어학적 특징을 추출하는 여러 겹의 신경망 계층들이 존재한다. 병목 특징은 이런 계층들에서 추출한 표현으로, 상대적으로 작은 크기&lt;/span&gt;(차원)를 가지면서 원래 음성의 중요한 정보가 압축되어 있다. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;430&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhtR6C/btsE4ZUYNMi/mrNYUmufgDk0Fh8mqEju51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhtR6C/btsE4ZUYNMi/mrNYUmufgDk0Fh8mqEju51/img.png&quot; data-alt=&quot;그림 1: HiFi-VC 추론 파이프라인. encoding를 위해 pre-trained된 ASR bottlenect features와 pitch tracker를 사용한다. decoder와 vocoder는 스피커 embedding에 대한 추가 조건으로 단일 HiFi GAN-like 모델에 결합된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhtR6C/btsE4ZUYNMi/mrNYUmufgDk0Fh8mqEju51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhtR6C%2FbtsE4ZUYNMi%2FmrNYUmufgDk0Fh8mqEju51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;430&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;430&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 1: HiFi-VC 추론 파이프라인. encoding를 위해 pre-trained된 ASR bottlenect features와 pitch tracker를 사용한다. decoder와 vocoder는 스피커 embedding에 대한 추가 조건으로 단일 HiFi GAN-like 모델에 결합된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 지난 10년간 TTS와 VC를 포함해서 여러 음성 합성 방법서 상당한 진전이 존재했다. 대부분의 작업은 세 단계로 음성 변환을 수행한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;입력 샘플에서 콘텐츠 및 speaker feature 를 추출한다&lt;/li&gt;
&lt;li&gt;추출한 정보들로 spectrogram 을 생성한다.&lt;/li&gt;
&lt;li&gt;vocoder 를 통해 파형&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(waveform)&lt;/span&gt; 으로 변환한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 여러 모델에서 neural waveform encoders 와 decoders 를 사용하며, 일부 방법들은 input coding&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(입력 음성 신호를 특정 표현(features)으로 변환하는 과정)&lt;/span&gt; 을 위해 voice pitch feature 및 ASR 기능을 적용하며&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(StarGANv2-VC)&lt;/span&gt;. 많은 접근 방식들이 GAN을 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적인 접근 방법들은 단일, 또는 다수의 미리 정의된 화자들의 음성을 단일 대상 화자의 음성으로 변환한다. 화자 세트에서 음성을 변환할 수 있는, 소위 Many-to-Many 방법들을 사용한다. 그러나 이러한 방법들은 미리 준비된 음성 세트를 예측하는데는 탁월하나, 훈련에 포함되지 않은 음성을 변환할 수 없다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(낮은 품질로 생성은 가능하다. 저자들도 생성은 가능하다고 명시 해 뒀는데, 사실 아무 의미 없는 수준이다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 VC에 대한 가장 실용적인 방법은 훈련데이터 세트에 포함되지 않은 임의의 음성으로 변환하는 것이다. 이 접근법은 any-to-any 또는 zero-shot 음성 변환이라고 지칭한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 해당 논문에서는 아래와 같은 사항을 이야기한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;text-align: start;&quot;&gt;논문에선 중간 feature에서 waveform을 직접 예측할 수 있는 새로운 조건부 GAN 아키텍처를 제안한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;text-align: start;&quot;&gt;논문에선 ASR 기반 콘텐츠 인코딩의 아이디어를 GAN 생성 접근 방식과 결합하여 고품질의 any-to-any VC를 달성한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;text-align: start;&quot;&gt;논문에선 객관적인 평가를 사용하여 제안된 방법을 비교한다. 실험에 따르면, 제안된 방법은 더 높은 음성 품질과 유사성&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(target)&lt;/span&gt; 을 달성한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; 2. Related Works&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해당 섹터에서 VC 에 관해 전반적으로 유용한 많은 정보가 기재되어 있기에, 생략을 최소화 하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1710&quot; data-origin-height=&quot;583&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc68kl/btsE42jVceF/dreZrwz7Pm8MZP1sWcaAe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc68kl/btsE42jVceF/dreZrwz7Pm8MZP1sWcaAe1/img.png&quot; data-alt=&quot;그림 2: HiFi-VC training pipeline. output waveform은 소스 샘플의 언어(linguistic) 정보와 운율(prosody)을 기준 음색(timbre) 정보와 결합한다 ASR 모델은 언어 encoder로 사용되고 pitch encoder는 운율 정보를 제공한다. content encoder에 사용되는 pre-trained된 ASR 모델은 훈련 중에 freezed 된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc68kl/btsE42jVceF/dreZrwz7Pm8MZP1sWcaAe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbc68kl%2FbtsE42jVceF%2FdreZrwz7Pm8MZP1sWcaAe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;273&quot; data-origin-width=&quot;1710&quot; data-origin-height=&quot;583&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 2: HiFi-VC training pipeline. output waveform은 소스 샘플의 언어(linguistic) 정보와 운율(prosody)을 기준 음색(timbre) 정보와 결합한다 ASR 모델은 언어 encoder로 사용되고 pitch encoder는 운율 정보를 제공한다. content encoder에 사용되는 pre-trained된 ASR 모델은 훈련 중에 freezed 된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;음성 특징을 변경하려면 source sample 에서 &lt;span style=&quot;color: #f89009;&quot;&gt;화자에 구애받지 않는&lt;/span&gt; 콘텐츠 정보를 추출할 필요가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 방법들은 auto-encoder, variational auto-encoder 등을 기반으로 하고, 병목 계층을 사용하여 잠재 공간에서 화자정보를 제거하는 방식을 사용하기도 하며&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(&lt;span style=&quot;color: #9d9d9d; text-align: start;&quot;&gt;병목계층을 거치며 &lt;/span&gt;운율 데이터가 사라지는 문제가 있지만, 화자 정보를 분리할 수 있다는 장점이 있다)&lt;/span&gt;, 여기서 화자와 콘텐츠의 특징 분리를 개선하기 위해 추가적인 normalization layers를 추가하는 등 여러 방법을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 많은 방법들은 ASR 모델을 사용한다. 일부는 언어 정보를 주출하기 위해 ASR을 통해 음소 확률을 적용하는 반면, 일부는 병목 특징을 활용한다. 병목 특징을 활용하는 방법의 경우&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;병목 특징이 소스 화자에 대한 정보를 거의 포함하지 않는다는 것이 경험적으로 관찰되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;ASR의 또 다른 사용은 변환 중 언어 정보의 손실을 최소화하는 훈련 목표를 설계하는 것이다. ASR 기반 정보추출의 한 가지 단점은 운율 특징을 인코딩할 수 없는 ASR의 무능력이다&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(당연히 content 정보 뽑을려고 쓰는거니 운율은 인코딩 못한다.)&lt;/span&gt; &lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;이 문제를 처리하기 위해 소스 샘플에서 F0 를 추출한다. 화자 정보는 일반적으로 정규화&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(&lt;span style=&quot;text-align: start;&quot;&gt;normalization)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;에 의해 F0에서 제거된다.&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(왜 StarGANv2-VC 에서 추가적인 ASR 모델과 F0 모델이 필요한지 알 수 있다.)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;저자들의&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt; 방법은 &lt;a href=&quot;https://arxiv.org/abs/1904.08983&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;TTS Skins&lt;/a&gt;와 유사한 ASR 및 F0 인코더를 사용하며, F0는 &lt;a href=&quot;https://arxiv.org/pdf/2009.02725.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;BNE-Seq2seqMoL&lt;/a&gt;에서와 유사한 네트워크에 의해 추가로 전처리된다.&lt;/span&gt; &lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;콘텐츠 및 스피커 특징이 주어지면 대부분의 다른 방법들은 예측을 디코더와 보코더의 두 단계로 분해한다. &lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;디코더의 목표는 출력 신호의 mel-spectrogram 을 예측하는 것인 반면 보코더는 예측된 spectrogram을 출력 파형으로 변환한다. 디코더는 RNN, Transformer 또는 FCN&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(fully convolution architecture)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;을 통해 구현될 수 있다. 인기 있는 보코더에는 STRAIT, Griffin-Lim 및 WaveGlow 및 HiFi-GAN과 같은 신경망 모델이 포함된다. 신경 접근 방식으로 더 나은 품질을 달성하려면 디코더 훈련 후에 추가 보코더 미세 조정 단계가 필요하다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;text-align: start;&quot;&gt;반면 HiFi-GAN 은 디코더만 사용한다. ASR 및 GAN 기반의&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt; 다른 모델과는 달리 중간 mel-spectrogram 예측 단계를 피하고 인코딩된 특징에서 직접 파형을 생성&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;한다. 이러한 방법은 스피커 임베딩이 음성 변환에 영향을 미치는 방식이 다르다. 대부분의 다른 모델에서는 speaker 임베딩이 spectrogram 예측을 위해 decoder에 사용된다. 하지만&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;저자들의 방식은 생성 중에 스피커 임베딩으로 GAN 잔차 블록을 직접 조절한다. 이러한 접근 방식은 별도의 보코더를 제외하고 변환 파이프라인을 단순화한다. &lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;따라서 이러한 방법은 디코더 훈련 후 보코더 미세 조정 단계가 필요하지 않다.&lt;/span&gt; &lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;VCRSS 및 NVC-Net과 같은 일부 이전 모델들도 별도의 보코더 사용을 피한다. 다만 해당 논문에선 VCRSS와 달리 더 나은 파형 예측을 위해 GAN 디코더를 사용한다. 이러한 저자들의 접근 방식은 ASR 인코더와 다른 GAN 아키텍처를 사용하기 때문에 NVC-Net과도 다르다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Proposed Method&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;430&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhtR6C/btsE4ZUYNMi/mrNYUmufgDk0Fh8mqEju51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhtR6C/btsE4ZUYNMi/mrNYUmufgDk0Fh8mqEju51/img.png&quot; data-alt=&quot;그림 1: HiFi-VC 추론 파이프라인. encoding를 위해 pre-trained된 ASR bottlenect features와 pitch tracker를 사용한다. decoder와 vocoder는 스피커 embedding에 대한 추가 조건으로 단일 HiFi GAN-like 모델에 결합된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhtR6C/btsE4ZUYNMi/mrNYUmufgDk0Fh8mqEju51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhtR6C%2FbtsE4ZUYNMi%2FmrNYUmufgDk0Fh8mqEju51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;430&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;430&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 1: HiFi-VC 추론 파이프라인. encoding를 위해 pre-trained된 ASR bottlenect features와 pitch tracker를 사용한다. decoder와 vocoder는 스피커 embedding에 대한 추가 조건으로 단일 HiFi GAN-like 모델에 결합된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국, 저자들이 제안하는 방식인 HiFi-VC 는 위의 그림 1과 같이 추가적인 화자의 embedder 가 있는 encoder-decoder 아키텍처를 기반으로 한다. 이러한 접근 방식은 TTS Skins, NVC-Net, BNE-Seq2seqMoL 에 영감을 받았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3-1. Model Architecture.&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1710&quot; data-origin-height=&quot;583&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc68kl/btsE42jVceF/dreZrwz7Pm8MZP1sWcaAe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc68kl/btsE42jVceF/dreZrwz7Pm8MZP1sWcaAe1/img.png&quot; data-alt=&quot;그림 2: HiFi-VC training pipeline. output waveform은 소스 샘플의 언어(linguistic) 정보와 운율(prosody)을 기준 음색(timbre) 정보와 결합한다 ASR 모델은 언어 encoder로 사용되고 pitch encoder는 운율 정보를 제공한다. content encoder에 사용되는 pre-trained된 ASR 모델은 훈련 중에 freezed 된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc68kl/btsE42jVceF/dreZrwz7Pm8MZP1sWcaAe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbc68kl%2FbtsE42jVceF%2FdreZrwz7Pm8MZP1sWcaAe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;273&quot; data-origin-width=&quot;1710&quot; data-origin-height=&quot;583&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 2: HiFi-VC training pipeline. output waveform은 소스 샘플의 언어(linguistic) 정보와 운율(prosody)을 기준 음색(timbre) 정보와 결합한다 ASR 모델은 언어 encoder로 사용되고 pitch encoder는 운율 정보를 제공한다. content encoder에 사용되는 pre-trained된 ASR 모델은 훈련 중에 freezed 된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델 아키텍쳐는 4가지로 요약할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Linguistic encoder&lt;/span&gt;&amp;nbsp;: 해당 인코더의 목표는 Source 음성 샘플로부터 Speaker 에 구애받지 않는 content 정보를 추출하는 것이다. 이를 위해 ASR 모델의 병목 현상을 활용하므로, TTS Skins 의 접근방식을 기반으로 한다. 최종적으로, &lt;a href=&quot;https://catalog.ngc.nvidia.com/orgs/nvidia/teams/nemo/models/stt_en_conformer_ctc_large_ls&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;NVIDIA 에서 제공해 주는&lt;/a&gt; Pre-trained 된 Conformer 모델&lt;span style=&quot;color: #9d9d9d; text-align: left;&quot;&gt;(Conformer-CTC)&lt;/span&gt; 을 사용한다. 이렇게 사전 학습된 ASR을 사용하면 ASR의 표현이 특정 VC 데이터 세트와 독립적이기 때문에 학습속도를 높일 수 있을 뿐만 아니라, 일반화도 개선할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;F0 encoder&lt;/span&gt; : 결국 '언어&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Linguistic)&lt;/span&gt; 인코더' 는 ASR 역할을 수행한다. 위에서도 언급했듯 이러한 ASR 은 Content 정보는 잘 뽑아내지만 운율을 포착 하는데에는 문제가 있다. 이러한 한계를 극복하기 위해 &lt;span style=&quot;text-align: start;&quot;&gt;BNE-Seq2seqMoL any-to-many 접근법과 유사한 F0 예측기를 추가한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Speaker embedder&lt;/span&gt; : any-to-any VC 작업은 speaker embedder 네트워크를 사용해야 한다. 이러한 speaker embedder 는 5개의 layer 의 residual fully-connected network 를 사용하여 오디오 샘플에서 화자&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;의 특징 벡터 분포를 예측한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Decoder&lt;/span&gt; : 저자들이 제안한 Decoder 방식은 GAN 기반 방식을 확장한다. 기존에 다른 방법들에서 사용하는 방법은, 최종 디코딩을 위한 보코더로 HiFi-GAN 을 확장해서 사용한다.&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(보코더의 목표는 mel-spectrogram 을 waveform 으로 변환하는 것)&lt;/span&gt;.&lt;/span&gt; 즉 이전 방식에선 디코딩을 위한 보코더가 따로 있고 보코더에서 나온 출력물을 가지고 Decoding 하는 Decoder가 따로 존재했었다는 것이다. 하지만 HiFi-VC 에서는 이러한 모듈을 '하나의 모듈' 로 결합한다. 때문의 그림 2 를 보면 별도의 Vocoder 가 존재하지 않는 모습을 살펴볼 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3-2. Training Objectives&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;훈련중에는 ASR 모델을 동결하고&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(아마 pre-trained 를 무조건 사용하는 형태의 설계일듯)&lt;/span&gt;, &lt;/span&gt;F0 encoder, speaker embedder, decoder network 및 GAN discriminator 를 동시에 최적화한다. 이를 HiFi-GAN과 NVC-Net의 speaker embedder 정규화&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #9d9d9d; text-align: left;&quot;&gt;(&lt;/span&gt;&lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://realblack0.github.io/2020/03/29/normalization-standardization-regularization.html&quot;&gt;regularization&lt;/a&gt;&lt;span style=&quot;color: #9d9d9d; text-align: left;&quot;&gt;)&lt;/span&gt;&lt;/span&gt; 손실을 결합하여 수행한다. 결국 이러한 방법을 사용했을 때 중간 mel-spectrogram 표현을 사용하지 않는다!&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(spectrogram 과 mel-spectrogram 은 &lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://ahnjg.tistory.com/93&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;다르다&lt;/a&gt;!) &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;834&quot; data-origin-height=&quot;260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqBjEG/btsE6HfFy7e/H6U2zIMAZXQt0Jg26rbR90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqBjEG/btsE6HfFy7e/H6U2zIMAZXQt0Jg26rbR90/img.png&quot; data-alt=&quot;TTS 의 예제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqBjEG/btsE6HfFy7e/H6U2zIMAZXQt0Jg26rbR90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqBjEG%2FbtsE6HfFy7e%2FH6U2zIMAZXQt0Jg26rbR90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;249&quot; data-origin-width=&quot;834&quot; data-origin-height=&quot;260&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;TTS 의 예제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래 TTS 던 STT 건 보통 encoder-decoder 구조로 구성되어 있다. 위의 이미지는 TTS의 예제인데, 중간에 mel-spectrogram 표현을 vocoder 측에서 입력으로 받는 모습을 확인할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;STT 도 마찬가지로 encoder 에서 mel-spectrogram 형태의 출력값을 내보내고, 이를 decoder 에서 받아 최종적인 text 로 출력하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마찬가지로 VC도 같은 매커니즘을 이용하기에 왠만한 모델들이 중간형태인 mel-spectrogram 을 만들어 처리한다. 하지만 저자들이 제안한 HiFi-VC 는 vocoder 와 decoder 를 합쳐 decoder 로 통합했기 때문에 이러한 mel-spectrogram 이 필요가 없다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이미지를 함께 보면서 세부 손실 함수 항목들에 관해서 파악해 보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1710&quot; data-origin-height=&quot;583&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc68kl/btsE42jVceF/dreZrwz7Pm8MZP1sWcaAe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc68kl/btsE42jVceF/dreZrwz7Pm8MZP1sWcaAe1/img.png&quot; data-alt=&quot;그림 2: HiFi-VC training pipeline. output waveform은 소스 샘플의 언어(linguistic) 정보와 운율(prosody)을 기준 음색(timbre) 정보와 결합한다 ASR 모델은 언어 encoder로 사용되고 pitch encoder는 운율 정보를 제공한다. content encoder에 사용되는 pre-trained된 ASR 모델은 훈련 중에 freezed 된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc68kl/btsE42jVceF/dreZrwz7Pm8MZP1sWcaAe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbc68kl%2FbtsE42jVceF%2FdreZrwz7Pm8MZP1sWcaAe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;273&quot; data-origin-width=&quot;1710&quot; data-origin-height=&quot;583&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 2: HiFi-VC training pipeline. output waveform은 소스 샘플의 언어(linguistic) 정보와 운율(prosody)을 기준 음색(timbre) 정보와 결합한다 ASR 모델은 언어 encoder로 사용되고 pitch encoder는 운율 정보를 제공한다. content encoder에 사용되는 pre-trained된 ASR 모델은 훈련 중에 freezed 된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;본래의 HiFi-GAN 과는 달리, 예측된 음성 샘플의 spectrogram 간 reconstruction loss 를 계산한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\mathcal{L}_{Rec} = ||\mathbf{M}_{source} - \mathbf{M}_{pred}||_1$$&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$||...||_1$&lt;/span&gt;: L1 Norm&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Manhattan distance)&lt;/span&gt;을 의미. 벡터의 각 요소 간 절댓값 차이의 합을 계산.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$M_{source}$&lt;/span&gt; : 원본 음성의 spectrogram&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$M_{pred}$&lt;/span&gt; : 예측&amp;nbsp;음성의 spectrogram.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;HiFi-GAN 은 GAN 인 만큼 적대적 손실을 사용하여 예측 파형&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(HiFi-GAN 이 생성한 waveform)&lt;/span&gt;을 자연 파형&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(인간이 녹음한 waveform)&lt;/span&gt;과 구분할 수 없게 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;예측 변수 최적화에 사용되는 손실은 아래와 같이 정의된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;$$\mathcal{L}_{AdbP}(s) = (D(s)-1)^2$$&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$s$&lt;/span&gt; : 예측파형&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(예측된 waveform)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$x$&lt;/span&gt; : 자연파형&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(실제 인간의 waveform)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$D$&lt;/span&gt; : 판별 네트워크&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$D(s)$&lt;/span&gt; :판별자의 출력이기도 하며, 파형 $s$ 를 판별자가 평가한 값이다.&lt;/li&gt;
&lt;li&gt;\mathcal{L}_{AdbP}(s) 가 1에 가깝다면 생성된 데이터, 0에 가깝다면 진짜 데이터로 판단한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과정을 정리해 보면&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;판별자 $D$는 예측된 음성파형 $s$를 입력으로 받는다.&lt;/li&gt;
&lt;li&gt;판별자 $D$는 해당 파형이 진짜인지 가짜인지 판단해서 확률값을 출력한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($D(s)$)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;예측기는 이 $D(s)$ 값이 커지도록&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(즉, 실제 데이터로 판단되도록)&lt;/span&gt; 한다.&lt;/li&gt;
&lt;li&gt;수식에서 $(D(s) -1)^2$ 를 계산하기에 $D(s)$ 는 1에 가까울수록 adversarial loss 는 최소화된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Discriminator 최적화를 위한 손실은 아래와 같이 정의된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;$$\mathcal{L}_{AdbD}(s, x) = (D(x)-1)^2 + (D(s))^2$$&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;과정을 정리하면&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;첫 번째 항 $(D(x) - 1)^2$&lt;/span&gt; : 자연 파형 'x' 에 대한 판별 오류를 나타낸다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;$D(x)$ 가 1에 가까울수록&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(판별자가 'x' 를 진짜라고 판단할수록)&lt;/span&gt; 이 항은 0에 가까워진다.&lt;/li&gt;
&lt;li&gt;$D(x)$ 가 1에서 멀어질수록&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(판별자가 'x'를 진짜라고 판단하지 못할수록)&lt;/span&gt; 이 항은 커진다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;두 번째 항 $(D(s))^2$&lt;/span&gt; : 예측 파형 's' 에 대한 판별 오류를 나타낸다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;$D(s)$가 0에 가까울수록&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(즉, 판별자가 's'를 가짜라고 판단할수록)&lt;/span&gt; 이 항은 0에 가까워진다.&lt;/li&gt;
&lt;li&gt;$D(s)$가 0에서 멀어질수록&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(즉, 판별자가 's'를 진짜라고 판단할수록)&lt;/span&gt; 이 항은 커진다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;두 항을 더하여 Discriminator의 최적화 목표를 정의한다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Discriminator는 자연 파형 'x'를 가능한 한 진짜라고 판단하고&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(첫 번째 항 최소화)&lt;/span&gt; &lt;br /&gt;예측 파형 's'를 가능한 한 가짜라고 판단하도록 학습된다&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(두 번째 항 최소화).&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;결과적으로, Discriminator는 자연 파형과 예측 파형을 효과적으로 구별하는 능력을 향상시키게 된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;더하여 GAN 에 대한 훈련은 feature matching loss 를 통해서 안정화 할 수 있다&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(GAN은 훈련이 불안정하다.)&lt;/span&gt; $i$번째 Discriminator layer 의 출력을 $Ni$ 차원 백터 $Di$ 라고 가정하면 아래와 같이 계산할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;$$\mathcal{L}_{FM}(s, x) = \sum_{i=1}^T{1 \over N_i} || D_i(x) - D_i(s) ||_1$$&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;위에서 NVC-Net 의 손실을 결합하여 사용한다고 언급했었다. 이와 유사하게 speaker embedding 정규화&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(&lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://realblack0.github.io/2020/03/29/normalization-standardization-regularization.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;regularization&lt;/a&gt;)&lt;/span&gt;손실도 존재한다. reference record $r$ 이 있다고 가정하고, 임베딩에 의해 예측된 평균 및 대각 공분산 행렬을 $\mu(r)$ 및 $\sum(r)$ 로 정의하면 정규화 손실은 아래와 같이 정의될 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;$$\mathcal{L}_{Spk}(r)=D_{KL}(\mathcal{N}(x;\mu(r), \sum(r) || \mathcal{N}(x;0,I))$$&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;최종적으로, $\mathcal{L}_P$ 의 최종손실은 위의 모든 손실을 더하면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;$$\mathcal{L_P} = \lambda_{Rec}\mathcal{L}_{Rec} + \lambda_{AdbP}\mathcal{L}_{AdbP} + \lambda_{FM}\mathcal{L}_{FM} + \lambda_ {Spk}\mathcal{L}_{Spk}$$&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;$\lambda$&lt;/span&gt; : 각 손실값을 조정하는 hyper-parameter.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자들은 $\lambda$ 값으로 $\lambda_{Rec} = 45$, $\lambda_{AdvP}=1$, $\lambda_{FM} = 1$, $ \lambda_{Spk} = 0.01$ 을 사용하였다고 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;3-3. Implementation&amp;nbsp;Details&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 섹터에서는 여러 구현하는데에 있어 부가적인 내용들을 설명하고 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;훈련중 모든 음성 샘플은 24kHz 로 변환된다.&lt;/li&gt;
&lt;li&gt;ASR은 40ms 주기로 특징을 생성한다.&lt;/li&gt;
&lt;li&gt;F0 예측기는 10ms 마다 특징을 생성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;등등 세부적인 여러 내용에 대해서 이야기하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.&amp;nbsp;Experiments&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;a href=&quot;https://paint-kitten-d96.notion.site/HiFi-VC-demo-samples-2fbe30b894a64f7fa8bccb96f8d09540&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;해당 링크&lt;/a&gt;에서 HiFi-VC 의 성능을 체험해 볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;185&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUdmRX/btsE0hW1aVc/is2sLPotDUU0A4o2AgfI2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUdmRX/btsE0hW1aVc/is2sLPotDUU0A4o2AgfI2K/img.png&quot; data-alt=&quot;표 1: many-to-many 음성 품질 및 유사성은 제안된 방법 및 기준선에 대한 의견 점수(MOS)를 의미한다. &amp;quot;F&amp;quot; 및 &amp;quot;M&amp;quot;은 소스 및 참조 음성의 서로 다른 성별 조합에 해당한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUdmRX/btsE0hW1aVc/is2sLPotDUU0A4o2AgfI2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUdmRX%2FbtsE0hW1aVc%2Fis2sLPotDUU0A4o2AgfI2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;196&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;185&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 1: many-to-many 음성 품질 및 유사성은 제안된 방법 및 기준선에 대한 의견 점수(MOS)를 의미한다. &quot;F&quot; 및 &quot;M&quot;은 소스 및 참조 음성의 서로 다른 성별 조합에 해당한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 다른 방법들 대비 높은 점수를 보여준다. 하지만 나는 HiFi-GAN 의 핵심은 any-to-any 라고 생각해서 사실 many-to-many 방법에 관해서는 큰 관심이 없다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ptJif/btsE0gX1NM7/3EZEoSLsZfEC7VcPUkwHmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ptJif/btsE0gX1NM7/3EZEoSLsZfEC7VcPUkwHmK/img.png&quot; data-alt=&quot;표 2: many-to-many WER, CER, PCC 지표&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ptJif/btsE0gX1NM7/3EZEoSLsZfEC7VcPUkwHmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FptJif%2FbtsE0gX1NM7%2F3EZEoSLsZfEC7VcPUkwHmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;452&quot; height=&quot;162&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 2: many-to-many WER, CER, PCC 지표&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 asr 을 통해서 생성된 음성의 정확도를 평가하는데, 다른 방법들 대비해서 월등히 높은 지표를 보여준다. asr의 경우 훈련용도로 사용된 pre-trained conformer-ctc 가 아닌 다른 asr 을 사용하였다고 하는데 뭘 사용했는지는 자세히 적혀있지 않다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1137&quot; data-origin-height=&quot;287&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfgBGs/btsE9ZT2OeZ/LSH1vj6u07JzKkjAnr4P90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfgBGs/btsE9ZT2OeZ/LSH1vj6u07JzKkjAnr4P90/img.png&quot; data-alt=&quot;표 3: 제안된 방법 및 기준선에 대한 Any-to-Any의 음성 품질 및 유사성 평균 의견 점수(MOS). &amp;quot;F&amp;quot; 및 &amp;quot;M&amp;quot;은 소스 및 참조 음성의 서로 다른 성별 조합에 해당한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfgBGs/btsE9ZT2OeZ/LSH1vj6u07JzKkjAnr4P90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfgBGs%2FbtsE9ZT2OeZ%2FLSH1vj6u07JzKkjAnr4P90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;202&quot; data-origin-width=&quot;1137&quot; data-origin-height=&quot;287&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 3: 제안된 방법 및 기준선에 대한 Any-to-Any의 음성 품질 및 유사성 평균 의견 점수(MOS). &quot;F&quot; 및 &quot;M&quot;은 소스 및 참조 음성의 서로 다른 성별 조합에 해당한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여담으로 many-to-many 부분에서 좀 이상한게, StarGANv2-VC 에 대한 비교표를 왜 작성하지 않았을까... 생각 해 보면 아마 StarGANv2-VC 의 성능이 더 우수해서 그렇지 않을까? 하는 의심이 든다. &lt;a href=&quot;https://paint-kitten-d96.notion.site/HiFi-VC-demo-samples-2fbe30b894a64f7fa8bccb96f8d09540&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;데모&amp;nbsp;링크&lt;/a&gt;에 가면 StarGANv2-VC 에 대해서 테스트를 진행한 흔적이 보이지만 위 결과표에는 포함되어 있지 않은걸로 봐서는 아마 저자들이 원하는 결과가 도출되지 않아서 StarGANv2-VC 를 배제 하였다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. Conclusion.&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매우 고무적인 성능을 보여준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 한국어 VC 기준, 내장되어 있는 Linguistic&amp;nbsp;encoder,&amp;nbsp;F0&amp;nbsp;encoder가 영어에 맞게끔 훈련되어 있기에 VC 작업을 진행하면 마치 외국인이 이야기 하는것 처럼 말투 자체가 변해버린다. 영어와 영어간 변환을 수행하면 상당히 비슷하지만, 그래도 many-to-many 방식인 StarGANv2-VC 만 못한것이 사실이다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(물론 StarGANv2-VC 는 any-to-any 가 불가하다는 결함이 있다) &lt;/span&gt;데모에서는 상대적으로 StarGANv2-VC 가 더 안좋게 들리나, 실제 결과가 그렇다면 표 1에 결과를 첨부하지 않을 이유가 없었을 텐데 넣지 않은 이유가 있을것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 나는 Linguistic encoder, &lt;span style=&quot;text-align: start;&quot;&gt;F0 encoder 를&lt;/span&gt; 한국어용으로 변경해서 테스트 해 보려 하였으나, 아쉽게도 학습에 관련된 소스코드가 공개되어 있지 않아서 이미 완성된 모델을 사용만 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로, 나는 HiFi-VC 를 매우 우수한 성능을 지닌 모델이라고 인식하며, 추가로 학습시간도 합리적이라고 생각한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(저자들의 학습시간은 단일 GPU로 70분씩 120 epoch)&lt;/span&gt; 한번 직접 학습시켜보고 이것 저것 커스텀 해 사용해 보고 싶었는데 아쉬운 상황이다. github 를 뒤져보니 어떤 서약 때문에 훈련모델을 공개하지 못하는 듯 하다.&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Artificial Intelligence/Paper Review</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/176</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-HiFi-VC-High-Quality-ASR-Based-Voice-Conversion#entry176comment</comments>
      <pubDate>Tue, 20 Feb 2024 15:21:09 +0900</pubDate>
    </item>
    <item>
      <title>[리뷰] Low-resource expressive text-to-speech using data augmentation</title>
      <link>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-Low-resource-expressive-text-to-speech-using-data-augmentation</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/pdf/2011.05707.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;해당&lt;/a&gt; &lt;a href=&quot;https://ieeexplore.ieee.org/document/9413466&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;논문&lt;/a&gt;은&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;진행중인 연구와 매우 밀접한 연관이 존재하여 읽게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Amazon Alexa 팀에서 2021년 발표한 논문으로 Voice Conversion 을 통해 Data Augmentation 하여 TTS 를 제작, 데이터 부족 환경에서 VC로 생성된 데이터가 유용하게 사용될 수 있다고 가능성을 보여준 논문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 요약&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근의 Text To Speech&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(TTS)&lt;/span&gt; 시스템은 매우 잘 작동하지만, 원하는 발화 스타일로 TTS 하려면 상당한 양의 녹음이 필요하다. 해당 논문에서는 불과 15분의 녹음으로 표현 스타일 음성을 구축하기 위해 새로운 3단계 방법론을 제시한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;다른 화자의 원하는 발화 스타일의 녹음을 사용하여 Voice Conversion 을 적용해 Data augment 한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(합성 데이터)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;제작한 합성 데이터를 사용하여 TTS 모델을 훈련한다.&lt;/li&gt;
&lt;li&gt;품질을 더욱 높이기 위해 해당 모델을 미세 조정한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평가 결과, 제안된 방법을 적용할 시 합성 음성의 여러 측면에서 증강되지 않은 모델에 비해 상당한 개선을 가져오는 것으로 확인되었다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 소개&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근의 TTS 시스템으로 생성된 음성은 매우 자연스럽고, 음성의 품질 역시 향상되었지만, Tacotron 과 같은 모델들은 최소 10시간의 label-voice 쌍을 필요로 한다. 이러한 데이터를 수집하는 것은 비용적으로 큰 부담이 되는 작업이기에 대안이 필요하다. &lt;br /&gt;&lt;br /&gt;문제를 해결하기 위해 저자원 TTS 에 초점을 맞춘 여러 연구는 다중 화자 모델링과 전이 학습을 통하여 제한된 데이터의 영향을 완화하려고 하였다. 이러한 방법으로 시스템의 품질을 향상시킬 수 있었지만, 부족한 데이터 문제를 해결하기 위한 유일한 방법은 아니다. &lt;br /&gt;&lt;br /&gt;데이터&amp;nbsp;증강은&amp;nbsp;앞서&amp;nbsp;언급한&amp;nbsp;문제를&amp;nbsp;극복하기&amp;nbsp;위해&amp;nbsp;기계&amp;nbsp;학습의&amp;nbsp;여러&amp;nbsp;분야에&amp;nbsp;걸쳐&amp;nbsp;사용되어&amp;nbsp;왔다.&amp;nbsp;특히&amp;nbsp;컴퓨터&amp;nbsp;비전에서&amp;nbsp;더&amp;nbsp;나은&amp;nbsp;모델을&amp;nbsp;훈련하기&amp;nbsp;위해&amp;nbsp;합성&amp;nbsp;데이터를&amp;nbsp;만드는&amp;nbsp;것이&amp;nbsp;철저하게&amp;nbsp;조사되었으며,&amp;nbsp;이와&amp;nbsp;더불어&amp;nbsp;음성&amp;nbsp;분야,&amp;nbsp;특히&amp;nbsp;자동&amp;nbsp;음성&amp;nbsp;인식&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(ASR)&amp;nbsp;&lt;/span&gt;분야에서도&amp;nbsp;연구되어&amp;nbsp;왔다.&amp;nbsp;그러나&amp;nbsp;합성&amp;nbsp;음성&amp;nbsp;데이터를&amp;nbsp;만들기&amp;nbsp;위해&amp;nbsp;수많은&amp;nbsp;연구가&amp;nbsp;진행되었음에도&amp;nbsp;불구하고,&amp;nbsp;비표현&amp;nbsp;TTS&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(감정이나&amp;nbsp;톤&amp;nbsp;강세&amp;nbsp;등이&amp;nbsp;없는)&lt;/span&gt;&amp;nbsp;최종&amp;nbsp;목표에만&amp;nbsp;활용하는&amp;nbsp;것으로&amp;nbsp;보인다. &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;multi-speaker TTS 모델을 훈련시키고 이를 특정 target-speaker 에 대한 합성 데이터를 생성하는데에 사용하며, 이 합성 데이터를 다시 새로운 target-speaker TTS 모델을 훈련시키는데 사용&lt;/span&gt;한다. 이는 리소스가 적은 multi-speaker 모델이 target-speaker 에 대한 음성을 합성할 수 있다고 가정한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(여기서 target-speaker 는 목표로 하는 화자의 목소리, 아마도 single-speaker 를 의미한다.)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;multi-speaker TTS 훈련 &amp;rarr; target-speaker 합성 데이터 생성 &amp;rarr; 새로운 target-speaker TTS 모델 훈련&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;결론적으로 target-speaker 에 대한 데이터가 매우 부족한 상황&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(10min, 기존에는 10hour)&lt;/span&gt; 을 타파할 수 있는 새로운 3단계 방법론을 제시한다. 아래 Result 단에서는 이러한 방법론으로 생성된 데이터를, 직접 청취자들에게 평가받아 그 성능을 평가받는다.&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 방법론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제안된 방법론은 3단계로 구성된다.&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;VC 모델을 활용하여 합성 데이터를 생성한다.&lt;/li&gt;
&lt;li&gt;새로 생성된 합성 데이터를 대상 화자 녹음과 함께 사용하여 최첨단 TTS 모델을 훈련한다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;TTS 모델의 미세 조정을 수행하여 더 높은 품질을 달성한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제&amp;nbsp;이러한&amp;nbsp;단계를&amp;nbsp;더&amp;nbsp;자세히&amp;nbsp;설명한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3-1.&amp;nbsp;Data augmentation &lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;681&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMWaM7/btsE0G1Er3U/mbiz3hqY9k7k29XvUDVebk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMWaM7/btsE0G1Er3U/mbiz3hqY9k7k29XvUDVebk/img.png&quot; data-alt=&quot;그림 1. VC 모델(Copycat) 아키텍처&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMWaM7/btsE0G1Er3U/mbiz3hqY9k7k29XvUDVebk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMWaM7%2FbtsE0G1Er3U%2Fmbiz3hqY9k7k29XvUDVebk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;515&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;681&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 1. VC 모델(Copycat) 아키텍처&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자들은 합성 데이터를 만들기 위해 Copycat 모델을 VC 모델로 활용한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(즉, VC로 Data Augmentation)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 모델은 세분화된 운율 전달 모델로, 화자 신원을 변환하면서 소스 오디오에서 운율과 언어, 콘텐츠를 유지하는 것을 목표로 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델은 간단히 아래와 같이 3가지 요소로 구성된다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;text-align: start;&quot;&gt;음소의 잠재 임베딩을 학습하는 음소 인코더&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(phoneme encoder)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;text-align: start;&quot;&gt;멜-스펙트럼에서 운율 표현을 분리하는 운율 병목 인코더&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(prosody bottlenect encoder)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;text-align: start;&quot;&gt;음소 임베딩, 운율 표현 및 제공된 화자 임베딩이 주어지면 멜-스펙트럼을 생성하는 병렬 디코더&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(parallel decoder)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;결과를 음소 인코더로 전달하기 전에 스피커 임베딩을 업샘플링된 음소에 연결하여 모델에 한 가지 수정 사항을 가한다. 이는 Speaker ID&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(개별 화자를 구분하기 위한 ID)&lt;/span&gt;에 따라 음소를 인코딩하는 데 도움이 되며, 따라서 VC 프로세스에 도움이 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;VC 모델은 하나 이상의 소스 스피커와 대상 스피커에 대해 훈련되어, $X$ 스타일의 표현 샘플을 소스 스피커 $S$에서 대상 스피커 $T$로 변환할 수 있다. 샘플은 녹음만큼 완벽하지는 않지만 여전히 우수한 품질이며 더 나은 TTS 모델을 훈련하는 데 도움이 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3-2. TTS Model&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;924&quot; data-origin-height=&quot;734&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kxkil/btsEXr5X6yC/OgsUrPjxGeEnKDte3jsmuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kxkil/btsEXr5X6yC/OgsUrPjxGeEnKDte3jsmuK/img.png&quot; data-alt=&quot;그림 2. TTS 모델 아키텍처&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kxkil/btsEXr5X6yC/OgsUrPjxGeEnKDte3jsmuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fkxkil%2FbtsEXr5X6yC%2FOgsUrPjxGeEnKDte3jsmuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;635&quot; data-origin-width=&quot;924&quot; data-origin-height=&quot;734&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 2. TTS 모델 아키텍처&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자들의 TTS 시스템은 운율 캡쳐를 위해 VAE가 있는 Tacotron 과 같은 구조를 기반으로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 시나리오에서 견고하게 운용하도록 multi-style single-speaker 혹은 single-style multi-speaker 모델을 훈련한다. 후자의 모델을 훈련할 때, decoder 수준에서 미리 훈련된 speaker embedding 을 추가시킨다&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(이미지 하단)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. Result&lt;/b&gt;&lt;/h2&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평가 전반에 걸쳐 모델을 평가하기 위한 4가지 지표에 중점을 둔다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;신호 품질&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(샘플의 신호 품질은 얼마나 좋은가?)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;스타일 적절성&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(샘플이 원하는 스타일과 일치하는가?)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;자연스러움&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(샘플이 자연스럽게 들리는가?)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;화자 유사성&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(샘플이 대상 화자와 유사한가?)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 TTS 는 Speech 된 결과를 평가해야 한다. 저자들은 이를 청취자들에게 샘플을 제공하는 방식으로 테스트 하였다고 한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(MUSHRA 테스트)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뉴스 캐스터 데이터는 200개의 테스트 샘플을 확보하였고, 이를 테스트하기 위해 200명의 테스터를 모집하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대화형의 경우 8개의 대상 화자의 50개 테스트 발화가 평가되며, 크라우드 소싱 플랫폼을 통해서 테스트 하였다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;273&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HgCya/btsEZSha3kJ/17W8M6YTTYKlekR8jlqTk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HgCya/btsEZSha3kJ/17W8M6YTTYKlekR8jlqTk1/img.png&quot; data-alt=&quot;표 2. 2명의 여성 speaker 를 대상으로 한 single-speaker 환경에서 신호 품질과 스타일 적합성 모두에서 평균 + 95%의 CI MUSHRA 점수를 보여주는 VC 데이터 사용 및 미세 조정에 대한 절제 연구. 밑줄 친 값은 (B)와 (B + VC + FT) 간의 통계적 차이를 의미한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HgCya/btsEZSha3kJ/17W8M6YTTYKlekR8jlqTk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHgCya%2FbtsEZSha3kJ%2F17W8M6YTTYKlekR8jlqTk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;229&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;273&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 2. 2명의 여성 speaker 를 대상으로 한 single-speaker 환경에서 신호 품질과 스타일 적합성 모두에서 평균 + 95%의 CI MUSHRA 점수를 보여주는 VC 데이터 사용 및 미세 조정에 대한 절제 연구. 밑줄 친 값은 (B)와 (B + VC + FT) 간의 통계적 차이를 의미한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;VC : Voice Conversion.&lt;/li&gt;
&lt;li&gt;FT : Fine Tuning&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재미있는 점은 단순히 Base 데이터셋에 Fine-Tuning 만을 수행하였을 때 보다 Voice Conversion 을 통해서 데이터를 보강 하였을 때 더 높은 수준의 TTS 제작이 가능 하였다는 점이다. 여기에 두가지 방법을 결합 하였을 때 가장 좋은 점수를 보여준다는 것을 표 2 에서 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 저자들은 이러한 방법론이 데이터 양에 어떻게 영향을 받는지 비교하기 위해 데이터 축소&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(DR)&lt;/span&gt; 비 데이터 축소&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(NDR)&lt;/span&gt; 시나리오 간의 추가적인 평가를 진행하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자들이 작업 전에 추측하기론, DR은 NDR 대비 더 적은 데이터에 대해 훈련되기에 성능이 떨어질것으로 추측한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 결과를 살펴보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;484&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PcXyD/btsE0sCyM6P/aH2JoLh8CPxMrRqMKfsYI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PcXyD/btsE0sCyM6P/aH2JoLh8CPxMrRqMKfsYI1/img.png&quot; data-alt=&quot;표 3. single-speaker 설정에서 신호 품질과 스타일 적정성에 대한 평균 MUSHRA 점수로, 서로 다른 데이터 감소 시나리오와 2명의 여성 스피커에 대한 방법론(DR + VC + FT)의 성능을 보여준다. 밑줄 친 값은 (DR)과 (DR + VC + FT) 사이의 통계적 차이를 의미한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PcXyD/btsE0sCyM6P/aH2JoLh8CPxMrRqMKfsYI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPcXyD%2FbtsE0sCyM6P%2FaH2JoLh8CPxMrRqMKfsYI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;433&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;484&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 3. single-speaker 설정에서 신호 품질과 스타일 적정성에 대한 평균 MUSHRA 점수로, 서로 다른 데이터 감소 시나리오와 2명의 여성 스피커에 대한 방법론(DR + VC + FT)의 성능을 보여준다. 밑줄 친 값은 (DR)과 (DR + VC + FT) 사이의 통계적 차이를 의미한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Recs : speaker 의 원본 녹음본 (뉴스캐스터) 이므로, 사실상 해당 점수가 '만점' 으로 볼 수 있다.&lt;/li&gt;
&lt;li&gt;NDR : Recs 로 학습시킨 TTS 모델&lt;/li&gt;
&lt;li&gt;DR : 더 적은 데이터로 훈련시킨 TTS 모델&lt;/li&gt;
&lt;li&gt;Neutral : 중립적인 감정의 데이터로만 훈련시킨 TTS 모델&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 위 표에서는 DR+VC+FT 의 성능이 DR 보다 훨신 우수함을 나타낸다. 이는 꽤 중요한 증명 과정인데, VC 라는 AI를 통해 생성해 낸 데이터로 &amp;rarr; 다른 AI 를 학습시켰을 때 성능이 증가될 수 있음을 보여주었기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 저자들은 robustness&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(모델이 변화하는 환경에 강건하게 작동하는 능력)&lt;/span&gt; 한지 보기 위해 테스트를 진행하였다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;541&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vkURZ/btsEZaoVihB/PuHEfJuz2n8qvNvrKK9fP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vkURZ/btsEZaoVihB/PuHEfJuz2n8qvNvrKK9fP0/img.png&quot; data-alt=&quot;표 4. multi-speaker 설정에서 자연스러움과 화자 유사성에 대한 평균 + 95% CI MUSHRA 점수로, 다양한 데이터 감소 시나리오와 8명의 speaker(남성과 여성으로 균등하게 구분)에 대한 방법론(DR + V C + FT)의 성능을 보여준다. 밑줄 친 값은 (NDR)과 (DR + VC + FT) 간의 통계적 차이를 의미한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vkURZ/btsEZaoVihB/PuHEfJuz2n8qvNvrKK9fP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvkURZ%2FbtsEZaoVihB%2FPuHEfJuz2n8qvNvrKK9fP0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;482&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;541&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 4. multi-speaker 설정에서 자연스러움과 화자 유사성에 대한 평균 + 95% CI MUSHRA 점수로, 다양한 데이터 감소 시나리오와 8명의 speaker(남성과 여성으로 균등하게 구분)에 대한 방법론(DR + V C + FT)의 성능을 보여준다. 밑줄 친 값은 (NDR)과 (DR + VC + FT) 간의 통계적 차이를 의미한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 데이터가 '감소' 되었을때 효과를 비교할 수 있다. 여기서 좀 의아한 부분이 존재하는데, 결국 30min 의 데이터만 선택하다는데, 어떤 방식으로 선택하였는지 구체적으로 기재되어 있지 않다. 만약 3가지 실험 모델이 모두 동일한&amp;nbsp; 30min 데이터로 학습되어 의미가 없을수도 있는것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 느낀점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 뭐 아마존 팀에서 작성한 논문이니 의미가 없으리라 생각되지는 않지만, 논문에 몇몇 있어야될 정보가 존재하지 않는다는 느낌을 받는다. 특히 VC 기술을 사용했다고 하면서, 구체적으로 '얼마만큼의 데이터를 VC 했다' 라고 기재한 부분이 존재하지 않다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(사기업인 만큼 추상적으로 작성한 느낌이다)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어쨋든 해당 논문으로 알게 된 점은, TTS 영역에서 데이터가 부족할 시 'VC + FT' 를 통해서 처리할 수 있다는 점이다&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(사실 위에서 사용한 Copycat 모델이나, TTS 구조는 별로 궁금하지 않다... Data Augmentation 할 수 있는 모델은 많이 존재하고 내 관심사는 TTS가 아닌 STT 이기 때문이다.)&lt;/span&gt; 이는 고무적인 점으로, 음성쪽에서는 잘 준비된 데이터가 부족한 경향이 있다. 하지만 VC를 잘 이용해 데이터를 증강한다면 이러한 문제를 해결할 수 있다는 가능성을 보여준 논문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 음성 데이터가 이미지 데이터보다 더 낮은 정밀도를 요구한다는 점으로 인해 발생한 장점이라고 추측된다. 이미지 데이터의 경우 어느 한 지점에 작은 오류가 있어도 쓰지 못하게 되는 경우가 많다. 예로 '강아지' 를 그리라고 했는데, 눈동자가 '고양이' 눈동자라면 이를 다시 학습용 데이터로 사용하기에 문제가 될 것이며, 많은 경우 특정 영역의 노이즈가 발생하면 아예 쓰지 못하게 되는경우도 흔하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 VC로 생성된 음성 데이터의 경우 실제 발화 구간에 어느정도 노이즈가 발생하더라도 이를 데이터로 사용할 수 있을 정도이다. 사람이 듣기에 큰 이질감을 느끼지 못하는 노이즈가 대다수이기 때문이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;물론 이러한 추측성 주장은 어디까지나 나의 경험적인 근거에 의한 추측이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;해당 논문의 의의는 생각보다 클 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;AI 모델을 통해 생성해낸 데이터를 &amp;rarr; 다시 AI 학습용으로 썻는데 성능이 올라가네? 라는 논리가 성립하기 때문이다. 아무쪼록 Voice 관련 AI 가 많이 발전해서 빠르게 자비스를 쓸 수 있게 될 날이 오기만을 고대하는 바이다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(물론 자비스는 단순 Voice AI 는 아니긴 하지만 뭐... 최종 테크는 결국 그쪽으로 수렴하지 않을까? ㅋㅋ..)&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Artificial Intelligence/Paper Review</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/175</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-Low-resource-expressive-text-to-speech-using-data-augmentation#entry175comment</comments>
      <pubDate>Sun, 18 Feb 2024 13:02:53 +0900</pubDate>
    </item>
    <item>
      <title>[리뷰] Make-A-Voice</title>
      <link>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-Make-A-Voice</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/pdf/2305.19269.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Make-A-Voice 논문&lt;/a&gt;에 관해 간단히 분석하는 포스팅이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해당 논문에 대한 몇몇 리뷰는 &lt;a href=&quot;https://openreview.net/forum?id=eGdhD93hZr&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;openreview.net&lt;/a&gt; 에서 확인 해 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해당 리뷰들을 참고하며 개인 의견 몇가지를 이야기하고자 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 소개&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;음성합성은 인간의 음성을 생성하는 것을 목표로 하며, &lt;/span&gt;&lt;span&gt;특히 제로샷 성능을 향상시키기 위해서 수많은 데이터를 기반으로 인간의 음성 다양성을 캡처&lt;span&gt;, &lt;/span&gt;표현을 예측하는 방법이 많이 개발되었다&lt;span&gt;. &lt;/span&gt;하지만 이러한 방법들은 &lt;/span&gt;&lt;span&gt;&amp;lsquo;&lt;/span&gt;&lt;span&gt;음성 생성&lt;/span&gt;&lt;span&gt;&amp;rsquo;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;이라는 공통 목표를 둠에도 불구하고 독립적으로 개발되었다&lt;span&gt;. &lt;/span&gt;때문에 각 애플리케이션에 대해 개발된 방법론은 여전히 &lt;/span&gt;&lt;span&gt;&amp;lsquo;&lt;/span&gt;&lt;span&gt;독립적&lt;/span&gt;&lt;span&gt;&amp;rsquo;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;이며&lt;span&gt;, &lt;/span&gt;별도로 각 모델을 최적화해야 하기에 비 효율적이다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;이 논문은 뭔가 새로운 모델을 제시하지는 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;결국 Make-A-Voice 라는 통합된 음성합성 프레임워크를 제안하는데 핵심 개념은 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;'coarse-to-fine' 기법을 사용한다. 해당 기법은 'coarse&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(거친, 굵은)&lt;/span&gt;' 값을 토대로, 더 의미있는 값&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(fine)&lt;/span&gt; 을 선택하는 최적화 방식의 일종이다. 좀 더 쉽게 설명하면, 우선 대분류를 고른뒤 &amp;rarr; 소분류를 선택하는 방식이라고 보면 된다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 아래와 같은 결과를 달성했다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;음성 및 노래 음성 합성을 위해 자기 지도 데이터를 활용하여 확장성을 향상시켰다&lt;/li&gt;
&lt;li&gt;실험 결과는 Make-A-Voice가 스타일 유사성과 &lt;a href=&quot;https://www.sciencedirect.com/topics/computer-science/perceptual-quality#:~:text=Perceptual%20quality%3A%20A%20measure%20of,Compression%20(Second%20Edition)%2C%202021&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;perceptual quality&lt;/a&gt; 측면에서 최첨단 결과를 달성했다는 것을 보여준다. Make-A-Voice는 &lt;a href=&quot;https://blog.naver.com/qbxlvnf11/221529266739&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;discrete representations&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(이산 표현)&lt;/span&gt;&lt;/a&gt; 을 사용하여 데이터 확장성, 제어 가능성 및 조건 유연성에서 뛰어나다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 논문의 저자들은 여러가지 광범위한 조사를 수행한듯 하다. 기본적인 Tacotron, FastSpeech 는 물론이고, GenerSpeech, YourSpeech 등 내가 잘 모르는 모델들도 논문 내에서 이야기한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더하여 결국 몇몇 구문들을 읽어보면 논문 저자들이 해당 모델로 최종적으로 하고 싶은것은 TTS&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Text To Speech)&lt;/span&gt;, VC&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Voice Conversion)&lt;/span&gt;, SVS&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Singing Voice Synthesis)&lt;/span&gt; 등을 공유하는 한가지의 프레임워크를 제작하는 것임을 알 수 있고, 그것이 바로 Make-A-Voice 인 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 구조&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1091&quot; data-origin-height=&quot;304&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cypxOa/btsETYBcCIo/mqfKDDR0dRQxzpJXKpe5EK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cypxOa/btsETYBcCIo/mqfKDDR0dRQxzpJXKpe5EK/img.png&quot; data-alt=&quot;그림 1: Make-A-Voice의 개요 점선으로 표시된 F0 보조 입력은 노래하는 음성(SVS) 합성에만 포함된.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cypxOa/btsETYBcCIo/mqfKDDR0dRQxzpJXKpe5EK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcypxOa%2FbtsETYBcCIo%2FmqfKDDR0dRQxzpJXKpe5EK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;223&quot; data-origin-width=&quot;1091&quot; data-origin-height=&quot;304&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 1: Make-A-Voice의 개요 점선으로 표시된 F0 보조 입력은 노래하는 음성(SVS) 합성에만 포함된.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Stage 를 보면 결국 크게 3가지로 구분된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$S_1$ : Semantic Stage 로 Speech, Text&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Label)&lt;/span&gt; 을 받아 Semantic Tokens 로 출력한다.&lt;/li&gt;
&lt;li&gt;$S_2$ : Acoustic Stage 로 Speaker Prompt 와 선택적으로 F0 Prompt 를 입력받아 Acoustic Tokens 로 출력한다.&lt;/li&gt;
&lt;li&gt;$S_3$ : Generation Stage 로 실질적으로 음성을 생성한다. F0 Excitation 은 선택적으로 입력받는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 음성 합성 프레임워크를 discrete representations 와 공유함으로서 TTS의 경우 Text Input 이 자동회귀적&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(autoregressively)&lt;/span&gt; 으로 Semantic Tokens 로 변환된다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(이는 자동적으로 이전 단계의 결과를 기반으로, 다음 단계를 생성하거나 변환한다는 것을 의미한다.)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이후에 $S_2$에서 Speaker Prompt&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(음성 데이터가 아닌, 화자에 대한 추가적인 정보들.)&lt;/span&gt; 가 주어지면 이를 Acoustic Token 으로 변환된다. 이때, 하려는 작업이 VC인지, SVS 인지에 따라서 과정이 달라진다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;VC일 경우 HuBERT 모델에 의해 Semantic Tokens 으로 토큰화 된 다음, Speaker Prompt 가 주어지면 Acousctic Tokens 로 변환된다.&lt;/li&gt;
&lt;li&gt;SVS 일 경우 Semantic Tokens 가 TTS로 자동회귀적&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Transformer)&lt;/span&gt;으로 생성된 후, 화자와 F0 프롬프트가 주어지면 Acoustic 토큰이 생성된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-1. Semantic Tokens&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;314&quot; data-origin-height=&quot;303&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQJJJO/btsETS9klOc/P6au0Zz0Xln17LSZvYg4qk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQJJJO/btsETS9klOc/P6au0Zz0Xln17LSZvYg4qk/img.png&quot; data-alt=&quot;그림 2: 이산 음성 표현(Discrete speech representations.)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQJJJO/btsETS9klOc/P6au0Zz0Xln17LSZvYg4qk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQJJJO%2FbtsETS9klOc%2FP6au0Zz0Xln17LSZvYg4qk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;386&quot; data-origin-width=&quot;314&quot; data-origin-height=&quot;303&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 2: 이산 음성 표현(Discrete speech representations.)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 언어에 대한 콘텐츠 정보를 제공하는데 HuBERT 가 효과적인 것으로 확인하였다고 한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(즉 HuBERT 로 Semantic tokens 을 제작)&lt;/span&gt; 라벨링되지 않은 음성에 대해 훈련된 HuBERT는 16kHz 로 샘플링된 음성을 20ms 마다 연속적인 표현으로 인코딩 하는 방식으로 작동된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2-2.&lt;span&gt; Acoustic&amp;nbsp;tokens&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;음향 코덱 모델은 일반적으로 audio encoder, residual vector-quantizer&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(RVQ)&lt;/span&gt;, audio decoder 로 구성되며, 결국 아래와 같은 과정을 따른다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(위의 그림 2 를 참고하며 보면 좋다.)&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;audio encoder $E$는 여러 convolution block 으로 구성되며, 16kHz 에서 20ms 보다 연속적인 표현을 생성한다.&lt;/li&gt;
&lt;li&gt;$RVQ$&lt;span style=&quot;color: #9d9d9d;&quot;&gt;($Q$라고도 지칭)&lt;/span&gt; 는 $K_2$ 크기의 코드북을 사용해 이산 표현 $a_q$ 를 생성한다.&lt;/li&gt;
&lt;li&gt;audio decoder $D$는 압축된 잠재 표현인 $a_q$ 로부터 신호 $\hat{y}$ 를 재구성한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2-3.&lt;span&gt;&lt;span&gt; 구조 요약&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외에도 논문에서는 $S_1, S_2, S_3$ 에 관해서 상세히 설명하고 있지만 요약하자면 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$S_1$ : 토큰화된 텍스트, 음성을 Semantic Tokens 로 매핑한다.&lt;/li&gt;
&lt;li&gt;$S_2$ : $S_1$ 에서 추출된 &lt;span style=&quot;text-align: left;&quot;&gt;Sementic Tokens 를 Acoustic Tokens 로 매핑한다.&lt;/span&gt;&lt;span style=&quot;text-align: left;&quot;&gt; 해당 부분에서 화자의 억양, 감정, 운율이나, 심지어 인구, 통계 등 각종 데이터를 이용해 zero-shot 의 견고성을 향상시킨다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;text-align: left;&quot;&gt;$S_3$ : $S_2$ 에서 추출된 정보로 최종적인 음성을 합성한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 과정을 통해서 위에서 언급한 VC, TTS, SVS 3가지를 수행할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1097&quot; data-origin-height=&quot;389&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8pjtn/btsEVJqBnx7/PerLgvTFKZ5kdPUk3EDTv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8pjtn/btsEVJqBnx7/PerLgvTFKZ5kdPUk3EDTv1/img.png&quot; data-alt=&quot;그림 3: 음성 합성 프레임워크를 시맨틱 및 음향 토큰과 공유하여 해결할 수 있는 음성 변환(VC), 텍스트 음성 변환(TTS), 노래 음성 합성(SVS) 등 세 가지 예시적인 애플리케이션을 소개합니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8pjtn/btsEVJqBnx7/PerLgvTFKZ5kdPUk3EDTv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8pjtn%2FbtsEVJqBnx7%2FPerLgvTFKZ5kdPUk3EDTv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;284&quot; data-origin-width=&quot;1097&quot; data-origin-height=&quot;389&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 3: 음성 합성 프레임워크를 시맨틱 및 음향 토큰과 공유하여 해결할 수 있는 음성 변환(VC), 텍스트 음성 변환(TTS), 노래 음성 합성(SVS) 등 세 가지 예시적인 애플리케이션을 소개합니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 과정에 대한 요약은 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;VC : speech sample 은 semantic tokens 로 토큰화 된 후, speaker prompt 가 주어딘 대상 스피커의 acoustic tokens 로 변환된다.&lt;/li&gt;
&lt;li&gt;TTS : 음소&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(phoneme)&lt;/span&gt; 시퀀스는 semantic tokens 로 변환되며 speaker prompt 정보를 토대로 acoustic tokens 로 변환된다.&lt;/li&gt;
&lt;li&gt;SVS : 음소&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(phoneme)&lt;/span&gt; 시퀀스는 semantic tokens 로 변환되며, F0 prompt&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(&lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://ko.wikipedia.org/wiki/MIDI&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MIDI&lt;/a&gt;)&lt;/span&gt;와 speaker prompt 가 주어지면 acoustic tokens 로 변환된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 결론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 저자들은 Make-A-Voice는 인간의 목소리를 모델링하기 위해 'coarse-to-fine' 기법을 사용하였다. &lt;span style=&quot;text-align: start;&quot;&gt;이는 모델이 음성 합성을 위해 의미론적 정보와 음향적 정보를 점진적으로 조합하고 활용하는 과정, 즉 &lt;a href=&quot;https://cypsw.tistory.com/entry/Make-A-Voice-Unified-Voice-Synthesis-With-Discrete-Representation-%EB%B6%84%EC%84%9D#2.%20%EA%B5%AC%EC%A1%B0-1&quot;&gt;위&lt;/a&gt;에서 말한 $S_1, S_2, S_3$ 과정을 의미한다고 추측한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터는 영어 기준 LibriLight 60,000 시간 데이터를 사용하였고, SVS 테스트 용으로 중국어 노래 OpenCPOP 에서 50시간 분량 데이터를 사용하였다고 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;759&quot; data-origin-height=&quot;412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pwMyy/btsETSn3hvU/FuhihaOemgqlcWLspBLNDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pwMyy/btsETSn3hvU/FuhihaOemgqlcWLspBLNDK/img.png&quot; data-alt=&quot;표 2 : zero-shot TTS 로 생성 된 샘플의 품질 및 스타일 유사성.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pwMyy/btsETSn3hvU/FuhihaOemgqlcWLspBLNDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpwMyy%2FbtsETSn3hvU%2FFuhihaOemgqlcWLspBLNDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;326&quot; data-origin-width=&quot;759&quot; data-origin-height=&quot;412&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 2 : zero-shot TTS 로 생성 된 샘플의 품질 및 스타일 유사성.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xI4SA/btsEWfQkm33/HJ78yDHPKZqqaqqvhAsPKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xI4SA/btsEWfQkm33/HJ78yDHPKZqqaqqvhAsPKk/img.png&quot; data-alt=&quot;표 3 : zero-shot VC 에서 생성 된 샘플의 품질 및 스타일 유사성.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xI4SA/btsEWfQkm33/HJ78yDHPKZqqaqqvhAsPKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxI4SA%2FbtsEWfQkm33%2FHJ78yDHPKZqqaqqvhAsPKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;232&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 3 : zero-shot VC 에서 생성 된 샘플의 품질 및 스타일 유사성.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;239&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ck98nQ/btsEQbbxSwe/h7ai8YQpVwIaKW2bHiyoH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ck98nQ/btsEQbbxSwe/h7ai8YQpVwIaKW2bHiyoH1/img.png&quot; data-alt=&quot;표 4 : zero-shot SVS 에서 생성 된 샘플의 품질 및 스타일 유사성.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ck98nQ/btsEQbbxSwe/h7ai8YQpVwIaKW2bHiyoH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fck98nQ%2FbtsEQbbxSwe%2Fh7ai8YQpVwIaKW2bHiyoH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;187&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;239&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 4 : zero-shot SVS 에서 생성 된 샘플의 품질 및 스타일 유사성.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종적인 결과를 보면 '마냥' 우수하진 않지만, 전반적으로 이전 방법들 대비 근소하게 높은 결과를 확인할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;참고로 MVoice 에 대한 성능은&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #0070d1; text-align: start;&quot; href=&quot;https://make-a-voice.github.io/&quot;&gt;해당 링크&lt;/a&gt;에서 체험해 볼 수 있다.&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 느낀점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 해당 모델을 직접적으로 테스트해 본 것이 아니기에, 전체적인 느낌은 정보가 좀 부족하다는 느낌이 든다. 위에서 언급한 &lt;a href=&quot;https://openreview.net/forum?id=eGdhD93hZr&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;다른 리뷰어들의 반응&lt;/a&gt;을 살펴봐도 대충 비슷한 느낌으로 장점과 단점을 이야기 하고 있다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(3가지 통합한건 뭐... 좋네, 근데 이거 증명이 좀 빈약한것 같네... 라는 느낌)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 논문을 보고 개인적으로 연구중인 과제에 대해서 TTS 를 고려해 볼만한 필요성을 느꼇다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Artificial Intelligence/Paper Review</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/174</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-Make-A-Voice#entry174comment</comments>
      <pubDate>Thu, 15 Feb 2024 15:26:55 +0900</pubDate>
    </item>
    <item>
      <title>Common Voice 데이터셋은 신뢰할 수 없다.</title>
      <link>https://cypsw.tistory.com/entry/Common-Voice-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%85%8B%EC%9D%80-%EC%8B%A0%EB%A2%B0%ED%95%A0-%EC%88%98-%EC%97%86%EB%8B%A4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;figure id=&quot;og_1706665642154&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;product&quot; data-og-title=&quot;Mozilla Common Voice&quot; data-og-description=&quot;&quot; data-og-host=&quot;commonvoice.mozilla.org&quot; data-og-source-url=&quot;https://commonvoice.mozilla.org/en/datasets&quot; data-og-url=&quot;https://commonvoice.mozilla.org/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/deydvO/hyVfZcjn94/69yEo6lI1H7AZdpTIxzX6K/img.jpg?width=1024&amp;amp;height=512&amp;amp;face=0_0_1024_512,https://scrap.kakaocdn.net/dn/eCyBE6/hyVb3OePIK/NH3Sed3Rfyuso0arU7Top0/img.jpg?width=2048&amp;amp;height=1024&amp;amp;face=0_0_2048_1024,https://scrap.kakaocdn.net/dn/ct7Loe/hyVfYLe4Be/n1lVYGDjzsXJfs8S5vdcNK/img.jpg?width=3072&amp;amp;height=1536&amp;amp;face=0_0_3072_1536&quot;&gt;&lt;a href=&quot;https://commonvoice.mozilla.org/en/datasets&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://commonvoice.mozilla.org/en/datasets&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/deydvO/hyVfZcjn94/69yEo6lI1H7AZdpTIxzX6K/img.jpg?width=1024&amp;amp;height=512&amp;amp;face=0_0_1024_512,https://scrap.kakaocdn.net/dn/eCyBE6/hyVb3OePIK/NH3Sed3Rfyuso0arU7Top0/img.jpg?width=2048&amp;amp;height=1024&amp;amp;face=0_0_2048_1024,https://scrap.kakaocdn.net/dn/ct7Loe/hyVfYLe4Be/n1lVYGDjzsXJfs8S5vdcNK/img.jpg?width=3072&amp;amp;height=1536&amp;amp;face=0_0_3072_1536');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Mozilla Common Voice&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;commonvoice.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Common Voice 데이터셋 + AI 모델로 여러 테스트를 거쳤는데&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;내가 원하는 방향의 결과가 나오지 않았고,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;어떤 문제 때문일까 고심하던 차에 데이터 표본 자체를 신뢰할 수 없겠다는 결론을 내렸다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;i&gt;그냥 원하는 결과 안나와서 땡깡부리는거 아니냐!&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;할 수 도 있겠지만 나름대로 근거가 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2554&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eUWraO/btsEdWdqWti/bU1ua3C7k3Jy9GqRrVFCk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eUWraO/btsEdWdqWti/bU1ua3C7k3Jy9GqRrVFCk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eUWraO/btsEdWdqWti/bU1ua3C7k3Jy9GqRrVFCk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeUWraO%2FbtsEdWdqWti%2FbU1ua3C7k3Jy9GqRrVFCk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;228&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2554&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;우선 Common Voice 의 경우 Mozilla 제단에서 제공하는 음성 데이터 셋이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;한국어를 비롯한 세계 여러 언어의 음성 데이터를 제공하며,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;개인들이 직접 녹음할 수 있고, 이를 평가할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;마치 Wikipedia 같은 방식이라고 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;나는 개인적으로 Wiki 가 가진 시스템의 장점이 참 마음에 드는데,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;결국 규모를 키우는데는 이만한게 없기 때문이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;한국의 나무위키만 봐도 공감할 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1042&quot; data-origin-height=&quot;585&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/snzic/btsEf2qEqQx/8sTguGWDedSKsxEhSnafM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/snzic/btsEf2qEqQx/8sTguGWDedSKsxEhSnafM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/snzic/btsEf2qEqQx/8sTguGWDedSKsxEhSnafM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsnzic%2FbtsEf2qEqQx%2F8sTguGWDedSKsxEhSnafM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;449&quot; data-origin-width=&quot;1042&quot; data-origin-height=&quot;585&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 아무래도 이런 시스템의 단점이라면 '정보의 정확성' 문제가 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;어느정도 자료조사의 기초를 공부한 사람이라면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;위키 정보를 그대로 옴겨적는 일은 하지 않을것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;위키는 어디까지나 정보를 겉으로 핥는 용도이며,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그 겉핥기를 토대로 진위를 확인할 필요성이 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;보통 기사나, 논문 등을 확인한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Common Voice 측에서도 이런 문제를 인지 못 하고 있는것은 아니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 Validated 라는 명목으로 사람들에게 '평가' 받은 데이터들을 'Validated' 로 분류하고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;143&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYjbhg/btsEdIzHrNI/w7qK610e4DFb2r2QyDL2z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYjbhg/btsEdIzHrNI/w7qK610e4DFb2r2QyDL2z0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYjbhg/btsEdIzHrNI/w7qK610e4DFb2r2QyDL2z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYjbhg%2FbtsEdIzHrNI%2Fw7qK610e4DFb2r2QyDL2z0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;142&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;143&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;사실 나도 이거에 낚여서 3일정도 시간을 허비했는데,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이 Validated 를 곧이 곧대로 믿으면 안된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Common Voice 는 음성에 관해서 여러 메타데이터 정보를 제공하는데,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;연령정보나, 억양과 같은 데이터를 제공한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;나의 경우, 음성의 '연령' 메타데이터 정보가 굉장히 중요했다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;한국에서 개인정보는 다소 경시되는 경향이 있어서 연령, 지역, 성별 등 발화자의 부가정보를 쉽게 얻을 수 있지만&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;영어 데이터에서 이러한 메타 데이터를 얻기란 매우 힘들다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그나마 영어 음성 데이터셋 중 Common Voice 에서 이런 연령 정보를&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;특정 범위 내에서 제공하기에 연구 자료로 사용 하려고 하였는데,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;저 Validated 라는 말에 너무 무게를 둔 것 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이쯤해서 서론은 집어치우고, Common Voice 의 문제점에 관해서 이야기 하겠다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Validated 데이터셋의 검증 기준이 너무 느슨하다&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;143&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqUOrl/btsEcbvpBJJ/I64Fv4GI2hQCJtrMfnrRJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqUOrl/btsEcbvpBJJ/I64Fv4GI2hQCJtrMfnrRJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqUOrl/btsEcbvpBJJ/I64Fv4GI2hQCJtrMfnrRJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqUOrl%2FbtsEcbvpBJJ%2FI64Fv4GI2hQCJtrMfnrRJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;807&quot; height=&quot;143&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;143&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;위에서도 언급했듯이 이러한 데이터를 제 3자가 '평가' 한 데이터셋을&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Validated 라고 말한다. 즉 '검증되었다' 라는 의미이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;검증 방식 자체는? 옳다고 본다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그런데 문제는 이게 과반수만 넘는다고 되는 투표도 아니고...&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;예시로, 어떤 음성 데이터에 대해서 3명중 2명이 '옳다' 고 투표하고&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;1명이 '옳지 않다' 고 투표한다면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해당 데이터셋을 Validated 라고 분류하면 안된다고 생각한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 Common-Voice 에서는 ${2 \over 3}$ = 66% 정확도도 Validated 셋으로 간주한다...&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그나마 이정도는 양반이고,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;몇몇 자료들은 ${4 \over 7} =$ 57% 같은 상황이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;예측해보건데&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;2표이상에 up_votes 비율이 50% 이상이면 Validated 되었다고 분류하는것 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;듣는 사람중에서 절반 가까이가&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;i&gt; '이거 아닌거같은데?'&lt;/i&gt; &lt;/span&gt;라고 말하는 음성을&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;어떻게 Validated 라고 이름붙여서 데이터셋으로 만드는지 잘 이해가 안된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 투표 수가 적다.&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;대충 눈대중으로 말하려다가&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그래도 비판글인데 명확히 해야겠다 싶어서 분석한 결과를 보여주면&lt;/p&gt;
&lt;pre id=&quot;code_1706667476429&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;up_votes
2       1455754
3        162601
4        126231
6         16095
5          8358
8          3529
7          2761
10         2337

...
...​

down_votes
0      1508496
1       248787
2        21693
3         2294
4          741
5          313
6          137
7           77
8           51
9           33
10          24
11          24&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;정도의 투표수를 보유중인데,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;2건의 찬성 투표를 받은 음성파일을 과연 Validated 라고 말할 수 있을까?&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;심지어 총 Validated 데이터셋이 177만개이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;근데 그 중 145만개&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(81%)&lt;/span&gt;가 단 2건의 투표만 받은것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이걸 신뢰할 수 있겠는가?&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;물론 위에서 언급한 나무위키 등과는 다르게&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;어느정도 데이터 구축에 관심이 있는 사람들이 청취후에 투표한 것이지만&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;본질적으로&lt;/span&gt; 나무위키와 Common Voice 는 다를게 없다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;오히려 명확한 기준을 가진 단일 전문가가 분류한것이 훨신 나을것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;실제로 나는 데이터들을 확인중&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;2건의 찬성표, 1건의 반대표를 받은&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;i&gt;Common_voice_en_71615.mp3&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;파일의 문제점을 발견하여 Mozilla 제단에 보고하였다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해당 파일은 녹음 정지버튼을 누르지 못한 것으로 추정되는데&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;발화자가 문장을 말한 뒤에 약 6분 가량 음성파일이 끊어지지 않고&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;주변 대화소리가 들려오는 잘못된 파일이였다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아니 이런 파일도 못 걸러진 데이터셋을 'Validated' 라고?&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(당연히 용량부터 수십배 차이가 난다)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;라는 생각이 들 수 밖에 없다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. MetaData 를 믿을 수 없다.&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;한국에서 수집되는 정보들은 보통 Metadata 를 같이 제공해 주는 경우가 많이있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;특히 한국 AI hub 에서 제공되는 데이터들은&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;연령, 지역, 성별등 많은 메타데이터를 제공해 주는데&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이런 정보들은 기관을 거쳐 검증된 정보만을 제공하는 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해외에서는 논문 검증용으로 사용되는 LibreSpeech 도 그렇고&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Transcript 를 제외한 상세한 메타데이터를 제공해 주는 데이터셋은 찾기가 매우 어렵다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;특히 공개 데이터 세트에서는 거의 불가능하다고 보면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그래도 나는 연령 정보가 필요했기에 Common Voice 를 선택했던 것인데,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;문제는 이 연령 메타 데이터도 믿을 수 없다는데에 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;615&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Dg95W/btsEaP06iy6/v3EvXEEJGutANz69qJ2WcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Dg95W/btsEaP06iy6/v3EvXEEJGutANz69qJ2WcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Dg95W/btsEaP06iy6/v3EvXEEJGutANz69qJ2WcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDg95W%2FbtsEaP06iy6%2Fv3EvXEEJGutANz69qJ2WcK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;541&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;615&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Common Voice 에 내 음성을 기여하다 보면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;사용자에 대한 메타데이터를 기재할 수 있는 란이 있는데&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;여기에 아무 나이대, 아무 성별이나 입력해도&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;검증과정이 없다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;902&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dMmnBT/btsEf3px1RC/uQwpJvRH6Tnfu0gQyfgDD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dMmnBT/btsEf3px1RC/uQwpJvRH6Tnfu0gQyfgDD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dMmnBT/btsEf3px1RC/uQwpJvRH6Tnfu0gQyfgDD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdMmnBT%2FbtsEf3px1RC%2FuQwpJvRH6Tnfu0gQyfgDD0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;648&quot; data-origin-width=&quot;902&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;심지어 투표 과정에서도 메타데이터 정보에 관해서 평가자가 확인할 수 있는 것이 없다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;예로, 10대 여성이 장난이든 착오든 80대 남성으로 메타데이터를 잘못 기입했다고 해서&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이걸 '평가자' 가 청취후 '메타데이터 잘못된거 같은데요?' 라고 할 수 없는것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;물론, 80대 남성같은 목소리를 내는 10대 여성이 없다는건 아니므로&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;애초에 명확한 검증방법 없이 이러한 메타데이터를 제공한다는 것 자체가 잘못되었다고 본다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;취지는 좋으나, 신뢰성을 떨어뜨리는 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 결론&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;물론 이건 2024년 1월 31일 기준으로 Common Voice 데이터셋을 신뢰하기 어렵다는 것이지&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;중장기적으로 Common Voice 의 정책 변경, 커뮤니티 활성화 등으로 인해&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;얼마든지 변경될 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;추가로 이러한 신뢰성은, 검증 기준이 잘못되어서 신뢰하기 어렵다는거지&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;내 느낌상 Transcript 기준 80% 이상은 올바르게 평가 된 것 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;현재 Validated 셋 기준해서 2,586 시간 정도의 데이터셋이 쌓여있는데,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;보다 많은 사람들이 참여&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(특히 평가)&lt;/span&gt;해서 데이터셋을 유용하게 쓸 수 있으면 하는 바람이고,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;나처럼 데이터셋을 찾아다니는 분들께 도움이 되었으면 좋겠다.&lt;/p&gt;</description>
      <category>Artificial Intelligence/Insights</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/173</guid>
      <comments>https://cypsw.tistory.com/entry/Common-Voice-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%85%8B%EC%9D%80-%EC%8B%A0%EB%A2%B0%ED%95%A0-%EC%88%98-%EC%97%86%EB%8B%A4#entry173comment</comments>
      <pubDate>Wed, 31 Jan 2024 11:43:14 +0900</pubDate>
    </item>
    <item>
      <title>인공지능에서 Parameter 란?</title>
      <link>https://cypsw.tistory.com/entry/%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5%EC%97%90%EC%84%9C-Parameter-%EB%9E%80</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;pre-trained 된 모델들을 보면 parameter 라는 단어가 눈에 띈다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;145&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccWQJQ/btsD4HmMcTi/KtsHUJ3EgS7yklNAKKBcKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccWQJQ/btsD4HmMcTi/KtsHUJ3EgS7yklNAKKBcKk/img.png&quot; data-alt=&quot;Conformer-CTC (Korean language)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccWQJQ/btsD4HmMcTi/KtsHUJ3EgS7yklNAKKBcKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccWQJQ%2FbtsD4HmMcTi%2FKtsHUJ3EgS7yklNAKKBcKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;124&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;145&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Conformer-CTC (Korean language)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 parameter 는 hyper-parameter 와는 별개의 뜻으로 사용된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;통상적으로 hyper-parameter 는 학습과정에 있어 유저가 지정할 수 있는 값들을 의미한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;예로 learning-rate, epoch, multi-head attention count 등이 포함된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;반면 parameter 는 아래와 같은 의미를 지닌다.&lt;/p&gt;
&lt;figure id=&quot;og_1706289895290&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;In an A.I. model, what exactly is a &amp;quot;parameter&amp;quot; counting?&quot; data-og-description=&quot;Tim Converse's answer: The question was &amp;ldquo;In an A.I. model, what exactly is a &amp;lsquo;parameter&amp;rsquo; counting?&amp;rdquo; Most machine-learned models have two aspects: 1) a structure into which numbers are plugged to define the model, 2) the numbers themselves, which ar&quot; data-og-host=&quot;www.quora.com&quot; data-og-source-url=&quot;https://qr.ae/pKBgw0&quot; data-og-url=&quot;https://www.quora.com/In-an-A-I-model-what-exactly-is-a-parameter-counting/answer/Tim-Converse&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/lOJiZ/hyVb6342v1/MwzwgPdc70Sfyr71D6Jua0/img.jpg?width=600&amp;amp;height=315&amp;amp;face=0_0_600_315,https://scrap.kakaocdn.net/dn/c0rh8I/hyU8WPAigq/EJfws6UJm31H8ikchCP27K/img.jpg?width=600&amp;amp;height=315&amp;amp;face=0_0_600_315&quot;&gt;&lt;a href=&quot;https://qr.ae/pKBgw0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://qr.ae/pKBgw0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/lOJiZ/hyVb6342v1/MwzwgPdc70Sfyr71D6Jua0/img.jpg?width=600&amp;amp;height=315&amp;amp;face=0_0_600_315,https://scrap.kakaocdn.net/dn/c0rh8I/hyU8WPAigq/EJfws6UJm31H8ikchCP27K/img.jpg?width=600&amp;amp;height=315&amp;amp;face=0_0_600_315');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;In an A.I. model, what exactly is a &quot;parameter&quot; counting?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Tim Converse's answer: The question was &amp;ldquo;In an A.I. model, what exactly is a &amp;lsquo;parameter&amp;rsquo; counting?&amp;rdquo; Most machine-learned models have two aspects: 1) a structure into which numbers are plugged to define the model, 2) the numbers themselves, which ar&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.quora.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;답변이 원론적이라 좀 어렵게 느껴질 수 있는데 요약하자면,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;신경망에서 다룰 수 있는 값들의 범위를 나타내는 것과 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 다룰 수 있는 범위의 값이란, 단순히 출력값을 의미하는 것이 아니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;예로, 0~9 까지의 손글씨를 출력하는 MLP 모델이 있다고 해서 parameter 가 10개라는 의미는 아니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;566&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crbF6O/btsDZ1gmXhQ/8uok22cV8x7BascJQExTb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crbF6O/btsDZ1gmXhQ/8uok22cV8x7BascJQExTb1/img.png&quot; data-alt=&quot;대표적인 손글씨 인식 데이터셋&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crbF6O/btsDZ1gmXhQ/8uok22cV8x7BascJQExTb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrbF6O%2FbtsDZ1gmXhQ%2F8uok22cV8x7BascJQExTb1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;566&quot; height=&quot;566&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;566&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;대표적인 손글씨 인식 데이터셋&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;좀 더 쉽게 말하자면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;입력값으로부터 출력값인 0~9 까지 가능한 모든 확립가능한 경로의 수를 의미한다고 보면 좋다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이를 나는 '경우의 수&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(weight, bias)&lt;/span&gt;' 라고 호칭한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;예로 MLP 모델일 경우&lt;span style=&quot;color: #f89009;&quot;&gt; perceptron 증가 = parameter 증가&lt;/span&gt; 이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;perceptron 이 증가한다는 건 조정해야할 weight, bias 가 많아진다는 의미이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 경우의 수는 모델 내부에서 결정되므로&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이미 완성된 모델을 단순히 학습시키는 유저 입장에서 관여할 수 없다는 점에서&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;hyper-parameter 와 &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;근본적인 차이점을 보인다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;만약 parameter 수를 변경하고 싶다면 모델의 구조를 변경해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;597&quot; data-origin-height=&quot;324&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HQEip/btsD5zhJSzB/jT9HxxYgIdHesAe476Hca1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HQEip/btsD5zhJSzB/jT9HxxYgIdHesAe476Hca1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HQEip/btsD5zhJSzB/jT9HxxYgIdHesAe476Hca1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHQEip%2FbtsD5zhJSzB%2FjT9HxxYgIdHesAe476Hca1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;597&quot; height=&quot;324&quot; data-origin-width=&quot;597&quot; data-origin-height=&quot;324&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;위와같은 MLP 가 있다고 가정했을 때&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;layer 의 width 가 넓어질 수도 있고, depth가 깊어질 수도 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이럴경우 당연히 모델 내부에서 계산해야 할 '경우의 수&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(weight, bias)&lt;/span&gt;' 역시 많아진다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;즉, parameter 라는 용어는 모델의 '복잡성' 을 나타낼 때 사용된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;예로 깊이가 3인 MLP와 10인 MLP 의 parameter 는 어떤것이 더 많을까?&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;width 가 같다면 깊이 10 짜리의 MLP 의 parameter 가 더 많을것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;parameter 수가 많음에 따른 장, 단점은 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장점
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;모델의 표현력이 높아진다.&lt;/li&gt;
&lt;li&gt;훈련 데이터가 충분히 풍부하다면, 모델이 보다 우수하게 일반화된 성능을 낼 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;'경우의 수' 가 많다는 의미는, 그만큼 훈련에 계산 리소스를 많이 소모한다는 의미도 동시에 가진다.&lt;/li&gt;
&lt;li&gt;훈련 데이터가 부족하다면 부족한 데이터의 노이즈 등 세세한 부분까지 훈련되어 과적합될 위험성이 존재한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Artificial Intelligence/Fundamentals</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/172</guid>
      <comments>https://cypsw.tistory.com/entry/%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5%EC%97%90%EC%84%9C-Parameter-%EB%9E%80#entry172comment</comments>
      <pubDate>Sat, 27 Jan 2024 02:48:32 +0900</pubDate>
    </item>
    <item>
      <title>[리뷰] Conformer</title>
      <link>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-Conformer</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Conformer 는 ASR 모델중 하나로서, 나온지 어느정도 지난 모델이다. 2020년 Google에 의해 &lt;a href=&quot;https://arxiv.org/pdf/2005.08100.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공개 된 논문&lt;/a&gt;이기에, 굳이 리뷰할 생각을 가지지 못했었지만, 여러 논문들을 리뷰해 보니 Whisper, Wav2vec 2.0 등에 비해 뒤쳐지는 모델도 아닐뿐더러 굉장히 많이 인용된다는 사실을 알게 되었기에 리뷰한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;이 포스팅의 본문을 볼 때 해당 논문이 2020년에 작성된 논문이라는 점을 인지하고 보길 바란다. 현행 ASR 에서 필수적으로 인용되는 wav2vec 2.0 역시 2020년도에 작성된 논문이기에, conformer 에서는 그러한 배경을 반영하기 어려웠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;1. Introduce&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;end-to-end ASR 시스템은 최근 몇 년간 큰 발전을 이루었다. RNN 을 기반으로 Audio Sequences 의 시간적인 종속성을 효과적으로 모델링 할 수 있었고, 그 후에 self-attention 을 기반으로 하는 Transformer 아키텍쳐가 등장하며 보다 먼 거리에 있어도 상호작용이 가능한 능력과 높은 훈련 효율성&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(transformer 는 병렬훈련이 가능)&lt;/span&gt;으로 한차례 발전 하였고, 그와 동시에 convolution 또한 ASR 에서 성공적으로 작동하는 등 여러 발전이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 self-attention 이나 convolution 을 사용하는 모델에는 각각 한계가 있다. transformer 는 장거리 global context 를 모델링하는데 유용하지만, 세분화된 로컬 기능 패턴을 추출하는 능력은 떨어진다. 반면 CNN 은 로컬 정보를 잘 활용하는 대신 global 한 특징을 추출하는 능력은 떨어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;local window 를 통해 shared position-based 커널을 학습해 translation equivariance 을 유지하고 edge, shape 와 같은 특징들을 캡쳐할 수 있다. 하지만 이러한 local 연결성을 활용하는데에 있어 한계점은, 만약 global 정보를 캡처하려면 더 많은 layer, parameter 가 필요하다는 점이다. 해당 문제를 해결하기 위해 CNN 에서는 residual block 에 squeeze-and-excitation 모듈을 사용하여 더 긴 context 를 캡쳐한다. 그러나 이러한 방식 역시 전체 sequence 에 대해 global 평균만을 캡쳐하므로, dynamic - global 한 context 를 캡쳐하는데는 여전히 문제가 있다. &lt;span style=&quot;color: #9d9d9d;&quot;&gt;(즉 global 한 특징을 추출하려면 그냥 transformer 에 비해서 convolution 은 열세이다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 상황 속에서 몇몇 연구자들이 발견한 점으로, convolution 과 self-attention 을 결합해 사용하면 성능이 개선 되는것이 확인되었다. 이를 통해 위치별 local feature 를 학습하고, global 상호작용을 이용하는것이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 연구에서 ASR 을 모델을 제작하는데 있어 convolution 과 self-attention 을 유기적으로 결합하는 방법을 연구하였다. 저자들은 global, local 상호작용이 parameter 의 효율성을 위해 중요하다고 전제를 깔아둔 채 연구를 진행하였고, 이를 달성하기 위해 self-attention 과 convolution 의 새로운 조합을 제안한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;893&quot; data-origin-height=&quot;1012&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eNBx1T/btsDKw7lfyD/G6TJTI9d8IbLbcjOAHD6G0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eNBx1T/btsDKw7lfyD/G6TJTI9d8IbLbcjOAHD6G0/img.png&quot; data-alt=&quot;그림 1: Conformer 인코더 모델 아키텍처. Conformer는 multi-headed self-attention 및 convolution 모듈을 사이에 두고 halfstep residual connection 이 있는 두 개의 macaron(마카롱과 네트워크 구조가 비슷하다는 비유적 표현) 과 같은 feed-forward layer로 구성되며, 그 뒤에는 post layernorm이 뒤따른다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eNBx1T/btsDKw7lfyD/G6TJTI9d8IbLbcjOAHD6G0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeNBx1T%2FbtsDKw7lfyD%2FG6TJTI9d8IbLbcjOAHD6G0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;793&quot; data-origin-width=&quot;893&quot; data-origin-height=&quot;1012&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 1: Conformer 인코더 모델 아키텍처. Conformer는 multi-headed self-attention 및 convolution 모듈을 사이에 두고 halfstep residual connection 이 있는 두 개의 macaron(마카롱과 네트워크 구조가 비슷하다는 비유적 표현) 과 같은 feed-forward layer로 구성되며, 그 뒤에는 post layernorm이 뒤따른다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자들은 attention head 수, convolution kernel size, activation function, feed-forward 레이어의 배치 및 Transformer 기반 네트워크에 convolution 모듈을 추가하는 등 여러가지 변형및 시도를 거쳤고, 각각이 정확도 향상에 어떻게 기여하는지 밝혔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2.&amp;nbsp;Conformer&amp;nbsp;Encoder &lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;conformer 의 encoder 는 그림 1 과 같이 먼저 convolution subsampling layer 를 사용하여 입력을 처리한 다음 여러 conformer 블록을 사용하여 처리한다. 즉 기존 모델대비 해당 모델의 특징은 transformer block 대신에 conformer 블록을 사용한다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종적으로 feed-forward 모듈, self-attention 모듈, convolution 모듈, second feed-forward 모듈로 구성된다. 아래 섹션에서는 해당 모듈들에 관해서 상세히 설명한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.1.&amp;nbsp;Multi-Headed&amp;nbsp;Self-Attention&amp;nbsp;Module&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 섹터에서는 3가지에 관해서 이야기하고 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Multi-Headed Self-Attention&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(MHSA)&lt;/span&gt;: Conformer 모델은 Transformer-XL에서 가져온 중요한 기술인 MHSA를 사용한다. 이는 모델이 입력 시퀀스의 다양한 길이에 대해 더 잘 일반화되도록 도와준다.&lt;/li&gt;
&lt;li&gt;Relative Sinusoidal Positional Encoding: &lt;a href=&quot;https://hyen4110.tistory.com/48&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Transformer-XL&lt;/a&gt;에서 유래된 방식으로. 상대적인 위치 정보를 포함하여 모델이 입력 시퀀스의 길이에 대한 변화에 더 잘 대응할 수 있도록 도와준다.&lt;/li&gt;
&lt;li&gt;Pre-norm Residual Units with Dropout: 훈련과 규제를 돕기 위해 pre-norm residual unit이 사용된다. 이는 더 깊은 모델을 효과적으로 학습하고 일반화할 수 있도록 도와준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;674&quot; data-origin-height=&quot;152&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PAowu/btsDHncYazw/Mg2jtJPfjelNovn3p5sLk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PAowu/btsDHncYazw/Mg2jtJPfjelNovn3p5sLk1/img.png&quot; data-alt=&quot;그림 3. Multi-Headed self-attention 모듈. 저자들은 multi-headed self-attention 을 relative positional embedding 과 pre-norm residual unit 에서 사용한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PAowu/btsDHncYazw/Mg2jtJPfjelNovn3p5sLk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPAowu%2FbtsDHncYazw%2FMg2jtJPfjelNovn3p5sLk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;135&quot; data-origin-width=&quot;674&quot; data-origin-height=&quot;152&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 3. Multi-Headed self-attention 모듈. 저자들은 multi-headed self-attention 을 relative positional embedding 과 pre-norm residual unit 에서 사용한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;transformer 모델에서 사용하던 Relative Sinusoidal Positional Encoding 을 동일하게 사용한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.2.&amp;nbsp;Convolution&amp;nbsp;Module&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Convolution 모듈은 GLU&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Gated Linear Unit)&lt;/span&gt; 로 시작한다. 그 다음 single 1-D 깊이별 convolution layer 가 이어지는 형식으로 설계되어 있으며, &lt;i&gt;&lt;b&gt;그림 2&lt;/b&gt;&lt;/i&gt;는 이러한 convolution block 을 보여주고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;139&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/07bmR/btsDIzYo5hd/I85N0TtLG2kDOGMzcqbT01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/07bmR/btsDIzYo5hd/I85N0TtLG2kDOGMzcqbT01/img.png&quot; data-alt=&quot;그림 2. Convolution module. Convolution module은 GLU 활성화 레이어가 있는 채널의 수를 투영하는 2의 expansion factor 를 가진 pointwise convolution을 포함하고 있으며, 1-D depthwise convolution을 포함한다. 1-D depthwise convolution &amp;amp;amp;rarr; Batch norm&amp;amp;amp;nbsp; &amp;amp;amp;rarr; swish Activation Layer 순이다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/07bmR/btsDIzYo5hd/I85N0TtLG2kDOGMzcqbT01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F07bmR%2FbtsDIzYo5hd%2FI85N0TtLG2kDOGMzcqbT01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;118&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;139&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 2. Convolution module. Convolution module은 GLU 활성화 레이어가 있는 채널의 수를 투영하는 2의 expansion factor 를 가진 pointwise convolution을 포함하고 있으며, 1-D depthwise convolution을 포함한다. 1-D depthwise convolution &amp;amp;rarr; Batch norm&amp;amp;nbsp; &amp;amp;rarr; swish Activation Layer 순이다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.3.&amp;nbsp;Feed&amp;nbsp;Forward&amp;nbsp;Module&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;transformer 아키텍처는 MHSA 뒤에 feed-forward 모듈을 배치하고, 두 개의 linear transformations 와 그 사이의 non-linear activation 으로 구성되어 있으며, 이러한 feed-forward 레이어 위에는 residual connection 이 추가되고 layer normalization 이 이어지는 형태를 띈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 논문에서 제안하는 Conformer 모델에서는 이러한 구조를 변형하여 수행하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;conformer에서는 pre-norm residual units을 따르며, layer normalization는 residual unit 내부 및 first linear layer 이전의 입력에 적용된다. 더하여 Swish activation function과 dropout이 적용되어 네트워크를 통제하는 데에 도움이 되었다. 이 구조는 feed-forward&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(FFN)&lt;/span&gt; 모듈을 설명하는 Figure 4에서 시각적으로 살펴볼 수 있다..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;895&quot; data-origin-height=&quot;190&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tSlqT/btsDQapfOT7/HCB4mUnGjVBw0pKv6HXkk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tSlqT/btsDQapfOT7/HCB4mUnGjVBw0pKv6HXkk1/img.png&quot; data-alt=&quot;그림 4. feed-forward module. first linear layer 는 expansion factor 를 통해 4 로 늘리고(입력 벡터의 차원을 4배로 늘리고), second linear layer 는 model dimension 으로 다시 projects(변환) 한다.(즉 원래 차원으로 다시 되돌린다).&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tSlqT/btsDQapfOT7/HCB4mUnGjVBw0pKv6HXkk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtSlqT%2FbtsDQapfOT7%2FHCB4mUnGjVBw0pKv6HXkk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;170&quot; data-origin-width=&quot;895&quot; data-origin-height=&quot;190&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 4. feed-forward module. first linear layer 는 expansion factor 를 통해 4 로 늘리고(입력 벡터의 차원을 4배로 늘리고), second linear layer 는 model dimension 으로 다시 projects(변환) 한다.(즉 원래 차원으로 다시 되돌린다).&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.4.&amp;nbsp;Conformer&amp;nbsp;Block&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자들이 제안한 conformer 블록&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(&lt;i&gt;&lt;b&gt;그림 1&lt;/b&gt;&lt;/i&gt;)&lt;/span&gt; 에는 Multi-Headed Self-Attention 모듈과 convolution 모듈을 사이에 둔 두개의 feed-forward 모듈이 포함되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 샌드위치 구조는 transformer 블록의 원래 feed-forward layer를 attention layer 앞과 뒤의 두 개의 반단계 feed-forward 레이어로 대체하는 것을 제안하였다. 여기서 우리는 feed-forward 모듈에 반단계 Residual weights 를 사용한다. second feed-forward 모듈 뒤에는 최종으로 layernorm layer 가 위치한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수학적으로 이는 conformer $i$ 에 대한 입력 $x_i$에 대해 블록의 출력 $y_i$ 는 다음과 같다는 것을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&lt;br /&gt;\begin{flalign}&lt;br /&gt;\tilde{x}_i &amp;amp;= x_i + \frac{1}{2} \text{FFN}(x_i)\\&lt;br /&gt;x'_i &amp;amp;= \tilde{x}_i + \text{MHSA}(\tilde{x}_i)\\&lt;br /&gt;x''_i &amp;amp;= x&amp;rsquo;_i + \text{Conv}(x'_i) )\\&lt;br /&gt;y_i &amp;amp;= \text{Layernorm}(x''_i + \frac{1}{2} \text{FFN}(x''_i))\\&lt;br /&gt;\end{flalign}&lt;br /&gt;$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 FFN은 feed-forward 모듈, MHSA 는 multi-head self-attention 모듈, Conv 는 convolution 모듈을 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 글에서는 적지 않았지만 논문에서는 이러한 구조 자체는 macaron-style&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(두개의 동일한 sub layer 사이에 다른 sub layer가 삽입된 구조를 지칭함.)&lt;/span&gt; 이라고 한다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(이는 macaron-net 에서 사용된 macaron-style 의 feed-forward 모듈로 제안되었다. 이를 conformer 에 적용한 것이다.) &lt;/span&gt;conformer 논문에서는 macaron-style 모듈을 사용하는것이 single feed-forward 모듈을 사용하는것 대비 상당한 개선을 가져온다는 것을 확인하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 논문에서는 convolution 과 self-attention 의 조합은 이전에 연구되었으며, 이를 달성하는데에는 다양한 방법이 존재한다고 언급한다. self-attention 을 사용하여 convolution 을 강화하는 다양한 옵션은 해당 논문의 '&lt;b&gt;&lt;i&gt;3.4.2. Combinations of Convolution and Transformer Modules&lt;/i&gt;&lt;/b&gt;' 에서 다루고 있으며, 결론적으로 연구진은 self-attention 모듈 뒤에 쌓인 convolution 모듈이 음성 인식과 전반적인 자연어 처리에 가장 적합하다는 것을 확인하였다.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.5. 정리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종적으로 &lt;i&gt;&lt;b&gt;그림 1.&lt;/b&gt;&lt;/i&gt; 을 보며 위의 내용을 정리 해 보자&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(다음 섹터는 실험 및 결과 섹터이다.)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;893&quot; data-origin-height=&quot;1012&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc3ILZ/btsDQZgUi6l/tdZLDbokIktsmylIrkshO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc3ILZ/btsDQZgUi6l/tdZLDbokIktsmylIrkshO0/img.png&quot; data-alt=&quot;그림 1: Conformer 인코더 모델 아키텍처. Conformer는 multi-headed self-attention 및 convolution 모듈을 사이에 두고 halfstep residual connection 이 있는 두 개의 macaron(마카롱과 네트워크 구조가 비슷하다는 비유적 표현) 과 같은 feed-forward layer로 구성되며, 그 뒤에는 post layernorm이 뒤따른다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc3ILZ/btsDQZgUi6l/tdZLDbokIktsmylIrkshO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbc3ILZ%2FbtsDQZgUi6l%2FtdZLDbokIktsmylIrkshO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;793&quot; data-origin-width=&quot;893&quot; data-origin-height=&quot;1012&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 1: Conformer 인코더 모델 아키텍처. Conformer는 multi-headed self-attention 및 convolution 모듈을 사이에 두고 halfstep residual connection 이 있는 두 개의 macaron(마카롱과 네트워크 구조가 비슷하다는 비유적 표현) 과 같은 feed-forward layer로 구성되며, 그 뒤에는 post layernorm이 뒤따른다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종적으로, Conformer 모델은 두개의 feed-forward 모듈 사이에 self-attention 과 convolution sub-layer&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Conformer 내에 포함되어 있으므로 sub-layer 라고 지칭)&lt;/span&gt;를 삽입한 구조를 나타내며, 저자들은 이러한 형태가 가장 음성인식 &amp;amp; 자연어 처리에 있어 유용한 구조라고 결론 내린 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외에 Conformer network 에 입력하기 전에 처리하는 과정은 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;SpecAug&lt;/b&gt; &lt;/span&gt;: SpecAugment이라는 데이터 증강 방법을 나타낸다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;Convolution Subsampling&lt;/b&gt; &lt;/span&gt;: 입력 차원을 줄이기 위해 사용됨.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;Linear&lt;/span&gt;&lt;/b&gt; : linear layer를 나타낸다. linear layer는 입력 벡터와 가중치 행렬의 곱에 bias&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(편향)&lt;/span&gt; 벡터를 더하는 층이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;Dropout&lt;/span&gt; &lt;/b&gt;: 드롭아웃은 신경망의 과적합을 방지하기 위해 사용되는 정규화 기법이다. 드롭아웃은 학습 과정에서 임의로 일부 뉴런을 비활성화시킨다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Experiments&lt;/b&gt;&lt;/h2&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3.1. Data&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문에서는 이렇게 완성된 Conformer 를 970시간의 LibriSpeech 데이터 셋으로 모델을 평가하였다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문 &lt;b&gt;&lt;i&gt;Experiments&lt;/i&gt; &lt;/b&gt;섹터에서 mask 파라미터, 최대 time-mask 비율 등에 대한 정보 및,&lt;br /&gt;Table 1 에서 Hyper parameter 에 대해 상세히 설명하고 있다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;240&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/poN3S/btsDT4JzryG/kkmWtSAek3HOWz3iWETtBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/poN3S/btsDT4JzryG/kkmWtSAek3HOWz3iWETtBK/img.png&quot; data-alt=&quot;표 1. Conformer $S, M, L$ 모델에 대한 모델 hyper-parameters&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/poN3S/btsDT4JzryG/kkmWtSAek3HOWz3iWETtBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpoN3S%2FbtsDT4JzryG%2FkkmWtSAek3HOWz3iWETtBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;502&quot; height=&quot;240&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;240&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 1. Conformer $S, M, L$ 모델에 대한 모델 hyper-parameters&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 모델을 개발, 운용할 때에는 중요할지 몰라도, 리뷰에서 크게 중요한 부분이 아니라고 생각하기에 생략하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3.2.&amp;nbsp;Conformer&amp;nbsp;Block&amp;nbsp;vs.&amp;nbsp;Transformer&amp;nbsp;Block &lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Conformer Block 과 Trasformer Block 은 구조적으로 다르다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rXh6t/btsDQS4ciDr/Sy9PO82k6dBVBB3SMAcqc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rXh6t/btsDQS4ciDr/Sy9PO82k6dBVBB3SMAcqc0/img.png&quot; data-origin-width=&quot;893&quot; data-origin-height=&quot;1012&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;52.14&quot; style=&quot;width: 51.5364%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rXh6t/btsDQS4ciDr/Sy9PO82k6dBVBB3SMAcqc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrXh6t%2FbtsDQS4ciDr%2FSy9PO82k6dBVBB3SMAcqc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;893&quot; height=&quot;1012&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvKbeX/btsDSqMU3ga/DrvGlov1vmbyFXlnpN3a4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvKbeX/btsDSqMU3ga/DrvGlov1vmbyFXlnpN3a4K/img.png&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;910&quot; data-is-animation=&quot;false&quot; style=&quot;width: 47.3008%;&quot; data-widthpercent=&quot;47.86&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvKbeX/btsDSqMU3ga/DrvGlov1vmbyFXlnpN3a4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvKbeX%2FbtsDSqMU3ga%2FDrvGlov1vmbyFXlnpN3a4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;737&quot; height=&quot;910&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;Left : Conformer, Right : Transformer&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Transformer 는 encoder-decoder 구조로 되어 있으며 논문에서 비교하는 transformer 부분은 붉은 박스로 지정된 encoder block 부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 transformer block 시작부분에 feed-forward 모듈을 추가하고, multi-head attention 뒤에 convolution 모듈을 끼워넣은 형태가 바로 conformer block 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자들은 conformer block 을 transformer 블록으로 변형시키면서, parameter 는 변경하지 않음으로서 이러한 모델의 설계 차이가 어떠한 효과를 불러일으키는지 연구하였고, 그 결과가 &lt;i&gt;&lt;b&gt;표 3.&lt;/b&gt;&lt;/i&gt; 이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;516&quot; data-origin-height=&quot;189&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btWsj4/btsDLKsf7JP/Qu4hBTKaPHlyxbklFmxKX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btWsj4/btsDLKsf7JP/Qu4hBTKaPHlyxbklFmxKX1/img.png&quot; data-alt=&quot;표 3. conformer 블록에서 시작하여 하나씩 기능을 제거하며 바닐라 transformer 블록으로 이동한다. (1) SWISH 를 ReLU 로 대체, (2) Convolution sub-block 제거, (3) Macaron-style 의 FFN 쌍을 단일 FFN 으로 대체, (4) self-attention 을 positional embedding 으로 대체.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btWsj4/btsDLKsf7JP/Qu4hBTKaPHlyxbklFmxKX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtWsj4%2FbtsDLKsf7JP%2FQu4hBTKaPHlyxbklFmxKX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;516&quot; height=&quot;189&quot; data-origin-width=&quot;516&quot; data-origin-height=&quot;189&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표 3. conformer 블록에서 시작하여 하나씩 기능을 제거하며 바닐라 transformer 블록으로 이동한다. (1) SWISH 를 ReLU 로 대체, (2) Convolution sub-block 제거, (3) Macaron-style 의 FFN 쌍을 단일 FFN 으로 대체, (4) self-attention 을 positional embedding 으로 대체.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;표의 첫번째 행이 conformer 블록이고, 가장 아래단이 transformer 블록을 통해 테스트한 결과물이라고 볼 수 있으며, 최종적으로 conformer 가 transformer 보다 모든 데이터 셋에서 우수하다는 점을 확인해 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 외에도 논문에서는 여러 가지 테스트 결과표를 제공하고 있다. attention head 수를 변경하여 테스트한 것이라던지, convolution kernel size 를 변경하거나, macaron-net 에 좀 변형을 줘 본다든지 등등.. 흔히 새로운 모델을 개발할 때 '노가다' 짓을 한 결과표를 제공해 주고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; 4. Conclusion&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 해당 논문에서는 CNN 과 Transformer 을 구성요소를 결합하여 end-to-end 음성 인식 아키텍처인 Conformer 를 제안하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LibreSpeech 데이터 세트에 대해서 이전 작업대비 더 적은 수의 parameter 를 사용 했음에도 불구하고 1.9%/3.9%&lt;span style=&quot;color: #9d9d9d;&quot;&gt; (test/testother) &lt;/span&gt;의 고무적인 성능을 달성하였다.&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Artificial Intelligence/Paper Review</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/171</guid>
      <comments>https://cypsw.tistory.com/entry/%EB%A6%AC%EB%B7%B0-Conformer#entry171comment</comments>
      <pubDate>Mon, 22 Jan 2024 14:29:36 +0900</pubDate>
    </item>
    <item>
      <title>DB에서 Field 와 Column</title>
      <link>https://cypsw.tistory.com/entry/DB%EC%97%90%EC%84%9C-Field-%EC%99%80-Column</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;분명 내가 보던 Oracle 11g 라는 도서에서는 field 와 column 을 '동의어' 취급했었다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 나도 field 와 column 을 동의어로 사용 해 왔는데,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;최근에 뭔가... 뭔가 좀 이질감을 크게 느껴 검색을 해 보았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;962&quot; data-origin-height=&quot;267&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/73LUF/btsDnxti1F3/XLMkeorOlk7OzO7VAG3c5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/73LUF/btsDnxti1F3/XLMkeorOlk7OzO7VAG3c5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/73LUF/btsDnxti1F3/XLMkeorOlk7OzO7VAG3c5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F73LUF%2FbtsDnxti1F3%2FXLMkeorOlk7OzO7VAG3c5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;222&quot; data-origin-width=&quot;962&quot; data-origin-height=&quot;267&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;wikipedia 에서는 스프레드시트서 cell 이라고 인식하는 지점을 'field' 라고 지칭한다고 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;참고로 내가 field 를 그냥 잘못 공부해서 이상하게 알고있는거 아닐까... 생각해 봐도&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그 시절엔&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(?)&lt;/span&gt; 지금보다 더 열심히 공부했던 시절이라, 절대 잘못 알고 있을리가 없다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 동의어로 알고 있는 사람이 얼마나 되는가 찾아보니&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;[ 용어 ] '행, 열, 필드, 레코드, 튜플, 속성, 필드' 도대체 뭐가 뭐야?&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;[ 행 ] * 행 (row) = 레코드 (record) = 튜플 (tuple) * 행의 수 = 카디널리티 = 기수 = 대응수 [ 열 ] * 열 (column) = 속성 = 필드 * 열의 수 = 디그리 (degree) = 차수 [ 행, 열이 헷갈릴 때 ] 가로, 세로 순서라고 이&quot; data-og-host=&quot;mminky.tistory.com&quot; data-og-source-url=&quot;https://mminky.tistory.com/155&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bR6Uv9/hyU5ReMFkl/Uv82yKyZGUjJPAQSe8wbN0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/ywWQv/hyU5OWE5kZ/zYKuV4Uob4ktBv5Izx2J91/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot; data-og-url=&quot;https://mminky.tistory.com/155&quot;&gt;&lt;a href=&quot;https://mminky.tistory.com/155&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://mminky.tistory.com/155&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bR6Uv9/hyU5ReMFkl/Uv82yKyZGUjJPAQSe8wbN0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/ywWQv/hyU5OWE5kZ/zYKuV4Uob4ktBv5Izx2J91/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[ 용어 ] '행, 열, 필드, 레코드, 튜플, 속성, 필드' 도대체 뭐가 뭐야?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;[ 행 ] * 행 (row) = 레코드 (record) = 튜플 (tuple) * 행의 수 = 카디널리티 = 기수 = 대응수 [ 열 ] * 열 (column) = 속성 = 필드 * 열의 수 = 디그리 (degree) = 차수 [ 행, 열이 헷갈릴 때 ] 가로, 세로 순서라고 이&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;mminky.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;튜플 - 해시넷&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;튜플(tuple) 또는 multiplier 라고 부르는 것은 영어의 숫자 체계이다. 그 의미상 '몇배'라는 의미를 포함한다. [1] 튜플이란 데이터베이스내의 주어진 목록과 관계있는 속성값의 모음이다. 관련 테이&quot; data-og-host=&quot;wiki.hash.kr&quot; data-og-source-url=&quot;http://wiki.hash.kr/index.php/%ED%8A%9C%ED%94%8C#:~:text=%ED%8A%9C%ED%94%8C%EC%9D%B4%EB%9E%80%20%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EB%82%B4%EC%9D%98%20%EC%A3%BC%EC%96%B4%EC%A7%84,%EC%9D%98%20%ED%96%89%EC%9D%84%20%EC%9D%98%EB%AF%B8%ED%95%9C%EB%8B%A4.&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hFCKh/hyU5Oh3QZb/yw4egbIw32R4kkAiZ1sg4K/img.jpg?width=1024&amp;amp;height=240&amp;amp;face=0_0_1024_240,https://scrap.kakaocdn.net/dn/bjsZqm/hyU2tmk182/n2lVbFSzNkKhKyIk7EceIK/img.jpg?width=1024&amp;amp;height=240&amp;amp;face=0_0_1024_240,https://scrap.kakaocdn.net/dn/QfD7o/hyU5TXYjrG/4VHNgwVuX6WF2zYRINSFFK/img.jpg?width=213&amp;amp;height=750&amp;amp;face=21_21_98_105&quot; data-og-url=&quot;http://wiki.hash.kr/index.php/%ED%8A%9C%ED%94%8C#:~:text=%ED%8A%9C%ED%94%8C%EC%9D%B4%EB%9E%80%20%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EB%82%B4%EC%9D%98%20%EC%A3%BC%EC%96%B4%EC%A7%84,%EC%9D%98%20%ED%96%89%EC%9D%84%20%EC%9D%98%EB%AF%B8%ED%95%9C%EB%8B%A4.&quot;&gt;&lt;a href=&quot;http://wiki.hash.kr/index.php/%ED%8A%9C%ED%94%8C#:~:text=%ED%8A%9C%ED%94%8C%EC%9D%B4%EB%9E%80%20%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EB%82%B4%EC%9D%98%20%EC%A3%BC%EC%96%B4%EC%A7%84,%EC%9D%98%20%ED%96%89%EC%9D%84%20%EC%9D%98%EB%AF%B8%ED%95%9C%EB%8B%A4.&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://wiki.hash.kr/index.php/%ED%8A%9C%ED%94%8C#:~:text=%ED%8A%9C%ED%94%8C%EC%9D%B4%EB%9E%80%20%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EB%82%B4%EC%9D%98%20%EC%A3%BC%EC%96%B4%EC%A7%84,%EC%9D%98%20%ED%96%89%EC%9D%84%20%EC%9D%98%EB%AF%B8%ED%95%9C%EB%8B%A4.&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hFCKh/hyU5Oh3QZb/yw4egbIw32R4kkAiZ1sg4K/img.jpg?width=1024&amp;amp;height=240&amp;amp;face=0_0_1024_240,https://scrap.kakaocdn.net/dn/bjsZqm/hyU2tmk182/n2lVbFSzNkKhKyIk7EceIK/img.jpg?width=1024&amp;amp;height=240&amp;amp;face=0_0_1024_240,https://scrap.kakaocdn.net/dn/QfD7o/hyU5TXYjrG/4VHNgwVuX6WF2zYRINSFFK/img.jpg?width=213&amp;amp;height=750&amp;amp;face=21_21_98_105');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;튜플 - 해시넷&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;튜플(tuple) 또는 multiplier 라고 부르는 것은 영어의 숫자 체계이다. 그 의미상 '몇배'라는 의미를 포함한다. [1] 튜플이란 데이터베이스내의 주어진 목록과 관계있는 속성값의 모음이다. 관련 테이&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;wiki.hash.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1705228371659&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Column vs Field: have I been using these terms incorrectly?&quot; data-og-description=&quot;I feel kind of embarrassed here, I've always used the terms &amp;quot;column&amp;quot; and &amp;quot;field&amp;quot; completely interchangeably, which recently caused some confusion in a technical discussion. I was told, though, that&quot; data-og-host=&quot;dba.stackexchange.com&quot; data-og-source-url=&quot;https://dba.stackexchange.com/a/66737&quot; data-og-url=&quot;https://dba.stackexchange.com/questions/65609/column-vs-field-have-i-been-using-these-terms-incorrectly&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/voLi1/hyU2lPCS36/wKd3ww6L32PtyZsrjaj6wk/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://dba.stackexchange.com/a/66737&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://dba.stackexchange.com/a/66737&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/voLi1/hyU2lPCS36/wKd3ww6L32PtyZsrjaj6wk/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Column vs Field: have I been using these terms incorrectly?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I feel kind of embarrassed here, I've always used the terms &quot;column&quot; and &quot;field&quot; completely interchangeably, which recently caused some confusion in a technical discussion. I was told, though, that&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;dba.stackexchange.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;꽤 있다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/h4&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;Column vs Field: have I been using these terms incorrectly?&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;I feel kind of embarrassed here, I've always used the terms &amp;quot;column&amp;quot; and &amp;quot;field&amp;quot; completely interchangeably, which recently caused some confusion in a technical discussion. I was told, though, that&quot; data-og-host=&quot;dba.stackexchange.com&quot; data-og-source-url=&quot;https://dba.stackexchange.com/questions/65609/column-vs-field-have-i-been-using-these-terms-incorrectly&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/93Yo4/hyU5RTn616/e5XvmfszrJrxschTvXIJb1/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot; data-og-url=&quot;https://dba.stackexchange.com/questions/65609/column-vs-field-have-i-been-using-these-terms-incorrectly&quot;&gt;&lt;a href=&quot;https://dba.stackexchange.com/questions/65609/column-vs-field-have-i-been-using-these-terms-incorrectly&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://dba.stackexchange.com/questions/65609/column-vs-field-have-i-been-using-these-terms-incorrectly&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/93Yo4/hyU5RTn616/e5XvmfszrJrxschTvXIJb1/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Column vs Field: have I been using these terms incorrectly?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I feel kind of embarrassed here, I've always used the terms &quot;column&quot; and &quot;field&quot; completely interchangeably, which recently caused some confusion in a technical discussion. I was told, though, that&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;dba.stackexchange.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;StackExchange 답변에서 여러 힌트를 얻을 수 있었는데&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;RDB 를 정의한 논문에는 Field 라는 용어 자체가 없다.&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;100&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWqnzu/btsDrm4Une7/tBvoibkyriDPX37uoKXRuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWqnzu/btsDrm4Une7/tBvoibkyriDPX37uoKXRuK/img.png&quot; data-alt=&quot;https://dba.stackexchange.com/a/65614&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWqnzu/btsDrm4Une7/tBvoibkyriDPX37uoKXRuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWqnzu%2FbtsDrm4Une7%2FtBvoibkyriDPX37uoKXRuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;100&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;100&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://dba.stackexchange.com/a/65614&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;따라서&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;database 에서 field 란 애초에 명확하게 정의되지 않은 용어이며,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;관용적으로 column 대신에 사용되어 왔다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;702&quot; data-origin-height=&quot;101&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EG7Ad/btsDp4RrAnD/jK2vas2MAieLKKajHT4Opk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EG7Ad/btsDp4RrAnD/jK2vas2MAieLKKajHT4Opk/img.png&quot; data-alt=&quot;뭐가 어찌되었든, field 라는 용어는 'column' 대신에 사용되어 왔다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EG7Ad/btsDp4RrAnD/jK2vas2MAieLKKajHT4Opk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEG7Ad%2FbtsDp4RrAnD%2FjK2vas2MAieLKKajHT4Opk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;86&quot; data-origin-width=&quot;702&quot; data-origin-height=&quot;101&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;뭐가 어찌되었든, field 라는 용어는 'column' 대신에 사용되어 왔다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;모든 정보를 파악하고 난 뒤 내가 내린 결론은&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;만약 field 라는 용어를 쓰는 사람과 함께 일을 한다면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;일단 column 을 의미한다고 해석한뒤,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;만약 뭔가 이질감을 느낀다면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;질문을 해 명확히 짚고 넘어가는 편이 좋겠다.&lt;/p&gt;
&lt;div class=&quot;notranslate&quot; style=&quot;all: initial;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Tools/DataBase</category>
      <author>Cyp</author>
      <guid isPermaLink="true">https://cypsw.tistory.com/170</guid>
      <comments>https://cypsw.tistory.com/entry/DB%EC%97%90%EC%84%9C-Field-%EC%99%80-Column#entry170comment</comments>
      <pubDate>Sat, 13 Jan 2024 14:33:29 +0900</pubDate>
    </item>
  </channel>
</rss>