<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Tasteam Tech Blog</title>
    <link>https://tasteam.tistory.com/</link>
    <description>Tasteam의 기술 블로그 입니다.</description>
    <language>ko</language>
    <pubDate>Sun, 20 Sep 2026 13:35:16 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>tasteam tech</managingEditor>
    <image>
      <title>Tasteam Tech Blog</title>
      <url>https://tistory1.daumcdn.net/tistory/8551924/attach/01a4e769a7de41fe82deb58fd46ee4e8</url>
      <link>https://tasteam.tistory.com</link>
    </image>
    <item>
      <title>[AI] DeepFM 추천 시스템 성능 향상(+트러블 슈팅)</title>
      <link>https://tasteam.tistory.com/45</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 추천 시스템 성능 테스트 시, 랜덤 추천 성능 메트릭보다는 높지만, 인기순 추천 성능 메트릭보다는 낮은 상황 발생. &amp;rarr; 따라서 성능 향상을 위해 파생 피처 추가 진행했으나 성능 메트릭이 오히려 0으로 나오는 상황 발생.&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[문제상황/원인분석]&lt;/b&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;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;목표 성능 미달 &amp;rarr; 파생 피처 추가 후 성능 메트릭 0&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;auc&quot;: 0.5060968660968661,
  &quot;ndcg@5&quot;: 0.0,
  &quot;ndcg@10&quot;: 0.0,
  &quot;recall@5&quot;: 0.0,
  &quot;recall@10&quot;: 0.0,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;원인 분석
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;목표 성능 미달
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;피처 수는 많지만 피처에 실제로 모델이 학습할 수 있는 preference signal의 부족.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;파생 피처 추가 후 성능 메트릭 0
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;새 feature들이 너무 한쪽으로 치우쳐 있고(train/test 분포도 다르고), 그 결과 모델이 거의 모든 샘플을 positive처럼 보는 방향으로 무너진 것&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[대처 방안/해결]&lt;/b&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;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;전체 추가 피처 중 몇개의 피처만 추가해서 성능 측정 진행&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;autohotkey&quot;&gt;&lt;code&gt;기존 baseline +

* `user_category_match`
* `user_region_match`
* `price_diff`
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;해결 (해결 완료)
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;목표 성능 달성 및 성능 메트릭 0 문제 해결&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;auc&quot;: 0.6426139601139602,
  &quot;ndcg@5&quot;: 0.22093023283013208,
  &quot;ndcg@10&quot;: 0.22093023283013208,
  &quot;recall@5&quot;: 0.22093023283013208,
  &quot;recall@10&quot;: 0.22093023283013208,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;목표 성능 달성 및 이전 모델 baseline보다 향상.

* 이전 모델 baseline: `recall@10 &amp;asymp; 0.058`
* popularity baseline: `recall@10 &amp;asymp; 0.186`
* 이번 실험 1: `recall@10 &amp;asymp; 0.221`
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
      <author>jayvi.oh</author>
      <guid isPermaLink="true">https://tasteam.tistory.com/45</guid>
      <comments>https://tasteam.tistory.com/45#entry45comment</comments>
      <pubDate>Sat, 28 Mar 2026 15:49:07 +0900</pubDate>
    </item>
    <item>
      <title>[AI] evidence 학습이 LLM의 JSON 구조화 능력에 미치는 영향</title>
      <link>https://tasteam.tistory.com/44</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;배경&lt;/b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt; Qwen2.5-0.5B를 GPT-4o-mini로 Knowledge Distillation할 때, 학습 라벨에 evidence(근거 문장) 필드를 포함시켰다. 그런데 모델은 evidence를 제대로 출력하지 못했고 &amp;mdash; bullets와 매칭되지 않거나 0으로 채우는 경우가 많았다. 프롬프트 제약, few-shot 변경, 후처리 로직 추가 등 다양한 시도를 해봤지만 성능 변화가 없었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;가설&lt;/b&gt; 그렇다면 처음부터 evidence 없는 라벨로 학습시키는 게 낫지 않을까? 티처 모델도 evidence 생성에 capacity를 쓰지 않으면 나머지 태스크 품질이 더 높아질 것이고, 학생 모델도 그걸 더 잘 학습할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실험 설계&lt;/b&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: evidence 포함 라벨로 학습 &amp;rarr; 추론/후처리/최종 출력에서 evidence 제거&lt;/li&gt;
&lt;li&gt;B: evidence 제외 라벨로 학습 &amp;rarr; evidence 없이 추론&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;div&gt;JSON 파싱률스키마 정확도
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A (evidence 포함 학습)&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B (evidence 제외 학습)&lt;/td&gt;
&lt;td&gt;52%&lt;/td&gt;
&lt;td&gt;52%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가설이 틀렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;인사이트&lt;/b&gt; 모델이 evidence를 제대로 '출력'하지 못하더라도, evidence를 도출하려는 학습 과정 자체가 JSON 구조화 능력을 강화하는 regularization 역할을 한다. 정확한 메커니즘은 불명확하지만, 결과는 명확했다. 이 비교 실험을 수행하지 않았다면 최적 셋팅을 놓쳤을 것이다.&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;Metrics&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. evidence 라벨 학습, evidence 관련 프롬프트 제거, evidence 관련 후처리 제거, 최종 출력에서 evidence 키 제거 후 평가&lt;br /&gt;ROUGE,BERTscore&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-28 at 12.52.48 PM.png&quot; data-origin-width=&quot;592&quot; data-origin-height=&quot;338&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvsBoK/dJMcahRniVQ/c7QQpJKDEPUvFURW9k4aE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvsBoK/dJMcahRniVQ/c7QQpJKDEPUvFURW9k4aE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvsBoK/dJMcahRniVQ/c7QQpJKDEPUvFURW9k4aE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvsBoK%2FdJMcahRniVQ%2Fc7QQpJKDEPUvFURW9k4aE1%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;592&quot; height=&quot;338&quot; data-filename=&quot;Screenshot 2026-03-28 at 12.52.48 PM.png&quot; data-origin-width=&quot;592&quot; data-origin-height=&quot;338&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-28 at 12.53.15 PM.png&quot; data-origin-width=&quot;558&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cyzclC/dJMcabKq9QU/IJpPe0u0UzqGvfPqZLGOPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cyzclC/dJMcabKq9QU/IJpPe0u0UzqGvfPqZLGOPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cyzclC/dJMcabKq9QU/IJpPe0u0UzqGvfPqZLGOPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcyzclC%2FdJMcabKq9QU%2FIJpPe0u0UzqGvfPqZLGOPK%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;558&quot; height=&quot;302&quot; data-filename=&quot;Screenshot 2026-03-28 at 12.53.15 PM.png&quot; data-origin-width=&quot;558&quot; data-origin-height=&quot;302&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;LLM as a Judge&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-28 at 1.11.45 PM.png&quot; data-origin-width=&quot;674&quot; data-origin-height=&quot;588&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yLF6P/dJMb996TjdT/8vuSRxgnfJX9dOoHxn65A0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yLF6P/dJMb996TjdT/8vuSRxgnfJX9dOoHxn65A0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yLF6P/dJMb996TjdT/8vuSRxgnfJX9dOoHxn65A0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyLF6P%2FdJMb996TjdT%2F8vuSRxgnfJX9dOoHxn65A0%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;674&quot; height=&quot;588&quot; data-filename=&quot;Screenshot 2026-03-28 at 1.11.45 PM.png&quot; data-origin-width=&quot;674&quot; data-origin-height=&quot;588&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Structure Metrics&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-28 at 1.12.54 PM.png&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cW1E8w/dJMcaaShLrq/BBwkoyMH6mzbIbkqkQLP8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cW1E8w/dJMcaaShLrq/BBwkoyMH6mzbIbkqkQLP8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cW1E8w/dJMcaaShLrq/BBwkoyMH6mzbIbkqkQLP8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcW1E8w%2FdJMcaaShLrq%2FBBwkoyMH6mzbIbkqkQLP8k%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;562&quot; height=&quot;696&quot; data-filename=&quot;Screenshot 2026-03-28 at 1.12.54 PM.png&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;696&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;2. evidence 라벨 학습 x, evidence 관련 프롬프트 제거, evidence 관련 후처리 제거, 최종 출력에서 evidence 키 제거 후 평가 x&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ROUGE,BERTscore&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-28 at 1.15.54 PM.png&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/coMn2u/dJMcajhj2Fc/Q7N92567KrTbPL3qVuNJg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/coMn2u/dJMcajhj2Fc/Q7N92567KrTbPL3qVuNJg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/coMn2u/dJMcajhj2Fc/Q7N92567KrTbPL3qVuNJg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcoMn2u%2FdJMcajhj2Fc%2FQ7N92567KrTbPL3qVuNJg0%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;342&quot; data-filename=&quot;Screenshot 2026-03-28 at 1.15.54 PM.png&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;342&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-28 at 1.16.09 PM.png&quot; data-origin-width=&quot;554&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHwQJQ/dJMcaivXzvN/5j2B1SjZSx8nxljdJB4qfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHwQJQ/dJMcaivXzvN/5j2B1SjZSx8nxljdJB4qfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHwQJQ/dJMcaivXzvN/5j2B1SjZSx8nxljdJB4qfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHwQJQ%2FdJMcaivXzvN%2F5j2B1SjZSx8nxljdJB4qfk%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;554&quot; height=&quot;300&quot; data-filename=&quot;Screenshot 2026-03-28 at 1.16.09 PM.png&quot; data-origin-width=&quot;554&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM as a Judge&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-28 at 1.17.46 PM.png&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;590&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tMg1f/dJMcaarcDV9/IEXNTfDwdYMyNKdwhaJIaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tMg1f/dJMcaarcDV9/IEXNTfDwdYMyNKdwhaJIaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tMg1f/dJMcaarcDV9/IEXNTfDwdYMyNKdwhaJIaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtMg1f%2FdJMcaarcDV9%2FIEXNTfDwdYMyNKdwhaJIaK%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;620&quot; height=&quot;590&quot; data-filename=&quot;Screenshot 2026-03-28 at 1.17.46 PM.png&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;590&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Structure Metrics&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-28 at 1.18.31 PM.png&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;702&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6t4Y3/dJMcaibIebU/ZO1aPSn19N8KbwWMyRpkY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6t4Y3/dJMcaibIebU/ZO1aPSn19N8KbwWMyRpkY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6t4Y3/dJMcaibIebU/ZO1aPSn19N8KbwWMyRpkY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6t4Y3%2FdJMcaibIebU%2FZO1aPSn19N8KbwWMyRpkY0%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;702&quot; data-filename=&quot;Screenshot 2026-03-28 at 1.18.31 PM.png&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;702&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>
      <author>jayvi.oh</author>
      <guid isPermaLink="true">https://tasteam.tistory.com/44</guid>
      <comments>https://tasteam.tistory.com/44#entry44comment</comments>
      <pubDate>Sat, 28 Mar 2026 13:19:17 +0900</pubDate>
    </item>
    <item>
      <title>[AI] 고빈도 동시 처리 상황에서 Model Load 초기화 Race로 인한 hard-death를 해결하자!</title>
      <link>https://tasteam.tistory.com/25</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;배경&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아키텍쳐 선택을 위해 동기, 비동기 파이프라인 각각에 대해 부하테스트(ramp-up test)를 수행.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;new_sync 파이프라인 요약 (완전 동기)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배치 내 단일 파이프라인 내 동기, 배치 내 단일 파이프라인 간 동기&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;new_async 파이프라인 요약 (완전 비동기)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배치 내 단일 파이프라인 내 비동기, 배치 내 단일 파이프라인 간 비동기&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결과&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;sync와 async가 다운된 이유(로그 분석)&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1) new_sync: &amp;ldquo;모델 파일이 없어서&amp;rdquo; 바로 예외로 터짐 (NoSuchFile)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;new_sync는 요청 처리 중 &lt;code&gt;get_vector_search &amp;rarr; VectorSearch &amp;rarr; fastembed(TextEmbedding) &amp;rarr; onnxruntime.InferenceSession&lt;/code&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;code&gt;/tmp/fastembed_cache/.../onnx/model.onnx&lt;/code&gt; &lt;b&gt;파일이 없어서&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;onnxruntime ... NoSuchFile&lt;/code&gt; 예외&lt;/li&gt;
&lt;li&gt;그 결과 &lt;code&gt;POST /api/v1/sentiment/analyze/batch&lt;/code&gt; 가 &lt;b&gt;500&lt;/b&gt;으로 떨어지고&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Unhandled exception&amp;rdquo;으로 찍혀 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 전형적으로 &lt;b&gt;다운로드/캐시가 아직 완성되기 전에 로드하려 했거나&lt;/b&gt;, 캐시가 깨졌거나, 경로가 휘발(&lt;code&gt;/tmp&lt;/code&gt;)이라 컨테이너 생명주기/동시성에 취약할 때 나옴.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2) new_async: NoSuchFile은 안 보이는데 &amp;ldquo;로드가 여러 번&amp;rdquo; 일어남 (중복 초기화/동시 초기화 정황)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;new_async 로그에는 같은 임베딩 모델이&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;Dense 벡터 모델 로드 완료&lt;/code&gt;가 &lt;b&gt;여러 번 반복&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, new_async는 &amp;ldquo;파일이 없어서 즉시 폭발&amp;rdquo;보다는,&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;여러 요청/태스크가 동시에 들어오면서 VectorSearch(또는 임베딩 모델)가 중복 초기화되는 정황&lt;/b&gt;이 더 강해 보임.&lt;/li&gt;
&lt;li&gt;이 상태도 결국 &lt;b&gt;캐시 다운로드/로드 race&lt;/b&gt;를 만들기 쉬워서, 타이밍 나쁘면 new_sync처럼 NoSuchFile로도 이어질 수 있음(이번 로그에선 그 전에 &amp;ldquo;운 좋게&amp;rdquo; 로드가 성공했을 가능성이 큼).&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;결론: &amp;ldquo;로그가 다르다&amp;rdquo; = 파이프라인 문제가 아니라, &lt;b&gt;공통 원인(임베딩 모델 캐시/초기화 레이스)&lt;/b&gt;가 다른 형태로 표출된 것&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;new_sync는 &lt;b&gt;첫 로드 타이밍이 더 공격적/동시성에 더 취약&lt;/b&gt;해서 &amp;ldquo;파일 없음&amp;rdquo;으로 터진 흔적이 명확하고&lt;/li&gt;
&lt;li&gt;new_async는 &lt;b&gt;중복 로드(동시 초기화)&lt;/b&gt;가 보이고 , 당장 NoSuchFile은 안 찍혔지만 구조적으로 안전하다고 보긴 어려움.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;아키텍쳐 선택에 대한 현실적인 답&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 로그만으로 &amp;ldquo;new_async가 더 낫다/ new_sync가 더 낫다&amp;rdquo;를 &lt;b&gt;아키텍처 선택 근거로 쓰긴 약함.&lt;/b&gt;&lt;br /&gt;대신 이 로그로는 &lt;b&gt;&amp;ldquo;선택 전에 반드시 고쳐야 할 공통 결함&amp;rdquo;&lt;/b&gt;이 드러났다고 보는 게 정확함:&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;반드시 고칠 것 (둘 다 해당)&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;VectorSearch(임베딩 모델)도 sentiment처럼 싱글톤 초기화 락(DCL) 적용&lt;/b&gt;&lt;br /&gt;&amp;rarr; 초기화 구간에 &lt;b&gt;동시 진입을 막는 락/세마포어&lt;/b&gt;로 중복 로드&amp;middot;캐시 race 제거.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;서버 시작 시 preload/warm-up&lt;/b&gt;&lt;br /&gt;&amp;rarr; &lt;b&gt;모델 + 토크나이저 + 첫 inference까지&lt;/b&gt; 강제 warm-up해서 &amp;ldquo;첫 요청에서 다운로드/로드&amp;rdquo;가 일어나지 않게.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;캐시 경로를 /tmp가 아니라 볼륨으로 고정&lt;/b&gt;&lt;br /&gt;&amp;rarr; HF/ONNX 캐시가 &lt;b&gt;공유 볼륨&lt;/b&gt;(또는 이미지 bake-in)으로 안정적으로 존재하도록 (컨테이너 재시작/동시성에 덜 취약).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;readiness(준비됨) 되기 전까지 트래픽을 안 받음&lt;/b&gt;&lt;br /&gt;&amp;rarr; K8s &lt;code&gt;readinessProbe&lt;/code&gt; 등으로 준비 완료 시점을 명시하고, 그 전에는 LB/트래픽이 들어오지 않게.&lt;/li&gt;
&lt;li&gt;(옵션) &lt;b&gt;HF 토큰 설정&lt;/b&gt;해서 rate limit/불안정 다운로드 가능성 줄이기 (로그에도 unauth 경고가 보임).&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 한 뒤에야 &amp;ldquo;sync vs async&amp;rdquo; 성능/안정성 비교가 &lt;b&gt;의미 있게&lt;/b&gt; 됌.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드로 전부 반영했을 때의 이점&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 안정성 (ramp-up&amp;middot;재시작)&lt;/h3&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;이점&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;싱글톤 락 + 초기화 락&lt;/td&gt;
&lt;td&gt;ramp-up 시 여러 요청이 동시에 임베딩/모델 로드를 트리거하지 않음 &amp;rarr; &lt;b&gt;중복 로드&amp;middot;캐시 race 제거&lt;/b&gt; &amp;rarr; NoSuchFile/ONNX 에러 감소.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;warm-up(모델+토크나이저+첫 inference)&lt;/td&gt;
&lt;td&gt;첫 실제 요청에서 로드가 일어나지 않음 &amp;rarr; &lt;b&gt;첫 요청 타임아웃/500&lt;/b&gt; 가능성 감소.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;캐시 볼륨/이미지 고정&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/tmp&lt;/code&gt; 휘발&amp;middot;재시작 시 캐시 소실 방지 &amp;rarr; &lt;b&gt;재시작 후에도 즉시 서빙&lt;/b&gt;, 다운로드 재시도로 인한 불안정 감소.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;readiness 전까지 트래픽 차단&lt;/td&gt;
&lt;td&gt;모델/캐시 준비 전에 요청이 들어오지 않음 &amp;rarr; &lt;b&gt;&quot;아직 준비 안 된 서버&quot;에 부하&lt;/b&gt;가 걸리는 상황 자체가 사라짐.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; ramp-up/재시작 시 &lt;b&gt;크래시&amp;middot;soft-death 확률 감소&lt;/b&gt;, 로그에서 보이던 실패 패턴이 재현되기 어려워짐.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 실서비스 측면 이점&lt;/h3&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;이점&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;가용성&amp;middot;SLA&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;롤링 배포&amp;middot;스케일아웃 시 &amp;ldquo;준비 안 된 인스턴스&amp;rdquo;에 트래픽이 가지 않음 &amp;rarr; &lt;b&gt;500/타임아웃 감소&lt;/b&gt;. 피크/갑작스런 트래픽에서도 중복 초기화로 인한 크래시 가능성 감소.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;사용자 체감(UX)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;첫 요청에서 cold start가 발생하지 않음 &amp;rarr; &lt;b&gt;첫 요청 지연&amp;middot;간헐적 500&amp;middot;재시도&lt;/b&gt; 감소.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;운영&amp;middot;배포&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;언제 트래픽 받을 수 있는지&amp;rdquo;가 명확해져 롤링 업데이트&amp;middot;오토스케일 시 동작이 예측 가능. 재시작 후 캐시 유지로 &lt;b&gt;복구 시간(RTO)&lt;/b&gt; 단축. 레이스 컨디션 성 장애 감소.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;비용&amp;middot;리소스&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;캐시 재다운로드 감소 &amp;rarr; 네트워크&amp;middot;스토리지&amp;middot;기동 시간 절감. 준비 전 트래픽 차단으로 불필요한 재시도&amp;middot;CPU 사용 감소.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; &lt;b&gt;실서비스에서도&lt;/b&gt; 가용성, 체감 품질, 운영성, 비용 측면에서 이득이 있음.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;new_async가 다운된 이유 (요약)(로그+코드 포함 분석)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;원인&lt;/b&gt;: new_sync와 같은 &lt;b&gt;임베딩 모델 캐시/초기화 레이스&lt;/b&gt;인데, &lt;b&gt;async 구조 때문에 동시 진입이 더 많이 일어나서&lt;/b&gt; 더 빨리/같이 죽은 것.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) 로그에서 보인 것 (new_sync와의 차이)&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;new_sync&lt;/b&gt;: &lt;code&gt;NoSuchFile&lt;/code&gt; (onnx 파일 없음) &amp;rarr; 바로 크래시.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;new_async&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;NoSuchFile&lt;/code&gt;이 &lt;b&gt;안 보이거나&lt;/b&gt;,&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;code&gt;Dense 벡터 모델 로드 완료&lt;/code&gt;가 여러 번 반복&lt;/b&gt; (같은 모델이 중복 로드되는 정황).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, new_async는 &amp;ldquo;한 번에 파일 없음으로 터진다&amp;rdquo;기보다 &lt;b&gt;여러 요청이 동시에&lt;/b&gt; &lt;code&gt;get_vector_search&lt;/code&gt; / VectorSearch 초기화를 타면서 &lt;b&gt;중복 초기화&amp;middot;캐시 race&lt;/b&gt;가 난 상황.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) 왜 async에서 더 심해졌나&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;async&lt;/b&gt; &amp;rarr; ramp-up 시 &lt;b&gt;여러 요청이 동시에&lt;/b&gt; 들어옴.&lt;/li&gt;
&lt;li&gt;그때 &lt;b&gt;VectorSearch 싱글톤에 락이 없었음&lt;/b&gt; &amp;rarr; 여러 코루틴이 동시에 &amp;ldquo;아직 없네?&amp;rdquo; 하고 &lt;b&gt;여러 번 생성 시도&lt;/b&gt; 또는 &lt;b&gt;동시에 같은 캐시/모델 로드&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;그 결과:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐시 다운로드/캐시 쓰기 &lt;b&gt;race&lt;/b&gt; 발생,&lt;/li&gt;
&lt;li&gt;타이밍 나쁘면 new_sync처럼 &lt;b&gt;NoSuchFile/로딩 실패 &amp;rarr; 프로세스 크래시&lt;/b&gt;로 이어짐.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서 표현 그대로면, &lt;b&gt;&amp;ldquo;구조적으로 async가 더 빨리 죽었을 가능성 높음&amp;rdquo;&lt;/b&gt;.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3) 한 줄로 정리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;new_async가 다운된 이유&lt;/b&gt;&lt;br /&gt;= &lt;b&gt;임베딩(및 HF/ONNX) 캐시&amp;middot;초기화 레이스&lt;/b&gt;가 근본 원인이고,&lt;br /&gt;async라서 &lt;b&gt;동시에 많은 요청이 초기화를 트리거&lt;/b&gt;해 그 레이스가 더 잘 걸리고, 결국 &lt;b&gt;로딩 실패/크래시(hard-death)&lt;/b&gt; 로 이어진 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 문서에서 &lt;b&gt;VectorSearch DCL 락, warm-up, 캐시 경로, readiness&lt;/b&gt;를 &amp;ldquo;반드시 고칠 것&amp;rdquo;으로 넣고, 그걸 코드에도 반영한 상태.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서와 로그 해석 기준으로 보면, &lt;b&gt;&amp;ldquo;왜 new_async에서는 NoSuchFile이 안 떴는지&amp;rdquo;&lt;/b&gt;는 두 가지로 설명할 수 있음.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 타이밍/운 &amp;mdash; &amp;ldquo;그 전에 로드가 성공했을 가능성&amp;rdquo;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서에 나온 대로:&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 상태도 결국 &lt;b&gt;캐시 다운로드/로드 race&lt;/b&gt;를 만들기 쉬워서, &lt;b&gt;타이밍 나쁘면&lt;/b&gt; new_sync처럼 NoSuchFile로도 이어질 수 있어(&lt;b&gt;이번 로그에선 그 전에 &quot;운 좋게&quot; 로드가 성공했을 가능성이 큼&lt;/b&gt;).&lt;/p&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;b&gt;new_sync&lt;/b&gt;: 요청이 &lt;b&gt;순차&lt;/b&gt;로 들어와서, &lt;b&gt;첫 요청이 너무 일찍&lt;/b&gt; 모델 로드를 시도 &amp;rarr; 캐시 다운로드가 끝나기 전에 &lt;code&gt;model.onnx&lt;/code&gt;를 열려다 &amp;rarr; &lt;b&gt;NoSuchFile&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;new_async&lt;/b&gt;: 요청이 &lt;b&gt;동시에&lt;/b&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;b&gt;어느 하나가 먼저&lt;/b&gt; 다운로드/로드를 끝내고&lt;/li&gt;
&lt;li&gt;나머지는 그 &lt;b&gt;뒤에&lt;/b&gt; 로드를 시도해, 그때는 이미 파일이 있어서 &lt;b&gt;NoSuchFile이 안 나온&lt;/b&gt; 경우.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, &lt;b&gt;같은 race가 있어도 &amp;ldquo;파일 없을 때 로드&amp;rdquo;를 누가 먼저 겪느냐&lt;/b&gt;가 sync/async 타이밍에 따라 달라져서,&lt;br /&gt;이번 new_async 로그에서는 &lt;b&gt;NoSuchFile이 발생하기 전에, 어떤 요청이 &amp;ldquo;운 좋게&amp;rdquo; 로드에 성공한 타이밍&lt;/b&gt;이었을 수 있다는 뜻.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 다른 이유로 먼저 죽었을 수 있음&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;new_async는 &lt;b&gt;중복 초기화&lt;/b&gt;(&lt;code&gt;Dense 벡터 모델 로드 완료&lt;/code&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;/b&gt;(중복 로드, 리소스 부족, 레이스로 인한 다른 에러)로 프로세스가 먼저 죽었거나&lt;/li&gt;
&lt;li&gt;&lt;b&gt;NoSuchFile이 나올 경로&lt;/b&gt;(예: 나중에 오는 요청이 아직 캐시가 안 된 상태에서 로드 시도)까지 가지 못하고 크래시했을 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;그러면 &lt;b&gt;로그에는 NoSuchFile이 안 찍히고&lt;/b&gt;, &amp;ldquo;여러 번 로드 완료&amp;rdquo;만 보이다가 그다음에 죽은 형태가 됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&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;b&gt;구조적으로는&lt;/b&gt; new_async도 new_sync와 같은 &lt;b&gt;캐시/초기화 레이스&lt;/b&gt; 때문에 NoSuchFile이 날 수 있는 상황.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;이번 로그에서 NoSuchFile이 안 보인 이유&lt;/b&gt;는:
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;타이밍&lt;/b&gt; &amp;mdash; 동시 요청 중 일부가 &amp;ldquo;캐시 준비된 뒤&amp;rdquo; 로드를 시도해서, 이번 런에서는 NoSuchFile이 안 나왔을 가능성(문서의 &amp;ldquo;운 좋게 로드 성공&amp;rdquo;),&lt;/li&gt;
&lt;li&gt;&lt;b&gt;또는&lt;/b&gt; 그 전에 &lt;b&gt;중복 초기화/다른 예외로 프로세스가 죽어서&lt;/b&gt;, NoSuchFile이 발생할 기회가 없었을 가능성,&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘 다 설득력 있습니다. 그래서 문서에서 &amp;ldquo;당장 NoSuchFile은 안 찍혔지만 &lt;b&gt;구조적으로 안전하다고 보긴 어려워&lt;/b&gt;&amp;rdquo;라고 한 것.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;new_sync vs new_async &amp;mdash; 죽는 방식 비교&lt;/h2&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;new_sync&lt;/th&gt;
&lt;th&gt;new_async&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;로그에 보이는 것&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NO_SUCHFILE&lt;/code&gt;, &lt;code&gt;Load model ... onnx/model.onnx failed. File doesn't exist&lt;/code&gt; &amp;rarr; &lt;b&gt;Unhandled exception&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Dense 벡터 모델 로드 완료&lt;/code&gt;가 &lt;b&gt;여러 번 반복&lt;/b&gt; (중복 초기화). NoSuchFile은 &lt;b&gt;안 보일 수 있음&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;트리거&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;(상대적으로) &lt;b&gt;순차&lt;/b&gt; 요청 중, &lt;b&gt;너무 이른&lt;/b&gt; 요청이 모델 로드를 시도&lt;/td&gt;
&lt;td&gt;&lt;b&gt;동시에 많은 요청&lt;/b&gt;이 들어와서 &lt;b&gt;여러 코루틴이 한꺼번에&lt;/b&gt; VectorSearch/모델 로드 트리거&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;직접 원인&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;캐시 다운로드 &lt;b&gt;끝나기 전에&lt;/b&gt; 한 요청이 &lt;code&gt;model.onnx&lt;/code&gt; 로드 시도 &amp;rarr; 파일 없음 &amp;rarr; 예외&lt;/td&gt;
&lt;td&gt;여러 요청이 &lt;b&gt;동시에&lt;/b&gt; 초기화 &amp;rarr; &lt;b&gt;중복 로드&amp;middot;캐시 race&lt;/b&gt; &amp;rarr; 그 과정에서 실패/크래시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;결과&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;Hard-death&lt;/b&gt;: unhandled exception &amp;rarr; 프로세스 종료 &amp;rarr; 컨테이너 사라짐&lt;/td&gt;
&lt;td&gt;&lt;b&gt;Hard-death&lt;/b&gt;: 같은 근본 원인(캐시/초기화 레이스)으로 역시 프로세스 종료. &amp;ldquo;더 빨리&amp;rdquo; 죽었을 가능성&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&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;b&gt;new_sync&lt;/b&gt;:&lt;br /&gt;&amp;ldquo;&lt;b&gt;한 요청이 너무 일찍&lt;/b&gt; 로드 시도 &amp;rarr; &lt;b&gt;NoSuchFile로 바로 터짐&lt;/b&gt;&amp;rdquo;이 로그에 그대로 찍힌 &lt;b&gt;명백한 크래시&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;new_async&lt;/b&gt;:&lt;br /&gt;&amp;ldquo;&lt;b&gt;여러 요청이 동시에&lt;/b&gt; 초기화를 타서 &lt;b&gt;로드가 여러 번&lt;/b&gt; 돌고, 그 레이스로 &lt;b&gt;같은 종류의 크래시&lt;/b&gt;&amp;rdquo;가 나지만,&lt;br /&gt;로그에는 &lt;b&gt;중복 로드&lt;/b&gt;가 먼저 보이고, NoSuchFile은 안 보이거나 다른 예외로 죽을 수 있음.&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;new_sync = &lt;b&gt;&amp;ldquo;너무 이른 한 번의 로드&amp;rdquo;&lt;/b&gt; &amp;rarr; NoSuchFile로 확실히 죽음.&lt;/li&gt;
&lt;li&gt;new_async = &lt;b&gt;&amp;ldquo;동시에 여러 번 로드&amp;rdquo;&lt;/b&gt; &amp;rarr; 중복 초기화 정황으로 죽음.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;죽는 방식(로그&amp;middot;트리거)만 다르고, 둘 다 hard-death*&lt;/i&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;1. 아키텍쳐 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;new_async 선택. 왜냐면, 비동기 아키텍쳐가 프로세스가 OOM으로 죽지 않게 해주기 때문에 비동기 아키텍쳐를 선택했다. 그러고, 위에서 말한 현재 비동기 아키텍쳐의 문제점을 해결하면 된다.&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. new_async 메커니즘 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Race Condition이 원인이라는 걸 알았으니 결론은 하나, 위에서 말했듯, 모델을 start-up 단계에서 로드하는 식으로 변경해. 앱이 모델 다운로드를 먼저 진행하고, 켜지는 방식이다. 이를 통해 콜드 스타트로 인한 Race Condition을 막는다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 추가적으로 비동기에서 최대한 OOM으로 죽지 않게 하려는 여러 조치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 비동기 방식으로 이벤트 루프가 돌 때, 동기 호출이 안에 있다면, 루프는 반드시 막히고, 결국 그게 OOM으로 이어진다.&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;a. 스레드 블로킹을 LLM에게도 적용.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존엔 스레드 블로킹이 sentiment 모델만 필요한 줄 알았지만, 모델은 기본적으로 sync 연산이다. 따라서, LLM도 마찬가지고, 따라서, LLM에 대해서도 to_thread()를 적용해 스레드 블로킹을 적용한다.&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;b. 비동기큐 설정과 워커 설정과 세마포 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 세마포는 설정이 안되어 있었다. 비동기 루프로 돌거면, 세마포는 사실 필수다. 왜냐면, 만약 세마포가 없다면, 동시처리 수가 늘어나는데, 그 처리가 감당 가능한 양을 벗어난다면, OOM이 발생한다. 비동기큐는 개인적으로는 요청을 비동기 루프에서 명시적으로 관리할 수 있기에 필수라고 생각한다. 또한, 비동기 루프 안에 sync 연산인 sentiment 모델이나, LLM이 있다면, async 연산처럼 볼수가 없기 때문에, 처리 성능에 대한 명시적 관리가 필요하다. 그 역할을 비동기큐가 한다고 생각한다. 구체적으로 말하면, 현재 LLM의 태스크는 리뷰 요약 태스크이기 때문에, 길이에 따라 연산의 양이 달라진다. 그럼, 큐이기 때문에 Starvation 문제가 발생할 가능성이 높다. 이에 대해 기본 셋팅인 FIFO말고 라운드로빈 방식을 적용해 볼수도 있고, 필요하면 리뷰 길이에 따라 큐의 순서를 다르게 하는 커스텀 메커니즘을 짜는 것도 가능하다. 워커는 동시처리를 위해 존재한다. 워커가 있어야 sync 연산인 모델 연산도 동시처리가 가능해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>jayvi.oh</author>
      <guid isPermaLink="true">https://tasteam.tistory.com/25</guid>
      <comments>https://tasteam.tistory.com/25#entry25comment</comments>
      <pubDate>Tue, 3 Mar 2026 17:22:23 +0900</pubDate>
    </item>
    <item>
      <title>[AI] GC(Garbage Collection)과 Batch size 변경으로 GPU 메모리 확보를 해보자!</title>
      <link>https://tasteam.tistory.com/24</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;0. GC(Garbage Collection)란?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GC(Garbage Collection)는 프로그램이 더 이상 참조하지 않는 객체를 자동으로 메모리에서 해제하는 메모리 관리 메커니즘이다.&lt;br /&gt;Python은 기본적으로 Reference Counting 방식을 사용하며, 순환 참조는 별도의 GC가 주기적으로 회수한다.&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;1. Trouble Shooting&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Eval&amp;nbsp;단계에서&amp;nbsp;OOM&amp;nbsp;(가장&amp;nbsp;빈번)&lt;/p&gt;
&lt;div style=&quot;background-color: #181818; color: #e4e4e4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;2026-03-01T00:35:51.150992577Z&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; torch.OutOfMemoryError: CUDA out of memory. Tried to allocate 9.27 GiB. GPU 0 has a total capacity of 23.52 GiB of which 7.48 GiB is free. Including non-PyTorch memory, this process has 16.03 GiB memory in use. Of the allocated memory 15.09 GiB is allocated by PyTorch, and 483.26 MiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (&lt;a href=&quot;https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)&quot;&gt;https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CUDA가 Out Of Memory가 발생했다. 현재 GPU는 23.52 GiB가 총 수용량이고, 7.48 GiB가 Free 지만, 9.27 GiB를 할당하려고 한다. 어떠한 파이토치 메모리도 포함되어 있지 않다면, 이 프로세스는 16.03 GiB 메모리를 사용 중이다. 할당된 15.09 GiB 메모리는 파이토치에 의해 할당 됐고, 483.26 MiB는 파이토치로 부터 예약됐지만, 할당되지는 않았다. 만약, 예약됐지만, 할당되지 않은 메모리가 크다면, 파편화를 피하기 위해, PYTORCH_CUDA_ALLOC)CONF=expandable_segments를 설정해라. 메모리 관리에 대한 문서는 이러하다. &lt;a href=&quot;https://pytorch.org/docs/stable/notes/cuda.html#environment-variables&quot;&gt;https://pytorch.org/docs/stable/notes/cuda.html#environment-variables&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1772520407263&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;CUDA semantics &amp;mdash; PyTorch 2.10 documentation&quot; data-og-description=&quot;CUDA semantics Created On: Jan 16, 2017 | Last Updated On: Dec 09, 2025 torch.cuda is used to set up and run CUDA operations. It keeps track of the currently selected GPU, and all CUDA tensors you allocate will by default be created on that device. The sel&quot; data-og-host=&quot;docs.pytorch.org&quot; data-og-source-url=&quot;https://pytorch.org/docs/stable/notes/cuda.html#environment-variables&quot; data-og-url=&quot;https://docs.pytorch.org/docs/stable/notes/cuda.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://pytorch.org/docs/stable/notes/cuda.html#environment-variables&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pytorch.org/docs/stable/notes/cuda.html#environment-variables&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;CUDA semantics &amp;mdash; PyTorch 2.10 documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CUDA semantics Created On: Jan 16, 2017 | Last Updated On: Dec 09, 2025 torch.cuda is used to set up and run CUDA operations. It keeps track of the currently selected GPU, and all CUDA tensors you allocate will by default be created on that device. The sel&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.pytorch.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;div style=&quot;background-color: #181818; color: #e4e4e4;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;background-color: #181818; color: #e4e4e4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #d6d6dd;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #f8c762;&quot;&gt;**발생**&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: step 100 근처 첫 eval 시&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d6d6dd;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #f8c762;&quot;&gt;**메시지**&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;`Tried to allocate 9.27 GiB. GPU 0 has a total capacity of 23.52 GiB of which 7.48 GiB is free.`&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d6d6dd;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #f8c762;&quot;&gt;**원인**&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: eval 시 gradient checkpointing 미적용, 기본 batch_size로 학습과 동일하게 사용 &amp;rarr; 추가 ~9GB 필요&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #f8c762;&quot;&gt;**적용한 대응**&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;`per_device_eval_batch_size=1`&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; 설정 (train_qlora.py)&lt;/span&gt;&lt;/div&gt;
&lt;/div&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. 이전&amp;nbsp;run&amp;nbsp;OOM&amp;nbsp;이후&amp;nbsp;&quot;Some&amp;nbsp;modules&amp;nbsp;dispatched&amp;nbsp;on&amp;nbsp;CPU&quot;&lt;/p&gt;
&lt;div style=&quot;background-color: #181818; color: #e4e4e4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;2026-03-01T00:36:12.384434846Z&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; ValueError: Some modules are dispatched on the CPU or the disk. Make sure you have enough GPU RAM to fit the quantized model. If you want to dispatch the model on the CPU or the disk while keeping these modules in 32-bit, you need to set `llm_int8_enable_fp32_cpu_offload=True` and pass a custom `device_map` to `from_pretrained`. Check &lt;a href=&quot;https://huggingface.co/docs/transformers/main/en/main_classes/quantization#offload-between-cpu-and-gpu&quot;&gt;https://huggingface.co/docs/transformers/main/en/main_classes/quantization#offload-between-cpu-and-gpu&lt;/a&gt; for more details.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몇몇 모듈이 디스크의 CPU에서 디스패치 됐다. 너의 양자화된 모델에 맞는 충분한 GPU 램을 확보해라. 이 모듈들이 32 비트를 지키면서 CPU나 디스크에서 디스패치 하고 싶다면, 너는 'llm_int8_enable_fp32_cpu_offload=True'를 설정하거나, 커스텀 'device_map'을 'from_pretrained'로 넘겨라. 더 많은 세부 사항을 알고 싶으면 &lt;a href=&quot;https://huggingface.co/docs/transformers/main/en/main_classes/quantization#offload-between-cpu-and-gpu&quot;&gt;https://huggingface.co/docs/transformers/main/en/main_classes/quantization#offload-between-cpu-and-gpu&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1772521174328&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;Quantization&quot; data-og-description=&quot;We&amp;rsquo;re on a journey to advance and democratize artificial intelligence through open source and open science.&quot; data-og-host=&quot;huggingface.co&quot; data-og-source-url=&quot;https://huggingface.co/docs/transformers/main/en/main_classes/quantization#offload-between-cpu-and-gpu&quot; data-og-url=&quot;https://huggingface.co/docs/transformers/main/en/main_classes/quantization&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/l46fR/dJMb88eYezD/CK4jOuiDUH37IUpljTYBY0/img.png?width=1200&amp;amp;height=648&amp;amp;face=0_0_1200_648,https://scrap.kakaocdn.net/dn/bNPMxy/dJMb84XWj0d/sxHkLtziHlQukrIEOVQcSK/img.png?width=1200&amp;amp;height=648&amp;amp;face=0_0_1200_648&quot;&gt;&lt;a href=&quot;https://huggingface.co/docs/transformers/main/en/main_classes/quantization#offload-between-cpu-and-gpu&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://huggingface.co/docs/transformers/main/en/main_classes/quantization#offload-between-cpu-and-gpu&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/l46fR/dJMb88eYezD/CK4jOuiDUH37IUpljTYBY0/img.png?width=1200&amp;amp;height=648&amp;amp;face=0_0_1200_648,https://scrap.kakaocdn.net/dn/bNPMxy/dJMb84XWj0d/sxHkLtziHlQukrIEOVQcSK/img.png?width=1200&amp;amp;height=648&amp;amp;face=0_0_1200_648');&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;Quantization&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;We&amp;rsquo;re on a journey to advance and democratize artificial intelligence through open source and open science.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;huggingface.co&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #181818; color: #e4e4e4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #d6d6dd;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #f8c762;&quot;&gt;**발생**&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: OOM 후 같은 프로세스에서 다음 run 시작 시 &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;`from_pretrained(..., device_map=&quot;auto&quot;)`&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d6d6dd;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #f8c762;&quot;&gt;**원인**&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: GPU 메모리 비정상/파편화 &amp;rarr; device_map이 일부 CPU로 보냄, 4bit BNB는 CPU 오프로드 미지원&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #f8c762;&quot;&gt;**적용한 대응**&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: run_train 시작 시 &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;`gc.collect()`&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; + &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;`torch.cuda.empty_cache()`&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; (train_qlora.py)&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&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. batch_size=4&amp;nbsp;+&amp;nbsp;max_seq_length=2048&amp;nbsp;조합&amp;nbsp;OOM&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #181818; color: #e4e4e4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;2026-03-01T00:35:58.459956338Z&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; torch.OutOfMemoryError: CUDA out of memory. Tried to allocate 3.79 GiB. GPU 0 has a total capacity of 23.52 GiB of which 391.75 MiB is free. Including non-PyTorch memory, this process has 23.12 GiB memory in use. Of the allocated memory 22.35 GiB is allocated by PyTorch, and 314.64 MiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (&lt;a href=&quot;https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)&quot;&gt;https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&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번과 동일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #181818; color: #e4e4e4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #d6d6dd;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #f8c762;&quot;&gt;**발생**&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: 학습 첫 스텝에서 &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;`22.35 GiB allocated`&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;, 24GB 초과&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #f8c762;&quot;&gt;**적용한 대응**&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: sweep에서 &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;`batch_size`&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;를 &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;`[1, 2]`&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;로 제한 (wandb_sweep_qlora.yaml)&lt;/span&gt;&lt;/div&gt;
&lt;/div&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;div style=&quot;background-color: #181818; color: #e4e4e4;&quot;&gt;&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;| 원인 | 적용 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;|------|------|&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;| Eval OOM | per_device_eval_batch_size=1 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;| 연쇄 실패 (CPU 디스패치) | run_train 시작 시 gc + empty_cache |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;| batch_size 4 OOM | batch_size values: [1, 2] |&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;</description>
      <author>jayvi.oh</author>
      <guid isPermaLink="true">https://tasteam.tistory.com/24</guid>
      <comments>https://tasteam.tistory.com/24#entry24comment</comments>
      <pubDate>Tue, 3 Mar 2026 16:03:02 +0900</pubDate>
    </item>
    <item>
      <title>[AI] Prefect로 지식증류(Knowledge Distillation) 파이프라인을 완전 자동화 해보자!</title>
      <link>https://tasteam.tistory.com/21</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;0. Prefect란?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img style=&quot;text-align: center; caret-color: transparent; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot; src=&quot;https://blog.kakaocdn.net/dna/9IY9Y/dJMcajnJOZ3/AAAAAAAAAAAAAAAAAAAAAFc2SrfJV4exeVWPzk3rPpmwJy0DZZsqp5308VvpaLRb/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1774969199&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=xA43uk6yIHtsVFRvqAtdIjDeExU%3D&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;1558&quot; data-origin-height=&quot;258&quot; data-filename=&quot;Screenshot 2026-03-02 at 1.17.14 PM.png&quot; /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.prefect.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.prefect.io/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1772424710253&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;Prefect - Workflow Orchestration &amp;amp; AI Infrastructure&quot; data-og-description=&quot;Orchestrate workflows with Prefect. Build AI applications with Horizon. Open-source foundations, production-ready platforms.&quot; data-og-host=&quot;www.prefect.io&quot; data-og-source-url=&quot;https://www.prefect.io/&quot; data-og-url=&quot;https://www.prefect.io&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/xCvKe/dJMb9gxiR8w/SlvKNhFI5bT10YxozEuepK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bTh4nv/dJMb9lk4C7B/leHNqpe54oqG5Y9PQa2oFk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/NG4Wh/dJMb9frCWCC/botXO5QEKRRj56rxDSc6pk/img.png?width=3522&amp;amp;height=864&amp;amp;face=0_0_3522_864&quot;&gt;&lt;a href=&quot;https://www.prefect.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.prefect.io/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/xCvKe/dJMb9gxiR8w/SlvKNhFI5bT10YxozEuepK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bTh4nv/dJMb9lk4C7B/leHNqpe54oqG5Y9PQa2oFk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/NG4Wh/dJMb9frCWCC/botXO5QEKRRj56rxDSc6pk/img.png?width=3522&amp;amp;height=864&amp;amp;face=0_0_3522_864');&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;Prefect - Workflow Orchestration &amp;amp; AI Infrastructure&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Orchestrate workflows with Prefect. Build AI applications with Horizon. Open-source foundations, production-ready platforms.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.prefect.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Airflow, Dagster와 동일한 워크플로우 완전 자동화 오케스트레이션 프레임워크이다. 하지만, prefect만의 장점은 Pythonic한 점이고, 데코레이터 기반 동작이라 셋팅이 매우 가볍다. 이러한 특성 때문에, 복잡한 워크플로우와 파이썬 환경에 해당하는 ML 워크플로우에서 가장 사용하기 좋은 오케스트레이션 프레임워크이다.&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;Airflow와 Dagster에 대한 비교는 후술하겠다.&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;(Prefect 공식에도 이 비교에 대한 문서가 존재한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.prefect.io/compare/airflow&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.prefect.io/compare/airflow&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1772425438878&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;Prefect vs Airflow - Modern Workflow Orchestration&quot; data-og-description=&quot;Learn why engineering teams are choosing Prefect over Airflow. 60-70% cost savings, Python-first simplicity, and hybrid architecture that keeps your data in your infrastructure.&quot; data-og-host=&quot;www.prefect.io&quot; data-og-source-url=&quot;https://www.prefect.io/compare/airflow&quot; data-og-url=&quot;https://www.prefect.io/compare/airflow&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c1tNhL/dJMb87f3UQ5/yKK8e0K2By8NwJe2KTPez1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/dlnLfG/dJMb86OZiCS/YRAQDnldBb7eswJn9ZnmiK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/O4jQq/dJMb84XWdM6/y5dE4POlQNe3Zy7KOIYK6K/img.png?width=3795&amp;amp;height=2000&amp;amp;face=0_0_3795_2000&quot;&gt;&lt;a href=&quot;https://www.prefect.io/compare/airflow&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.prefect.io/compare/airflow&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c1tNhL/dJMb87f3UQ5/yKK8e0K2By8NwJe2KTPez1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/dlnLfG/dJMb86OZiCS/YRAQDnldBb7eswJn9ZnmiK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/O4jQq/dJMb84XWdM6/y5dE4POlQNe3Zy7KOIYK6K/img.png?width=3795&amp;amp;height=2000&amp;amp;face=0_0_3795_2000');&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;Prefect vs Airflow - Modern Workflow Orchestration&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Learn why engineering teams are choosing Prefect over Airflow. 60-70% cost savings, Python-first simplicity, and hybrid architecture that keeps your data in your infrastructure.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.prefect.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.prefect.io/compare/dagster&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.prefect.io/compare/dagster&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1772425452142&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;Prefect vs Dagster - Python-First Workflow Orchestration&quot; data-og-description=&quot;Learn why engineering teams are choosing Prefect over Dagster. 60-70% cost savings, days to value vs months, and Python-first simplicity without forced asset restructuring.&quot; data-og-host=&quot;www.prefect.io&quot; data-og-source-url=&quot;https://www.prefect.io/compare/dagster&quot; data-og-url=&quot;https://www.prefect.io/compare/dagster&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bk4mGA/dJMb9fZsND4/9zOE6H60EhxBKKTA8bNCXK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bdxkVi/dJMb9iIEATY/KfTa2HKqukolKdDEmbRuLK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.prefect.io/compare/dagster&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.prefect.io/compare/dagster&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bk4mGA/dJMb9fZsND4/9zOE6H60EhxBKKTA8bNCXK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bdxkVi/dJMb9iIEATY/KfTa2HKqukolKdDEmbRuLK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;Prefect vs Dagster - Python-First Workflow Orchestration&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Learn why engineering teams are choosing Prefect over Dagster. 60-70% cost savings, days to value vs months, and Python-first simplicity without forced asset restructuring.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.prefect.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;p data-ke-size=&quot;size16&quot;&gt;1. 지식증류란?&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;지식증류의 과정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큰 모델로 라벨링을 진행한다. -&amp;gt; 작은 모델이 이 큰 모델이 만든 라벨을 라벨로 삼아 학습을 진행한다 (SFT(Supervised Fine-tunning))&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. 지식증류 파이프라인(+Wandb)&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;a. Labelling&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;처음 고민은, Teacher 모델을 뭐로 할지였다. Student 모델은 Qwen2.5-0.5B-instruct로 정했지만, Teacher 모델은 Openai gpt 모델이어야 할까? 아니면, opensource 모델이지만, 다른 계열인 LLama,Gemma를 써야할까? 아니면, 같은 계열인 Qwen 계열 모델을 사용해야할까?&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Qwen에 같은 Qwen을 학습 시키면, 학습이 편향되지 않을까? Qwen모델은 Alibaba에서 학습 데이터,학습 방식,아키텍쳐를 매번 다르게 쓴다기 보다 기존 데이터에서 확장, 학습 방식,아키텍쳐도 약간의 변경만 발생할텐데, 학습의 편향이 일어나지는 않을까? 즉, 오히려 과적합이 발생하는거 아닐까? 라는 걱정이었다.&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;Openai gpt 모델은 한국어 도메인에 대한 학습이 다른 모델 대비 잘되어 있고, 모델 자체의 성능이 현재 기준 상당히 하이엔드이다. 따라서, 사용하는게 좋은 선택이라는 생각은 들었지만, 내가 기존에 아는 지식증류와는 다른거 같아서 일단 바로 선택을 하지는 않았다.&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;다른 계열 LLama, Gemma에 대한 고려를 진행했지만, 한가지 문제점은, 현재 서빙 프레임워크로 vllm을 사용하는데, 이번에 성능 측정을 진행할때, Qwen모델은 애초에 vllm에 맞게 학습되어 vllm에서 추론이 잘되는 모습을 보였지만, llama, gemma는 vllm과의 호환성이 매우 떨어져 추론 속도도 늦고, 아예 에러를 내놓는 경우도 있었다. 따라서, Qwen의 vllm에 호환성있게 학습된 이 특성이 llama gemma로 부터 학습할때 해쳐지면 어떡하지? 라는 걱정이었다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알아본 바론, 내가 우려한대로 Qwen 모델에 대한 과적합 문제는 발생하지만, 그게 그렇게 치명적인 영향을 주지는 않았다. 또한, 위에서 말한대로 Qwen 모델이 가진 vllm 호환성에 대한 유지를 위해서도, 같은 Qwen 모델을 사용하는게 맞았다. 과적합에 대한 문제를 방지하는 목적으로, 그리고 고품질 라벨을 위한 목적으로, Openai-gpt-4o-mini를 통해 라벨을 생성하되, qwen2.5-7B-instruct 모델도 훈련 라벨을 생성하는 쪽으로 변경했다. Validation label, Test label은 당연히 고품질 라벨인 Openai label을 사용했다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-02 at 1.49.46 PM.png&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;262&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXSBc6/dJMcad18Si6/RkYObkmK0uUoTXkwKNvq30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXSBc6/dJMcad18Si6/RkYObkmK0uUoTXkwKNvq30/img.png&quot; data-alt=&quot;Train data split&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXSBc6/dJMcad18Si6/RkYObkmK0uUoTXkwKNvq30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXSBc6%2FdJMcad18Si6%2FRkYObkmK0uUoTXkwKNvq30%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;500&quot; height=&quot;262&quot; data-filename=&quot;Screenshot 2026-03-02 at 1.49.46 PM.png&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;262&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Train data split&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Train 500 gpt-4o-mini label&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Train 1302 Qwen2.5-7B-instruct&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-02 at 1.51.29 PM.png&quot; data-origin-width=&quot;394&quot; data-origin-height=&quot;158&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AGurE/dJMcaaqShku/HKM0lGQABJ4VqWmmKMSPQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AGurE/dJMcaaqShku/HKM0lGQABJ4VqWmmKMSPQ0/img.png&quot; data-alt=&quot;Val data split&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AGurE/dJMcaaqShku/HKM0lGQABJ4VqWmmKMSPQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAGurE%2FdJMcaaqShku%2FHKM0lGQABJ4VqWmmKMSPQ0%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;394&quot; height=&quot;158&quot; data-filename=&quot;Screenshot 2026-03-02 at 1.51.29 PM.png&quot; data-origin-width=&quot;394&quot; data-origin-height=&quot;158&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Val data split&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Val 944 gpt-4o-mini label&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-02 at 1.52.34 PM.png&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WT7Jm/dJMcahcrNnl/2fPX3WiVMt81xybHCc2Ak1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WT7Jm/dJMcahcrNnl/2fPX3WiVMt81xybHCc2Ak1/img.png&quot; data-alt=&quot;Test data split&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WT7Jm/dJMcahcrNnl/2fPX3WiVMt81xybHCc2Ak1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWT7Jm%2FdJMcahcrNnl%2F2fPX3WiVMt81xybHCc2Ak1%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;420&quot; height=&quot;156&quot; data-filename=&quot;Screenshot 2026-03-02 at 1.52.34 PM.png&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;156&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Test data split&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Test 1277 gpt-4o-mini label&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;b. Train&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 훈련을 시작해야 한다. 훈련은 이 라벨을 학습루프에 돌려 모델이 Loss를 줄여가며, 선생 모델의 사고방식을 어느정도 학습하게 해야한다. 학습에 대한 추적이 필요하다. 현재 학습이 잘되고 있는지, 모니터링이 필요하다고 느꼈다. 모니터링을 위해 Wandb를 도입했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://wandb.ai/site/ko/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://wandb.ai/site/ko/&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1772427712178&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;Weights &amp;amp; Biases: The AI Developer Platform&quot; data-og-description=&quot;Weights &amp;amp; Biases는 모델을 학습 및 파인튜닝하고, 실험부터 생산까지 모델을 관리하며, LLM으로 구동되는 GenAI 애플리케이션을 추적 및 평가할 수 있는 선도적인 AI 개발자 플랫폼입니다.&quot; data-og-host=&quot;wandb.ai&quot; data-og-source-url=&quot;https://wandb.ai/site/ko/&quot; data-og-url=&quot;https://wandb.ai/site/ko/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Gwiq3/dJMb84XWdVR/XIcdSVEkVKEjHrJts0ExIk/img.png?width=1776&amp;amp;height=969&amp;amp;face=0_0_1776_969&quot;&gt;&lt;a href=&quot;https://wandb.ai/site/ko/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://wandb.ai/site/ko/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Gwiq3/dJMb84XWdVR/XIcdSVEkVKEjHrJts0ExIk/img.png?width=1776&amp;amp;height=969&amp;amp;face=0_0_1776_969');&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;Weights &amp;amp; Biases: The AI Developer Platform&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Weights &amp;amp; Biases는 모델을 학습 및 파인튜닝하고, 실험부터 생산까지 모델을 관리하며, LLM으로 구동되는 GenAI 애플리케이션을 추적 및 평가할 수 있는 선도적인 AI 개발자 플랫폼입니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;wandb.ai&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모니터링 목적으로 도입을 했지만, 좀 더 알아보다 보니, wandb의 sweep 기능과 artifact 기능이 존재했다. sweep이 모델 학습의 편의를 제공해주었고, artifact가 데이터/모델 버전 관리를 제공해 주었다.&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;Wandb의 모니터링에 대해 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재는 Runpod의 pod 컨테이너에 띄워서 학습이 돌고 있고, 내부에서 Wandb API에 메트릭을 전달해주는 중이다. Wandb의 특이한 점은, matplotlib 같은 정적 그래프 시스템이 아닌, Grafana처럼 실시간 시각화를 지원한다는 점이다. 따라서, 학습의 실시간 추적이 가능하다.&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;Screenshot 2026-03-02 at 2.13.07 PM.png&quot; data-origin-width=&quot;2354&quot; data-origin-height=&quot;1354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dOxp2B/dJMcac3f85s/YMzr0KO7klrH2KEPnRfvJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dOxp2B/dJMcac3f85s/YMzr0KO7klrH2KEPnRfvJk/img.png&quot; data-alt=&quot;Eval(이걸 기준으로 Earlystopping을 결정한다.)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dOxp2B/dJMcac3f85s/YMzr0KO7klrH2KEPnRfvJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdOxp2B%2FdJMcac3f85s%2FYMzr0KO7klrH2KEPnRfvJk%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;2354&quot; height=&quot;1354&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.13.07 PM.png&quot; data-origin-width=&quot;2354&quot; data-origin-height=&quot;1354&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Eval(이걸 기준으로 Earlystopping을 결정한다.)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.13.18 PM.png&quot; data-origin-width=&quot;2358&quot; data-origin-height=&quot;1366&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LrDZ9/dJMcadVnR2d/Qt0IyhamtfBIAz1Ayv9gV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LrDZ9/dJMcadVnR2d/Qt0IyhamtfBIAz1Ayv9gV0/img.png&quot; data-alt=&quot;Train&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LrDZ9/dJMcadVnR2d/Qt0IyhamtfBIAz1Ayv9gV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLrDZ9%2FdJMcadVnR2d%2FQt0IyhamtfBIAz1Ayv9gV0%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;2358&quot; height=&quot;1366&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.13.18 PM.png&quot; data-origin-width=&quot;2358&quot; data-origin-height=&quot;1366&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Train&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.15.16 PM.png&quot; data-origin-width=&quot;2356&quot; data-origin-height=&quot;1364&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBRhbO/dJMcajnJPRh/MoLMCn57j2dXJCuFz6phT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBRhbO/dJMcajnJPRh/MoLMCn57j2dXJCuFz6phT0/img.png&quot; data-alt=&quot;GPU Metric&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBRhbO/dJMcajnJPRh/MoLMCn57j2dXJCuFz6phT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBRhbO%2FdJMcajnJPRh%2FMoLMCn57j2dXJCuFz6phT0%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;2356&quot; height=&quot;1364&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.15.16 PM.png&quot; data-origin-width=&quot;2356&quot; data-origin-height=&quot;1364&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;GPU Metric&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.15.30 PM.png&quot; data-origin-width=&quot;2354&quot; data-origin-height=&quot;1354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ebyT9B/dJMcaaRXK9S/JfiD8LcH1ojBcXBv5BYzBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ebyT9B/dJMcaaRXK9S/JfiD8LcH1ojBcXBv5BYzBk/img.png&quot; data-alt=&quot;GPU Metric, Network Traffic&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ebyT9B/dJMcaaRXK9S/JfiD8LcH1ojBcXBv5BYzBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FebyT9B%2FdJMcaaRXK9S%2FJfiD8LcH1ojBcXBv5BYzBk%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;2354&quot; height=&quot;1354&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.15.30 PM.png&quot; data-origin-width=&quot;2354&quot; data-origin-height=&quot;1354&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;GPU Metric, Network Traffic&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.15.42 PM.png&quot; data-origin-width=&quot;2352&quot; data-origin-height=&quot;1362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dhULiP/dJMcagkiUWT/zPqOaI12KCN1j2lWfeZkfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dhULiP/dJMcagkiUWT/zPqOaI12KCN1j2lWfeZkfK/img.png&quot; data-alt=&quot;Disk, CPU, Memory 등 기본 지표&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dhULiP/dJMcagkiUWT/zPqOaI12KCN1j2lWfeZkfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdhULiP%2FdJMcagkiUWT%2FzPqOaI12KCN1j2lWfeZkfK%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;2352&quot; height=&quot;1362&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.15.42 PM.png&quot; data-origin-width=&quot;2352&quot; data-origin-height=&quot;1362&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Disk, CPU, Memory 등 기본 지표&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.16.01 PM.png&quot; data-origin-width=&quot;2352&quot; data-origin-height=&quot;736&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eg2ZAe/dJMcacI0vBO/NbCoMKUcFbXpYOMMFlBqlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eg2ZAe/dJMcacI0vBO/NbCoMKUcFbXpYOMMFlBqlK/img.png&quot; data-alt=&quot;Memory, CPU 등 기본 지표&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eg2ZAe/dJMcacI0vBO/NbCoMKUcFbXpYOMMFlBqlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Feg2ZAe%2FdJMcacI0vBO%2FNbCoMKUcFbXpYOMMFlBqlK%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;2352&quot; height=&quot;736&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.16.01 PM.png&quot; data-origin-width=&quot;2352&quot; data-origin-height=&quot;736&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Memory, CPU 등 기본 지표&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.21.54 PM.png&quot; data-origin-width=&quot;2354&quot; data-origin-height=&quot;726&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBG29Y/dJMcadVnR5T/E9w1zrGfNibPFO00e7cgk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBG29Y/dJMcadVnR5T/E9w1zrGfNibPFO00e7cgk0/img.png&quot; data-alt=&quot;태블로처럼 인터랙티브 기능을 제공한다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBG29Y/dJMcadVnR5T/E9w1zrGfNibPFO00e7cgk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBG29Y%2FdJMcadVnR5T%2FE9w1zrGfNibPFO00e7cgk0%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;2354&quot; height=&quot;726&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.21.54 PM.png&quot; data-origin-width=&quot;2354&quot; data-origin-height=&quot;726&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-filename=&quot;Screenshot 2026-03-02 at 2.25.06 PM.png&quot; data-origin-width=&quot;1354&quot; data-origin-height=&quot;1450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l8Yp1/dJMcabXB0Mv/r9lfB4PvzYtNc1ajsA3TaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l8Yp1/dJMcabXB0Mv/r9lfB4PvzYtNc1ajsA3TaK/img.png&quot; data-alt=&quot;좌측에 Run들이 표시된다. 좌측의 모든 Run이 우측에 모든 선에 해당한다. 초록색 불이 들어와있는건 현재 학습이 진행중인 Run을 의미한다. 현재 Run이 2개가 같이 진행중인건, 현재 학습 시간 단축을 위해 멀티 Pod을 이용해 학습을 진행중이기 때문이다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l8Yp1/dJMcabXB0Mv/r9lfB4PvzYtNc1ajsA3TaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl8Yp1%2FdJMcabXB0Mv%2Fr9lfB4PvzYtNc1ajsA3TaK%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;1354&quot; height=&quot;1450&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.25.06 PM.png&quot; data-origin-width=&quot;1354&quot; data-origin-height=&quot;1450&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;좌측에 Run들이 표시된다. 좌측의 모든 Run이 우측에 모든 선에 해당한다. 초록색 불이 들어와있는건 현재 학습이 진행중인 Run을 의미한다. 현재 Run이 2개가 같이 진행중인건, 현재 학습 시간 단축을 위해 멀티 Pod을 이용해 학습을 진행중이기 때문이다.&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;Screenshot 2026-03-02 at 2.28.48 PM.png&quot; data-origin-width=&quot;1700&quot; data-origin-height=&quot;662&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4YeQ2/dJMcaaYG4GI/W7FKAg0cbwAp85kPzRP5Q1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4YeQ2/dJMcaaYG4GI/W7FKAg0cbwAp85kPzRP5Q1/img.png&quot; data-alt=&quot;이런식으로 필터 기능이 존재한다. running,finisihed, failed, crashed 등 다양한 run의 상태에 대해 필터링이 가능하다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4YeQ2/dJMcaaYG4GI/W7FKAg0cbwAp85kPzRP5Q1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4YeQ2%2FdJMcaaYG4GI%2FW7FKAg0cbwAp85kPzRP5Q1%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;1700&quot; height=&quot;662&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.28.48 PM.png&quot; data-origin-width=&quot;1700&quot; data-origin-height=&quot;662&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이런식으로 필터 기능이 존재한다. running,finisihed, failed, crashed 등 다양한 run의 상태에 대해 필터링이 가능하다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.21.54 PM.png&quot; data-origin-width=&quot;2354&quot; data-origin-height=&quot;726&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Oyw6O/dJMb99ZO8kK/ACITji5hEfMkSWI8K5Lso0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Oyw6O/dJMb99ZO8kK/ACITji5hEfMkSWI8K5Lso0/img.png&quot; data-alt=&quot;이런식으로 태블로처럼 인터랙티브 기능을 지원한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Oyw6O/dJMb99ZO8kK/ACITji5hEfMkSWI8K5Lso0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOyw6O%2FdJMb99ZO8kK%2FACITji5hEfMkSWI8K5Lso0%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;2354&quot; height=&quot;726&quot; data-filename=&quot;Screenshot 2026-03-02 at 2.21.54 PM.png&quot; data-origin-width=&quot;2354&quot; data-origin-height=&quot;726&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;참고로 GPU 및 시스템 메트릭은 내가 전혀 설정하지 않았다. wandb API가 알아서 수집을 진행해주는 것이다. 나는 처음에 단순 학습 모니터링 목적으로만 사용했던건데, 이 기능 때문에 wandb의 편리성에 매우 놀랐다.&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;Wandb의 장점 중 하나는 Sweep 기능이다. 위 사진을 보면 많은 run이 존재하는걸 볼 수 있다. 즉, run=학습 사이클 단위이고, sweep으로기능을 사용하면, 학습 사이클만큼 돌리고, 그게 다가 아니고, yaml 파일로 학습 자체의 관리를 수행해준다. 현재 yaml 파일 설정은 이러하다.&lt;/p&gt;
&lt;div style=&quot;background-color: #181818; color: #e4e4e4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;# wandb Sweep 설정: QLoRA SFT 하이퍼파라미터 탐색 (cap_strategy.md 반영)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;# 사용: wandb sweep scripts/wandb_sweep_qlora.yaml&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;# 실행: WANDB_SWEEP_LABELED_PATH=... WANDB_SWEEP_OUTPUT_DIR=... wandb agent &amp;lt;sweep_id&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;# 환경변수(필수): WANDB_SWEEP_LABELED_PATH, WANDB_SWEEP_OUTPUT_DIR, WANDB_API_KEY, WANDB_PROJECT&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;program&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;scripts/run_qlora_sweep.py&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;method&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;bayes&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;metric&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;eval_loss&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;goal&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;minimize&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;run_cap&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;50&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;parameters&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;# 핵심 하이퍼 6개 (cap_strategy &amp;sect;3)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;learning_rate&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;distribution&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;log_uniform_values&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;min&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;1.0e-5&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;max&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;5.0e-5&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;batch_size&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;values&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;grad_accum&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;values&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;num_epochs&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;values&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;warmup_ratio&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;distribution&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;uniform&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;min&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;0.0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;max&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;0.1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;weight_decay&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;distribution&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;log_uniform_values&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;min&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;1.0e-7&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;max&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;1.0e-3&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;max_seq_length&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;values&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;512&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;1024&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;2048&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;# 고정 (탐색 공간 축소)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;student_model&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;&quot;Qwen/Qwen2.5-0.5B-Instruct&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;gold_oversample_ratio&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;0.25&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;target_modules&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;&quot;q_proj,v_proj,k_proj,o_proj,gate_proj,up_proj,down_proj&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;r&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;8&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;alpha&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #e394dc;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #e4e4e4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #ebc88d;&quot;&gt;16&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;c. Eval,Test&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;학습이 끝난 모든 모델은 Wandb의 Artifact라는 저장소에 저장된다. 그 Artifact에서 Best run을 자동으로 로컬에 다운로드를 진행한다. &lt;/span&gt;Sweep은 또한 Best Run 즉, 가장 학습이 잘된 모델을 자동으로 선택해주는 기능이 존재한다. 이 Sweep이 선택해준 Best run 모델을 다운로드 한다.&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;학습 기준은 ROUGE,BERTscore를 사용한다. 왜냐하면 현재 하는건 SFT이기 때문에, 라벨 문장과 student 모델의 유사도를 측정해, student 모델이 잘 추론하는지를 평가해야 하기 때문이다.&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: #333333; text-align: start;&quot;&gt;&lt;span&gt;3. &lt;/span&gt;Prefect를 기반한 지식증류 완전 자동화 파이프라인 구축&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&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;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Prefect는 한마디로 말해 상태(State)를 관리하는 오케스트레이터이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Prefect는 크게 Flow, task가 존재한다. Flow는 분기이고, Task는 분기 안에 있는 동작에 해당한다.&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;&lt;span style=&quot;color: #333333; text-align: start;&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;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Raw 데이터 데이터 증강 - wandb artifact에 데이터 업로드 - 데이터 train/val/test 분할 - wandb artifact에 업로드 - train/val 라벨링 데이터를 pod의 네트워크 볼륨으로 업로드(Runpod S3 compatible을 이용)&amp;nbsp; - pod on - 데이터 라벨링 - pod off - pod on&amp;nbsp; - wandb의 sweep으로 학습 진행 - wandb에서 모니터링 - 모든 학습된 모델을 wandb artifact에 저장 - pod off - wandb artifact에서 sweep이 골라준 best run을 로컬로 다운로드 - 로컬에서 val,test 라벨 데이터에 대해 ROUGE로 평가 수행. &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;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;2026.03.28&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;--&amp;gt; 이렇게 한번에 돌아가게 구성했지만, 아티팩트 다운로드 이후 평가 단계가 돌아가지 않았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;따라서 현재는,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;1. sweep on pod -&amp;gt; download artifact&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;2. evaluation 으로 진행된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&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;이 구성이 위에서 말한 문제점 해소가 가능하면서, 학습과 추론 이렇게 명확히 나뉘어 더 관리에 용이하다.&lt;/p&gt;</description>
      <author>jayvi.oh</author>
      <guid isPermaLink="true">https://tasteam.tistory.com/21</guid>
      <comments>https://tasteam.tistory.com/21#entry21comment</comments>
      <pubDate>Mon, 2 Mar 2026 15:05:51 +0900</pubDate>
    </item>
    <item>
      <title>도메인은 정상인데 왜 접속이 안 될까? &amp;mdash; ISP DNS 캐시가 만든 SERVFAIL 트러블슈팅</title>
      <link>https://tasteam.tistory.com/11</link>
      <description>&lt;h1 style=&quot;color: #000000; text-align: start;&quot; data-heading=&quot;도메인은 정상인데 왜 접속이 안 될까? &amp;mdash; ISP DNS 캐시가 만든 SERVFAIL 트러블슈팅&quot;&gt;도메인은 정상인데 왜 접속이 안 될까? &amp;mdash; ISP DNS 캐시가 만든 SERVFAIL 트러블슈팅&lt;/h1&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요, Tasteam에서 Cloud 팀을 맡고 있는 clay입니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&quot;저는 접속이 되는데, 다른 팀원은 접속이 안 돼요.&quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;인프라를 운영하다 보면 이런 제보를 종종 받게 됩니다. 도메인 설정은 분명히 끝냈는데, 특정 사용자만 접속이 안 되는 상황.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;가비아에서 구매한 tasteam.kr 도메인을 Cloudflare에 연결한 직후, 저희도 정확히 이 문제를 마주했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;특히&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;KT 네트워크 환경&lt;/b&gt;에서 nslookup tasteam.kr을 실행하면 IP 주소를 찾지 못하고 SERVFAIL 오류를 반환했어요. 모든 설정은 정상이었는데, 대체 무엇이 문제였을까요?&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;오늘은 이 문제를 어떻게 진단하고 해결했는지, 그 과정을 공유해 드리겠습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot; data-heading=&quot;환경&quot;&gt;환경&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 당시 저희의 환경 구성입니다. 가비아에서 도메인을 구매하고, DNS는 Cloudflare를 통해 운영하고 있었어요.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;항목 내용&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;도메인 레지스트라&lt;/td&gt;
&lt;td&gt;가비아 (Gabia)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DNS&lt;/td&gt;
&lt;td&gt;Cloudflare&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;문제 발생 네트워크&lt;/td&gt;
&lt;td&gt;KT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;정상 동작 네트워크&lt;/td&gt;
&lt;td&gt;SKT, LG U+, Google DNS 등&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot; data-heading=&quot;처음엔 컴퓨터 문제인 줄 알았습니다&quot;&gt;처음엔 컴퓨터 문제인 줄 알았습니다&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이상했던 건&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;클라우드 팀원들은 전원 정상 접속&lt;/b&gt;이 되는데,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;백엔드 팀원들만 접속이 안 된다&lt;/b&gt;는 점이었어요. 같은 도메인, 같은 시간인데 팀마다 결과가 다르니 처음엔 개인 PC 문제를 의심했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 맥북의 로컬 DNS 캐시를 삭제해 봤습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot;&gt;&lt;code&gt;sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 캐시를 비워도 증상은 그대로였어요. 로컬 캐시가 원인이 아니라면, 그 위 단계에서 무언가 막고 있다는 뜻이었습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이후 확인해 보니, 클라우드 팀원들은 공용 DNS(8.8.8.8 등)를 사용하고 있었고, 백엔드 팀원들은 ISP 기본 DNS(KT)를 그대로 쓰고 있었던 거예요.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;사람의 차이가 아니라 네트워크 설정의 차이&lt;/b&gt;였습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot; data-heading=&quot;증상 확인&quot;&gt;증상 확인&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 단서를 바탕으로, KT 네트워크 환경에서 nslookup을 실행해 봤습니다.&lt;/p&gt;
&lt;pre style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot;&gt;&lt;code&gt;nslookup tasteam.kr
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&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;02-nslookup-kt-servfail.png&quot; data-origin-width=&quot;1402&quot; data-origin-height=&quot;306&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zZuco/dJMcabwR8y2/DzdGXw2eOgy62GhnotHkV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zZuco/dJMcabwR8y2/DzdGXw2eOgy62GhnotHkV1/img.png&quot; data-alt=&quot;nslookup-kt-servfail&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zZuco/dJMcabwR8y2/DzdGXw2eOgy62GhnotHkV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzZuco%2FdJMcabwR8y2%2FDzdGXw2eOgy62GhnotHkV1%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;1402&quot; height=&quot;306&quot; data-filename=&quot;02-nslookup-kt-servfail.png&quot; data-origin-width=&quot;1402&quot; data-origin-height=&quot;306&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;nslookup-kt-servfail&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;KT DNS 서버(168.126.63.1, 168.126.63.2)가 SERVFAIL을 반환하고 있었습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;반면, 같은 시간에 다른 네트워크에서는 정상적으로 IP가 반환됐어요. 도메인 자체의 문제라기보다는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;특정 DNS 서버의 문제&lt;/b&gt;가 의심되는 상황이었습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot; data-heading=&quot;가설 수립&quot;&gt;가설 수립&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;SERVFAIL 오류와 &quot;일부 사용자에게만 발생&quot;이라는 조건을 바탕으로 세 가지 가설을 세워 봤습니다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-heading=&quot;가설 1. DNS 전파 지연&quot;&gt;가설 1. DNS 전파 지연&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;가비아에서 Cloudflare로 네임서버를 변경한 직후이므로, 변경 정보가 전 세계 DNS 망에 아직 전파되지 않았을 가능성이 있었습니다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-heading=&quot;가설 2. 설정 오류&quot;&gt;가설 2. 설정 오류&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;가비아의 네임서버 설정 또는 Cloudflare의 DNS 레코드(A, CNAME 등)가 잘못 구성되었을 가능성도 있었어요.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-heading=&quot;가설 3. DNSSEC 서명 불일치&quot;&gt;가설 3. DNSSEC 서명 불일치&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;SERVFAIL의 가장 흔한 원인 중 하나인데요. 가비아에 남아있는 이전 DNSSEC 서명 정보와 Cloudflare의 새 서명 정보가 일치하지 않아, 보안 검사를 수행하는 DNS 서버가 응답을 거부하는 경우입니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot; data-heading=&quot;검증 과정&quot;&gt;검증 과정&lt;/h2&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-heading=&quot;1단계 &amp;mdash; 네임서버 전파 확인&quot;&gt;1단계 &amp;mdash; 네임서버 전파 확인&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://dnschecker.org&quot; data-tooltip-position=&quot;top&quot;&gt;dnschecker.org&lt;/a&gt;를 통해 tasteam.kr의 NS 레코드를 조회했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Cloudflare의 네임서버(dakota.ns.cloudflare.com, gigi.ns.cloudflare.com)가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;전 세계적으로 정상 전파&lt;/b&gt;된 것을 확인할 수 있었어요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02-nslookup-kt-servfail.png&quot; data-origin-width=&quot;1402&quot; data-origin-height=&quot;306&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4YWJh/dJMcahjBy9B/tPGKfq0L8ykkiUdGk7AhMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4YWJh/dJMcahjBy9B/tPGKfq0L8ykkiUdGk7AhMk/img.png&quot; data-alt=&quot;dnschecker-ns-정상전파&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4YWJh/dJMcahjBy9B/tPGKfq0L8ykkiUdGk7AhMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4YWJh%2FdJMcahjBy9B%2FtPGKfq0L8ykkiUdGk7AhMk%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;1402&quot; height=&quot;306&quot; data-filename=&quot;02-nslookup-kt-servfail.png&quot; data-origin-width=&quot;1402&quot; data-origin-height=&quot;306&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;dnschecker-ns-정상전파&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #000000; color: #333333; text-align: center;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p style=&quot;color: #666666;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결과: 정상&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr; 가설 1 기각&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-heading=&quot;2단계 &amp;mdash; Cloudflare 설정 확인&quot;&gt;2단계 &amp;mdash; Cloudflare 설정 확인&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Cloudflare 대시보드에서 다음 내용을 확인했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;A 레코드가 정확한 서버 IP를 가리키고 있음&lt;/li&gt;
&lt;li&gt;프록시(주황색 구름) 상태가 활성화됨&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote style=&quot;background-color: #000000; color: #333333; text-align: center;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p style=&quot;color: #666666;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결과: 정상&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr; 가설 2 기각&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-heading=&quot;3단계 &amp;mdash; DNSSEC 설정 확인&quot;&gt;3단계 &amp;mdash; DNSSEC 설정 확인&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;가비아&lt;/b&gt;: DNSSEC 관련 설정 메뉴를 찾을 수 없었습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Cloudflare&lt;/b&gt;: DNSSEC 기능이 비활성화(&quot;Enable DNSSEC&quot; 버튼 표시) 상태였어요.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote style=&quot;background-color: #000000; color: #333333; text-align: center;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p style=&quot;color: #666666;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결과: 양쪽 모두 비활성화 상태&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr; 가설 3의 일반적인 시나리오와 불일치&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-heading=&quot;4단계 &amp;mdash; DNS 경로 정밀 분석&quot;&gt;4단계 &amp;mdash; DNS 경로 정밀 분석&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://dnsviz.net&quot; data-tooltip-position=&quot;top&quot;&gt;dnsviz.net&lt;/a&gt;을 사용하여 루트(.)에서부터 tasteam.kr까지의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;전체 DNS 신뢰 체인&lt;/b&gt;을 시각적으로 분석했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;분석 결과, 어떠한 오류(빨간색 Error/Bogus)도 발견되지 않았어요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05-dnsviz-신뢰체인-정상.png&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;1094&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byWzsa/dJMcabDFdXP/9WmvGNGOsgdCxySGhnXKr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byWzsa/dJMcabDFdXP/9WmvGNGOsgdCxySGhnXKr0/img.png&quot; data-alt=&quot;dnsviz-신뢰체인-정상&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byWzsa/dJMcabDFdXP/9WmvGNGOsgdCxySGhnXKr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyWzsa%2FdJMcabDFdXP%2F9WmvGNGOsgdCxySGhnXKr0%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;336&quot; height=&quot;578&quot; data-filename=&quot;05-dnsviz-신뢰체인-정상.png&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;1094&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;dnsviz-신뢰체인-정상&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #000000; color: #333333; text-align: center;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p style=&quot;color: #666666;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결과: 도메인 자체의 기술적인 설정은 완벽한 상태&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot; data-heading=&quot;모든 설정이 정상인데 왜 SERVFAIL인가?&quot;&gt;모든 설정이 정상인데 왜 SERVFAIL인가?&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 관점을 전환했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;도메인 설정에는 문제가 없다면, 문제는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;DNS 해석(Resolution) 단계&lt;/b&gt;에 있을 수밖에 없었어요.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-heading=&quot;DNS가 동작하는 과정&quot;&gt;DNS가 동작하는 과정&lt;/h3&gt;
&lt;pre style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot;&gt;&lt;code&gt;사용자 브라우저
    &amp;darr; tasteam.kr 요청
사용자 PC의 DNS 설정 (예: KT DNS)
    &amp;darr; 재귀 질의
KT DNS 서버 (Recursive Resolver)
    &amp;darr; 캐시에 있으면 캐시 응답, 없으면 상위 질의
루트 DNS &amp;rarr; .kr DNS &amp;rarr; Cloudflare NS
    &amp;darr; 응답
최종 IP 반환
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 핵심은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Recursive Resolver의 캐시&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;KT DNS 서버가 도메인 설정 변경 과정 중에 발생한 일시적인 오류 응답을 캐시에 저장해 둔 거예요. 이후 정상적인 설정이 완료되었음에도&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;캐시가 만료되기 전까지 계속 오래된 오류 응답을 반환&lt;/b&gt;하고 있었습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot; data-heading=&quot;결정적 검증&quot;&gt;결정적 검증&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;사용자 PC에서 DNS 서버를 KT &amp;rarr; Google 공용 DNS로 변경한 후 다시 조회해 봤습니다.&lt;/p&gt;
&lt;pre style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot;&gt;&lt;code&gt;nslookup tasteam.kr 8.8.8.8
&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;03-nslookup-google-dns-정상.png&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;478&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dUHTo2/dJMcajuTt82/PWy4akw0izCvNHbh8BSuE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dUHTo2/dJMcajuTt82/PWy4akw0izCvNHbh8BSuE1/img.png&quot; data-alt=&quot;nslookup-google-dns-정상&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dUHTo2/dJMcajuTt82/PWy4akw0izCvNHbh8BSuE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdUHTo2%2FdJMcajuTt82%2FPWy4akw0izCvNHbh8BSuE1%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;586&quot; height=&quot;362&quot; data-filename=&quot;03-nslookup-google-dns-정상.png&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;478&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;nslookup-google-dns-정상&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;즉시 정상적인 IP 주소가 반환&lt;/b&gt;됐어요.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;dig 명령으로 더 정밀하게 비교하면 차이가 명확합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04-dig-google-vs-kt-비교-1.png&quot; data-origin-width=&quot;1522&quot; data-origin-height=&quot;1550&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cs2qba/dJMcabKsnTU/XcNTtsFO8AhHaG09COhdak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cs2qba/dJMcabKsnTU/XcNTtsFO8AhHaG09COhdak/img.png&quot; data-alt=&quot;dig-google-vs-kt-비교&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cs2qba/dJMcabKsnTU/XcNTtsFO8AhHaG09COhdak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcs2qba%2FdJMcabKsnTU%2FXcNTtsFO8AhHaG09COhdak%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;473&quot; height=&quot;482&quot; data-filename=&quot;04-dig-google-vs-kt-비교-1.png&quot; data-origin-width=&quot;1522&quot; data-origin-height=&quot;1550&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;dig-google-vs-kt-비교&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;dig tasteam.kr @8.8.8.8 &amp;rarr; status: NOERROR, A 레코드 2개 정상 반환&lt;/li&gt;
&lt;li&gt;dig tasteam.kr @168.126.63.1 &amp;rarr; status: SERVFAIL, ANSWER 0개&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이것으로 원인이 확정됐습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;KT DNS 서버의 캐싱 문제&lt;/b&gt;였어요.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot; data-heading=&quot;해결 조치&quot;&gt;해결 조치&lt;/h2&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-heading=&quot;단기 해결 &amp;mdash; 개별 사용자&quot;&gt;단기 해결 &amp;mdash; 개별 사용자&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문제가 발생하는 사용자의 DNS 서버를 공용 DNS로 변경하는 방법입니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;DNS 서비스 Primary Secondary&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;8.8.8.8&lt;/td&gt;
&lt;td&gt;8.8.4.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloudflare&lt;/td&gt;
&lt;td&gt;1.1.1.1&lt;/td&gt;
&lt;td&gt;1.0.0.1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-heading=&quot;장기 해결 &amp;mdash; 전체 사용자&quot;&gt;장기 해결 &amp;mdash; 전체 사용자&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;두 가지 방법이 있었습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 수동적 대기&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;KT DNS 서버의 캐시가 TTL 만료로 자연 갱신될 때까지 기다리는 방법이에요. (수 시간 ~ 최대 2일 소요)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 능동적 캐시 갱신 유도&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Cloudflare 대시보드에서 DNSSEC 기능을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;켰다가 1분 후 다시 끄는&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;조치를 수행했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 작업은 Cloudflare가 DNS 망에 구성 변경 신호를 보내, KT와 같은 하위 DNS 서버들이 캐시를 더 빨리 새로고침하도록 유도하는 효과가 있어요.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot; data-heading=&quot;돌아보며&quot;&gt;돌아보며&lt;/h2&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-heading=&quot;1. SERVFAIL &amp;ne; 설정 오류&quot;&gt;1. SERVFAIL &amp;ne; 설정 오류&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;SERVFAIL을 보면 본능적으로 &quot;내 설정이 잘못됐나?&quot;를 먼저 의심하게 됩니다. 하지만 이번 케이스처럼&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;설정은 완벽한데 중간 경로의 캐시가 원인&lt;/b&gt;인 경우도 있어요.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-heading=&quot;2. ISP DNS 캐시는 통제 불가 영역&quot;&gt;2. ISP DNS 캐시는 통제 불가 영역&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;KT, SKT, LG U+ 등 ISP의 DNS 서버는 우리가 직접 제어할 수 없습니다. 캐시 만료를 기다리거나, 간접적으로 갱신을 유도하는 수밖에 없어요.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-heading=&quot;3. 문제 격리가 핵심&quot;&gt;3. 문제 격리가 핵심&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&quot;일부 사용자만 안 된다&quot;는 증상에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;네트워크 환경 차이&lt;/b&gt;를 빠르게 캐치하는 것이 중요했습니다. DNS 서버를 바꿔보는 것만으로 원인을 좁힐 수 있었어요.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot; data-heading=&quot;도메인 마이그레이션 후 체크리스트&quot;&gt;도메인 마이그레이션 후 체크리스트&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;마지막으로, 도메인 연결이나 네임서버 변경 후 아래 항목을 순서대로 확인하면 대부분의 DNS 문제를 빠르게 진단할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-task=&quot;&quot;&gt;&lt;b&gt;NS 레코드 전파 확인&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;mdash;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://dnschecker.org&quot; data-tooltip-position=&quot;top&quot;&gt;dnschecker.org&lt;/a&gt;에서 전 세계 NS 응답 확인&lt;/li&gt;
&lt;li data-task=&quot;&quot;&gt;&lt;b&gt;DNS 레코드 확인&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;mdash; A/CNAME 레코드가 올바른 IP/도메인을 가리키는지 확인&lt;/li&gt;
&lt;li data-task=&quot;&quot;&gt;&lt;b&gt;DNSSEC 상태 확인&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;mdash; 레지스트라와 DNS 제공자 양쪽의 DNSSEC 설정이 일치하는지 확인&lt;/li&gt;
&lt;li data-task=&quot;&quot;&gt;&lt;b&gt;DNS 신뢰 체인 검증&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;mdash;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://dnsviz.net&quot; data-tooltip-position=&quot;top&quot;&gt;dnsviz.net&lt;/a&gt;에서 오류 없는지 확인&lt;/li&gt;
&lt;li data-task=&quot;&quot;&gt;&lt;b&gt;다른 DNS 서버로 테스트&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;mdash; nslookup 도메인 8.8.8.8로 ISP DNS 문제 여부 격리&lt;/li&gt;
&lt;li data-task=&quot;&quot;&gt;&lt;b&gt;TTL 대기 또는 캐시 갱신 유도&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;mdash; 문제가 ISP 캐시라면 시간 경과 또는 DNSSEC 토글로 대응&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot; data-heading=&quot;마치며&quot;&gt;마치며&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&quot;설정은 다 맞는데 왜 안 되지?&quot;라는 상황은 인프라를 운영하다 보면 정말 자주 마주치게 됩니다. 이번 트러블슈팅에서 얻은 가장 큰 교훈은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;내가 통제할 수 있는 영역과 없는 영역을 구분하고, 체계적으로 가설을 세워 하나씩 검증해 나가는 것&lt;/b&gt;의 중요성이었어요.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;비슷한 문제를 겪고 계신 분이 있다면 이 글이 도움이 되었으면 좋겠습니다. 읽어 주셔서 감사합니다.&lt;/p&gt;</description>
      <author>clay.kim</author>
      <guid isPermaLink="true">https://tasteam.tistory.com/11</guid>
      <comments>https://tasteam.tistory.com/11#entry11comment</comments>
      <pubDate>Sun, 22 Feb 2026 14:39:01 +0900</pubDate>
    </item>
  </channel>
</rss>