<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>칼의 치치</title>
    <link>https://chalchichi.tistory.com/</link>
    <description>기록 저장소</description>
    <language>ko</language>
    <pubDate>Thu, 30 Jul 2026 19:01:54 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>칼쵸쵸</managingEditor>
    <image>
      <title>칼의 치치</title>
      <url>https://tistory1.daumcdn.net/tistory/3039896/attach/e5c12decd4bd4559b042c64fbb16c316</url>
      <link>https://chalchichi.tistory.com</link>
    </image>
    <item>
      <title>Trino 쿼리를 통한 Iceberg 내부 살펴보기</title>
      <link>https://chalchichi.tistory.com/137</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1198&quot; data-origin-height=&quot;660&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tzJli/btsPDZKEVRK/AjnEQk4GdDYK9IhLLkmQik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tzJli/btsPDZKEVRK/AjnEQk4GdDYK9IhLLkmQik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tzJli/btsPDZKEVRK/AjnEQk4GdDYK9IhLLkmQik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtzJli%2FbtsPDZKEVRK%2FAjnEQk4GdDYK9IhLLkmQik%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;1198&quot; height=&quot;660&quot; data-origin-width=&quot;1198&quot; data-origin-height=&quot;660&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1 data-end=&quot;216&quot; data-start=&quot;192&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1 data-end=&quot;216&quot; data-start=&quot;192&quot;&gt;  1. Iceberg 파일 구조 개요&lt;/h1&gt;
&lt;p data-end=&quot;291&quot; data-start=&quot;218&quot; data-ke-size=&quot;size16&quot;&gt;Iceberg 테이블은 HDFS, S3, HDFS-compatible storage 등에 저장되며 크게 두 가지 계층으로 나뉩니다:&lt;/p&gt;
&lt;pre id=&quot;code_1753968814775&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;table_name/
 ├── data/                  # 실제 데이터 파일 (Parquet/ORC/Avro)
 │    ├── ...partition.../
 │    │    └── 00000-aaaa.parquet
 │    └── ...
 └── metadata/              # 테이블 스냅샷과 스키마/파티션 정의
      ├── version-hash.json
      ├── v0001.metadata.json
      ├── v0002.metadata.json
      └── snapshots/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;616&quot; data-start=&quot;607&quot; data-ke-size=&quot;size23&quot;&gt;구성 요소&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;996&quot; data-start=&quot;617&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;702&quot; data-start=&quot;617&quot;&gt;&lt;b&gt;데이터 파일 (data/)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;702&quot; data-start=&quot;644&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;675&quot; data-start=&quot;644&quot;&gt;실질적인 레코드가 저장되는 Parquet/ORC 파일&lt;/li&gt;
&lt;li data-end=&quot;702&quot; data-start=&quot;678&quot;&gt;파티션 규칙에 따라 디렉터리 구조로 나뉨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;796&quot; data-start=&quot;704&quot;&gt;&lt;b&gt;매니페스트 파일 (manifest)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;796&quot; data-start=&quot;734&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;770&quot; data-start=&quot;734&quot;&gt;데이터 파일 리스트 + min/max statistics 보관&lt;/li&gt;
&lt;li data-end=&quot;796&quot; data-start=&quot;773&quot;&gt;&lt;b&gt;파일 단위 pruning&lt;/b&gt;에 활용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;860&quot; data-start=&quot;798&quot;&gt;&lt;b&gt;매니페스트 리스트 (manifest list)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;860&quot; data-start=&quot;834&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;860&quot; data-start=&quot;834&quot;&gt;하나의 스냅샷을 구성하는 매니페스트들의 목록&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;919&quot; data-start=&quot;862&quot;&gt;&lt;b&gt;스냅샷 (snapshot)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;919&quot; data-start=&quot;887&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;919&quot; data-start=&quot;887&quot;&gt;테이블의 특정 시점 상태 (매니페스트 리스트를 가리킴)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;996&quot; data-start=&quot;921&quot;&gt;&lt;b&gt;메타데이터 JSON (v000N.metadata.json)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;996&quot; data-start=&quot;966&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;996&quot; data-start=&quot;966&quot;&gt;테이블 전체 이력과 모든 스냅샷/스키마 정의를 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 data-end=&quot;1029&quot; data-start=&quot;1003&quot;&gt;  2. Iceberg 스냅샷의 연결 관계&lt;/h1&gt;
&lt;p data-end=&quot;1048&quot; data-start=&quot;1031&quot; data-ke-size=&quot;size16&quot;&gt;아키텍처 플로우 (간단 버전):&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1753968887442&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;metadata.json
   │
   └─ snapshot &amp;rarr; manifest list &amp;rarr; manifest &amp;rarr; data files&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1330&quot; data-start=&quot;1133&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1180&quot; data-start=&quot;1133&quot;&gt;&lt;b&gt;metadata.json&lt;/b&gt;: 스냅샷 목록 + 현재 활성 snapshot ID&lt;/li&gt;
&lt;li data-end=&quot;1224&quot; data-start=&quot;1181&quot;&gt;&lt;b&gt;snapshot&lt;/b&gt;: manifest list 파일 경로 + 요약 정보&lt;/li&gt;
&lt;li data-end=&quot;1266&quot; data-start=&quot;1225&quot;&gt;&lt;b&gt;manifest list&lt;/b&gt;: 여러 manifest 파일 경로 모음&lt;/li&gt;
&lt;li data-end=&quot;1299&quot; data-start=&quot;1267&quot;&gt;&lt;b&gt;manifest&lt;/b&gt;: 개별 데이터 파일 경로와 통계&lt;/li&gt;
&lt;li data-end=&quot;1330&quot; data-start=&quot;1300&quot;&gt;&lt;b&gt;data file&lt;/b&gt;: 실제 row 데이터 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-end=&quot;852&quot; data-start=&quot;811&quot;&gt;  3. $snapshots에서 Manifest List 확인하기&lt;/h1&gt;
&lt;p data-end=&quot;908&quot; data-start=&quot;854&quot; data-ke-size=&quot;size16&quot;&gt;Trino에서 $snapshots를 조회하면 manifest list 경로를 볼 수 있습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1753969176653&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT snapshot_id,
       committed_at,
       manifest_list
FROM table_name$snapshots
ORDER BY committed_at DESC
LIMIT 3;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&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;b&gt;예시 결과&lt;/b&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;snapshot_id&lt;/td&gt;
&lt;td&gt;committed_at&lt;/td&gt;
&lt;td&gt;manifest_list&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4151342690114749344&lt;/td&gt;
&lt;td&gt;2025-07-27 00:00&lt;/td&gt;
&lt;td&gt;hdfs://warehouse/table_name/metadata/snap-4151342690114749344-1-ml.avro&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4151342690114749221&lt;/td&gt;
&lt;td&gt;2025-07-26 00:00&lt;/td&gt;
&lt;td&gt;hdfs://warehouse/table_name/metadata/snap-4151342690114749221-1-ml.avro&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1642&quot; data-start=&quot;1549&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1589&quot; data-start=&quot;1549&quot;&gt;&lt;b&gt;manifest_list&lt;/b&gt;: manifest list 파일 경로&lt;/li&gt;
&lt;li data-end=&quot;1642&quot; data-start=&quot;1590&quot;&gt;Iceberg는 이 파일을 통해 어떤 manifest들이 이 스냅샷에 속하는지 알 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1647&quot; data-start=&quot;1644&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1676&quot; data-start=&quot;1649&quot;&gt;  4. Manifest List 내부 구조&lt;/h1&gt;
&lt;p data-end=&quot;1751&quot; data-start=&quot;1678&quot; data-ke-size=&quot;size16&quot;&gt;manifest list 파일 자체는 &lt;b&gt;Avro 포맷&lt;/b&gt;으로 저장되어 있으며, 각 행은 하나의 manifest 파일을 나타냅니다.&lt;/p&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;2108&quot; data-start=&quot;1753&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style4&quot;&gt;
&lt;tbody data-end=&quot;2108&quot; data-start=&quot;1813&quot;&gt;
&lt;tr data-end=&quot;1853&quot; data-start=&quot;1813&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1835&quot; data-start=&quot;1813&quot;&gt;manifest_path&lt;/td&gt;
&lt;td data-end=&quot;1853&quot; data-start=&quot;1835&quot; data-col-size=&quot;sm&quot;&gt;manifest 파일 경로&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1894&quot; data-start=&quot;1854&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1876&quot; data-start=&quot;1854&quot;&gt;manifest_length&lt;/td&gt;
&lt;td data-end=&quot;1894&quot; data-start=&quot;1876&quot; data-col-size=&quot;sm&quot;&gt;manifest 파일 크기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1945&quot; data-start=&quot;1895&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1917&quot; data-start=&quot;1895&quot;&gt;partition_spec_id&lt;/td&gt;
&lt;td data-end=&quot;1945&quot; data-start=&quot;1917&quot; data-col-size=&quot;sm&quot;&gt;어떤 partition spec에 해당하는지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1986&quot; data-start=&quot;1946&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1968&quot; data-start=&quot;1946&quot;&gt;added_snapshot_id&lt;/td&gt;
&lt;td data-end=&quot;1986&quot; data-start=&quot;1968&quot; data-col-size=&quot;sm&quot;&gt;어떤 스냅샷에서 추가됐는지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2025&quot; data-start=&quot;1987&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2009&quot; data-start=&quot;1987&quot;&gt;existing&lt;/td&gt;
&lt;td data-end=&quot;2025&quot; data-start=&quot;2009&quot; data-col-size=&quot;sm&quot;&gt;기존 데이터 파일 개수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2068&quot; data-start=&quot;2026&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2048&quot; data-start=&quot;2026&quot;&gt;added_files_count&lt;/td&gt;
&lt;td data-end=&quot;2068&quot; data-start=&quot;2048&quot; data-col-size=&quot;sm&quot;&gt;새로 추가된 데이터 파일 개수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2108&quot; data-start=&quot;2069&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2091&quot; data-start=&quot;2069&quot;&gt;deleted_files_count&lt;/td&gt;
&lt;td data-end=&quot;2108&quot; data-start=&quot;2091&quot; data-col-size=&quot;sm&quot;&gt;삭제된 데이터 파일 개수&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-end=&quot;2142&quot; data-start=&quot;2115&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1 data-end=&quot;2142&quot; data-start=&quot;2115&quot;&gt;  5. Manifest 파일 구조 (참고)&lt;/h1&gt;
&lt;p data-end=&quot;2182&quot; data-start=&quot;2144&quot; data-ke-size=&quot;size16&quot;&gt;각 manifest 파일에는 실제 데이터 파일 정보가 들어 있습니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2370&quot; data-start=&quot;2184&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2223&quot; data-start=&quot;2184&quot;&gt;&lt;b&gt;data_file_path&lt;/b&gt;: parquet/orc 파일 경로&lt;/li&gt;
&lt;li data-end=&quot;2251&quot; data-start=&quot;2224&quot;&gt;&lt;b&gt;partition_data&lt;/b&gt;: 파티션 값&lt;/li&gt;
&lt;li data-end=&quot;2281&quot; data-start=&quot;2252&quot;&gt;&lt;b&gt;record_count&lt;/b&gt;: 파일의 레코드 수&lt;/li&gt;
&lt;li data-end=&quot;2345&quot; data-start=&quot;2282&quot;&gt;&lt;b&gt;lower_bounds / upper_bounds&lt;/b&gt;: 각 컬럼의 최소/최대 값 (&amp;rarr; pruning 가능)&lt;/li&gt;
&lt;li data-end=&quot;2370&quot; data-start=&quot;2346&quot;&gt;&lt;b&gt;file_size_in_bytes&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2423&quot; data-start=&quot;2372&quot; data-ke-size=&quot;size16&quot;&gt;이 덕분에 Iceberg는 **파일 단위 프루닝(file pruning)**을 할 수 있음.&lt;/p&gt;
&lt;h1 data-end=&quot;1371&quot; data-start=&quot;1337&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1 data-end=&quot;1371&quot; data-start=&quot;1337&quot;&gt;  6. Trino에서 $snapshots 메타테이블&lt;/h1&gt;
&lt;p data-end=&quot;1437&quot; data-start=&quot;1373&quot; data-ke-size=&quot;size16&quot;&gt;Trino는 Iceberg 테이블 메타데이터를 &lt;b&gt;SQL로 조회&lt;/b&gt;할 수 있게 $snapshots를 제공합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1753968907859&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT snapshot_id,
       committed_at,
       parent_id,
       operation,
       summary
FROM table_name$snapshots
ORDER BY committed_at DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&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;b&gt;출력 예시&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;2058&quot; data-start=&quot;1608&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;snapshot_id&lt;/td&gt;
&lt;td&gt;committed_at&lt;/td&gt;
&lt;td&gt;parent_id&lt;/td&gt;
&lt;td&gt;operation&lt;/td&gt;
&lt;td&gt;summary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1946&quot; data-start=&quot;1834&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1855&quot; data-start=&quot;1834&quot;&gt;4151342690114749344&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1875&quot; data-start=&quot;1855&quot;&gt;2025-07-27 00:00&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1896&quot; data-start=&quot;1875&quot;&gt;4151342690114749221&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1907&quot; data-start=&quot;1896&quot;&gt;append&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1946&quot; data-start=&quot;1907&quot;&gt;{&quot;added-records&quot;:&quot;12000&quot;}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2058&quot; data-start=&quot;1947&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1968&quot; data-start=&quot;1947&quot;&gt;4151342690114749221&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1988&quot; data-start=&quot;1968&quot;&gt;2025-07-26 00:00&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2008&quot; data-start=&quot;1988&quot;&gt;NULL&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2019&quot; data-start=&quot;2008&quot;&gt;overwrite&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2058&quot; data-start=&quot;2019&quot;&gt;{&quot;deleted-records&quot;:&quot;500&quot;}&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2226&quot; data-start=&quot;2060&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2090&quot; data-start=&quot;2060&quot;&gt;&lt;b&gt;snapshot_id&lt;/b&gt;: 스냅샷 고유 ID&lt;/li&gt;
&lt;li data-end=&quot;2131&quot; data-start=&quot;2091&quot;&gt;&lt;b&gt;parent_id&lt;/b&gt;: 이전 스냅샷 (branch 구조 추적)&lt;/li&gt;
&lt;li data-end=&quot;2180&quot; data-start=&quot;2132&quot;&gt;&lt;b&gt;operation&lt;/b&gt;: append / overwrite / delete 등&lt;/li&gt;
&lt;li data-end=&quot;2226&quot; data-start=&quot;2181&quot;&gt;&lt;b&gt;summary&lt;/b&gt;: record count, 파일 수, 파티션 통계 등&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2284&quot; data-start=&quot;2228&quot; data-ke-size=&quot;size16&quot;&gt;  $snapshots는 Iceberg 테이블의 &lt;b&gt;전체 히스토리와 파일 구조 추적&lt;/b&gt;의 시작점&lt;/p&gt;
&lt;hr data-end=&quot;2289&quot; data-start=&quot;2286&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2329&quot; data-start=&quot;2291&quot;&gt;  7. Trino에서 $refs (Branch / Tag)&lt;/h1&gt;
&lt;p data-end=&quot;2416&quot; data-start=&quot;2331&quot; data-ke-size=&quot;size16&quot;&gt;$refs는 &lt;b&gt;현재 살아있는 참조 (branch, tag)&lt;/b&gt; 목록을 보여줍니다.&lt;br /&gt;즉, 어떤 snapshot_id를 보호하고 있는지 확인 가능.&lt;/p&gt;
&lt;p data-end=&quot;2416&quot; data-start=&quot;2331&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1753968983545&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT name,
       type,
       snapshot_id,
       min_snapshots_to_keep,
       max_snapshot_age_ms,
       max_ref_age_ms
FROM table_name$refs;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 113px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;height: 43px;&quot;&gt;name&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 43px;&quot;&gt;type&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 43px;&quot;&gt;snapshot_id&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 43px;&quot;&gt;min_snapshots_to_keep&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 43px;&quot;&gt;max_snapshot_age_ms&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 43px;&quot;&gt;max_ref_age_ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 35px;&quot;&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;main&lt;/td&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;BRANCH&lt;/td&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;4151342690114749344&lt;/td&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;NULL&lt;/td&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 35px;&quot;&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;month_end_202507&lt;/td&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;TAG&lt;/td&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;4151342690114749221&lt;/td&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;NULL&lt;/td&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;NULL&lt;/td&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;31536000000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3184&quot; data-start=&quot;3042&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3083&quot; data-start=&quot;3042&quot;&gt;&lt;b&gt;name&lt;/b&gt;: 참조 이름 (main, branch명, tag명)&lt;/li&gt;
&lt;li data-end=&quot;3110&quot; data-start=&quot;3084&quot;&gt;&lt;b&gt;type&lt;/b&gt;: BRANCH / TAG&lt;/li&gt;
&lt;li data-end=&quot;3152&quot; data-start=&quot;3111&quot;&gt;&lt;b&gt;snapshot_id&lt;/b&gt;: 해당 참조가 가리키는 snapshot&lt;/li&gt;
&lt;li data-end=&quot;3184&quot; data-start=&quot;3153&quot;&gt;&lt;b&gt;보존 정책 필드&lt;/b&gt;: 만료 정책 (ms 단위)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3246&quot; data-start=&quot;3186&quot; data-ke-size=&quot;size16&quot;&gt;  $refs를 보면 어떤 snapshot이 expire 대상에서 &lt;b&gt;제외되는지&lt;/b&gt; 한눈에 알 수 있음&lt;/p&gt;
&lt;p data-end=&quot;3246&quot; data-start=&quot;3186&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3246&quot; data-start=&quot;3186&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3246&quot; data-start=&quot;3186&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-end=&quot;3300&quot; data-start=&quot;3253&quot;&gt;  8. $snapshots + $refs로 Iceberg 구조 이해하기&lt;/h1&gt;
&lt;p data-end=&quot;3307&quot; data-start=&quot;3302&quot; data-ke-size=&quot;size16&quot;&gt;예시:&lt;/p&gt;
&lt;pre id=&quot;code_1753969077835&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT r.name, r.type, r.snapshot_id, s.committed_at, s.operation
FROM table_name$refs r
JOIN table_name$snapshots s
  ON r.snapshot_id = s.snapshot_id
ORDER BY s.committed_at DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결과:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;3835&quot; data-start=&quot;3507&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;name&lt;/td&gt;
&lt;td&gt;type&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;background-color: #6ed3d8; color: #ffffff; text-align: start;&quot;&gt;snapshot_id&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;background-color: #6ed3d8; color: #ffffff; text-align: start;&quot;&gt;committed_at&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;background-color: #6ed3d8; color: #ffffff; text-align: start;&quot;&gt;operation&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3753&quot; data-start=&quot;3672&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3691&quot; data-start=&quot;3672&quot;&gt;main&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3700&quot; data-start=&quot;3691&quot;&gt;BRANCH&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3721&quot; data-start=&quot;3700&quot;&gt;4151342690114749344&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3741&quot; data-start=&quot;3721&quot;&gt;2025-07-27 00:00&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3753&quot; data-start=&quot;3741&quot;&gt;append&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3835&quot; data-start=&quot;3754&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3773&quot; data-start=&quot;3754&quot;&gt;month_end_202507&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3782&quot; data-start=&quot;3773&quot;&gt;TAG&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3803&quot; data-start=&quot;3782&quot;&gt;4151342690114749221&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3823&quot; data-start=&quot;3803&quot;&gt;2025-07-26 00:00&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3835&quot; data-start=&quot;3823&quot;&gt;overwrite&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3915&quot; data-start=&quot;3837&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3868&quot; data-start=&quot;3837&quot;&gt;main branch &amp;rarr; 최신 snapshot&lt;/li&gt;
&lt;li data-end=&quot;3915&quot; data-start=&quot;3869&quot;&gt;month_end_202507 tag &amp;rarr; 이전 snapshot 고정 보존&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3926&quot; data-start=&quot;3917&quot; data-ke-size=&quot;size16&quot;&gt;이 구조를 통해:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4008&quot; data-start=&quot;3927&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3963&quot; data-start=&quot;3927&quot;&gt;데이터 파일 계층이 어떻게 스냅샷으로 묶여있는지 확인 가능&lt;/li&gt;
&lt;li data-end=&quot;4008&quot; data-start=&quot;3964&quot;&gt;어떤 snapshot이 보존되고 어떤 건 expire 대상인지 식별 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ 정리&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4269&quot; data-start=&quot;4023&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4053&quot; data-start=&quot;4023&quot;&gt;&lt;b&gt;data/&lt;/b&gt; &amp;rarr; 실제 파티션별 데이터 파일&lt;/li&gt;
&lt;li data-end=&quot;4094&quot; data-start=&quot;4054&quot;&gt;&lt;b&gt;metadata/&lt;/b&gt; &amp;rarr; snapshot/manifest 정의&lt;/li&gt;
&lt;li data-end=&quot;4159&quot; data-start=&quot;4095&quot;&gt;$snapshots &amp;rarr; 모든 snapshot 이력 (commit, operation, parent 관계)&lt;/li&gt;
&lt;li data-end=&quot;4208&quot; data-start=&quot;4160&quot;&gt;$refs &amp;rarr; branch/tag &amp;rarr; snapshot 매핑, 보존 정책 확인&lt;/li&gt;
&lt;li data-end=&quot;4269&quot; data-start=&quot;4209&quot;&gt;Trino에서는 FOR VERSION AS OF 'tag_name' 문법으로 태그 기반 조회 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.&lt;/p&gt;
&lt;hr data-end=&quot;2428&quot; data-start=&quot;2425&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2477&quot; data-start=&quot;2430&quot;&gt;  9. Manifest List &amp;harr; Snapshot &amp;harr; Ref 관계 쿼리 예시&lt;/h1&gt;
&lt;p data-end=&quot;2528&quot; data-start=&quot;2479&quot; data-ke-size=&quot;size16&quot;&gt;Trino에서 manifest list를 확인하고 어떤 태그/브랜치가 참조 중인지 조회:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1753969324859&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT r.name AS ref_name,
       r.type,
       s.snapshot_id,
       s.committed_at,
       s.manifest_list
FROM table_name$refs r
JOIN table_name$snapshots s
  ON r.snapshot_id = s.snapshot_id
ORDER BY s.committed_at DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&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;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-end=&quot;2797&quot; data-start=&quot;2773&quot;&gt;  그림으로 요약 (텍스트 다이어그램)&lt;/h1&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1753969351722&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[table_name$refs]
   │   (태그: month_end_202507 &amp;rarr; snapshot_id=4151342690114749344)
   │
   ▼
[table_name$snapshots]
   snapshot_id=4151342690114749344
   manifest_list = snap-4151342690114749344-1-ml.avro
   │
   ▼
[manifest list]
   ├─ manifest-001.avro
   └─ manifest-002.avro
       │
       ├─ data-0001.parquet
       ├─ data-0002.parquet
       └─ ...&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3176&quot; data-start=&quot;3170&quot; data-ke-size=&quot;size16&quot;&gt;✅ 정리&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3412&quot; data-start=&quot;3177&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3247&quot; data-start=&quot;3177&quot;&gt;$snapshots.manifest_list &amp;rarr; 특정 snapshot이 참조하는 manifest list 파일 경로&lt;/li&gt;
&lt;li data-end=&quot;3300&quot; data-start=&quot;3248&quot;&gt;&lt;b&gt;manifest list 파일&lt;/b&gt; &amp;rarr; 여러 manifest 파일을 가리키는 Avro&lt;/li&gt;
&lt;li data-end=&quot;3351&quot; data-start=&quot;3301&quot;&gt;&lt;b&gt;manifest 파일&lt;/b&gt; &amp;rarr; 실제 데이터 파일(Parquet 등) + 통계 정보&lt;/li&gt;
&lt;li data-end=&quot;3412&quot; data-start=&quot;3352&quot;&gt;$refs와 조합해 &quot;어떤 태그/브랜치가 어떤 manifest list를 보호 중인지&quot; 파악 가능&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Tools/Iceberg</category>
      <author>칼쵸쵸</author>
      <guid isPermaLink="true">https://chalchichi.tistory.com/137</guid>
      <comments>https://chalchichi.tistory.com/137#entry137comment</comments>
      <pubDate>Thu, 31 Jul 2025 22:43:20 +0900</pubDate>
    </item>
    <item>
      <title>Iceberg에서 Tagging을 활용한 데이터 Snapshot 관리</title>
      <link>https://chalchichi.tistory.com/136</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;191&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bN0PXp/btsPC7JsirP/6M137funKhkzZ5pYEcPb50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bN0PXp/btsPC7JsirP/6M137funKhkzZ5pYEcPb50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bN0PXp/btsPC7JsirP/6M137funKhkzZ5pYEcPb50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbN0PXp%2FbtsPC7JsirP%2F6M137funKhkzZ5pYEcPb50%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;626&quot; height=&quot;191&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;191&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-end=&quot;156&quot; data-start=&quot;129&quot; data-ke-size=&quot;size26&quot;&gt;1. Iceberg에서 Tagging의 개념&lt;/h2&gt;
&lt;p data-end=&quot;219&quot; data-start=&quot;157&quot; data-ke-size=&quot;size16&quot;&gt;Iceberg의 &lt;b&gt;Tag&lt;/b&gt;는 특정 시점의 스냅샷을 &lt;b&gt;이름 기반으로 고정 보존&lt;/b&gt;할 수 있는 기능입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;363&quot; data-start=&quot;220&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;264&quot; data-start=&quot;220&quot;&gt;&lt;b&gt;스냅샷&lt;/b&gt;: 테이블의 특정 시점 상태 (데이터 파일 목록 + 메타데이터)&lt;/li&gt;
&lt;li data-end=&quot;304&quot; data-start=&quot;265&quot;&gt;&lt;b&gt;태그(Tag)&lt;/b&gt;: 스냅샷에 붙이는 &lt;b&gt;사용자 정의 라벨&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;363&quot; data-start=&quot;305&quot;&gt;&lt;b&gt;목적&lt;/b&gt;: 보존(retention) 정책에서 제외하거나, 특정 분석/재처리를 위해 고정 시점 참조&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1753967820473&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ALTER TABLE db.table 
CREATE TAG `month_end_202507` 
AS OF VERSION 4151342690114749344 
RETAIN 365 DAYS;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;561&quot; data-start=&quot;482&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;514&quot; data-start=&quot;482&quot;&gt;AS OF VERSION : 특정 스냅샷 버전 지정&lt;/li&gt;
&lt;li data-end=&quot;561&quot; data-start=&quot;515&quot;&gt;RETAIN : 이 태그를 최소 며칠 동안 보존할지 설정 (만료 보호 기간)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;605&quot; data-start=&quot;568&quot; data-ke-size=&quot;size26&quot;&gt;2. Expire Snapshots와 Tagging의 상호작용&lt;/h2&gt;
&lt;p data-end=&quot;697&quot; data-start=&quot;606&quot; data-ke-size=&quot;size16&quot;&gt;보통 Iceberg 테이블은 &lt;b&gt;expire_snapshots&lt;/b&gt; 명령어를 주기적으로 실행하여&lt;br /&gt;오래된 스냅샷과 관련 파일(데이터, 매니페스트)을 정리합니다.&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre id=&quot;code_1753967846016&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ALTER TABLE db.table 
EXECUTE expire_snapshots(retention_threshold =&amp;gt; '7d');&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;797&quot; data-start=&quot;788&quot; data-ke-size=&quot;size23&quot;&gt;동작 원리&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;872&quot; data-start=&quot;798&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;833&quot; data-start=&quot;798&quot;&gt;retention_threshold보다 오래된 스냅샷을 삭제&lt;/li&gt;
&lt;li data-end=&quot;872&quot; data-start=&quot;834&quot;&gt;&lt;b&gt;단, Tag나 Branch가 참조 중인 스냅샷은 삭제 제외&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;907&quot; data-start=&quot;874&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;즉, 태그가 달린 스냅샷은 expire 대상에서 제외됩니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;907&quot; data-start=&quot;874&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;938&quot; data-start=&quot;914&quot; data-ke-size=&quot;size26&quot;&gt;3. 태그 기반 Expire 제외 전략&lt;/h2&gt;
&lt;h3 data-end=&quot;956&quot; data-start=&quot;940&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;대표 시점 보존&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1051&quot; data-start=&quot;957&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;995&quot; data-start=&quot;957&quot;&gt;월말/분기말/연말 등 &lt;b&gt;대표 시점&lt;/b&gt; 스냅샷에 태그를 걸어 보존&lt;/li&gt;
&lt;li data-end=&quot;1023&quot; data-start=&quot;996&quot;&gt;일반 스냅샷은 7일~30일 단위로 expire&lt;/li&gt;
&lt;li data-end=&quot;1051&quot; data-start=&quot;1024&quot;&gt;태그가 붙은 스냅샷만 장기 보존 (예: 1년)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1753967882762&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 매일 만료 실행 (최근 7일 유지)
ALTER TABLE db.table EXECUTE expire_snapshots(retention_threshold =&amp;gt; '7d');

-- 월말 스냅샷 보존
ALTER TABLE db.table 
CREATE TAG `month_end_202507` 
AS OF VERSION &amp;lt;snapshot_id&amp;gt; 
RETAIN 365 DAYS;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-end=&quot;109&quot; data-start=&quot;87&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-end=&quot;109&quot; data-start=&quot;87&quot; data-ke-size=&quot;size26&quot;&gt;4. Trino에서 태그 기반 조회&lt;/h2&gt;
&lt;p data-end=&quot;153&quot; data-start=&quot;110&quot; data-ke-size=&quot;size16&quot;&gt;Trino는 Iceberg &lt;b&gt;tag name을 직접 지정&lt;/b&gt;할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1753968465027&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT *
FROM table_name
FOR VERSION AS OF 'month_end_202507';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;279&quot; data-start=&quot;230&quot;&gt;'month_end_202507' &amp;rarr; snapshot_id가 아니라 &lt;b&gt;태그명 (문자열 일시)&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;339&quot; data-start=&quot;280&quot;&gt;Trino 엔진이 Iceberg 메타스토어에서 해당 태그가 가리키는 snapshot_id를 찾아서 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tools/Iceberg</category>
      <author>칼쵸쵸</author>
      <guid isPermaLink="true">https://chalchichi.tistory.com/136</guid>
      <comments>https://chalchichi.tistory.com/136#entry136comment</comments>
      <pubDate>Thu, 31 Jul 2025 22:28:57 +0900</pubDate>
    </item>
    <item>
      <title>JVM (Java Virtual Machine) 구조 상세 설명</title>
      <link>https://chalchichi.tistory.com/135</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Egu1o/btsPE4R6w1v/E28Aw3dKJDvGqDu0IAk811/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Egu1o/btsPE4R6w1v/E28Aw3dKJDvGqDu0IAk811/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Egu1o/btsPE4R6w1v/E28Aw3dKJDvGqDu0IAk811/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEgu1o%2FbtsPE4R6w1v%2FE28Aw3dKJDvGqDu0IAk811%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;974&quot; height=&quot;768&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;280&quot; data-start=&quot;168&quot; data-ke-size=&quot;size16&quot;&gt;JVM은 **자바 바이트코드(.class 파일)**를 실행하기 위한 &lt;b&gt;가상 머신&lt;/b&gt;이에요.&lt;br /&gt;구조적으로는 크게 &lt;b&gt;클래스 로더, 런타임 데이터 영역, 실행 엔진, 네이티브 인터페이스&lt;/b&gt;로 나뉘어요.&lt;/p&gt;
&lt;hr data-end=&quot;285&quot; data-start=&quot;282&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;325&quot; data-start=&quot;287&quot; data-ke-size=&quot;size26&quot;&gt;1️⃣ 클래스 로더 (Class Loader Subsystem)&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;735&quot; data-start=&quot;326&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;378&quot; data-start=&quot;326&quot;&gt;&lt;b&gt;역할:&lt;/b&gt; .class 파일(바이트코드)을 메모리로 적재해서 런타임 영역에 올림&lt;/li&gt;
&lt;li data-end=&quot;432&quot; data-start=&quot;379&quot;&gt;&lt;b&gt;동적 로딩(Dynamic Loading)&lt;/b&gt;: 실행 중 필요한 클래스만 메모리에 로드&lt;/li&gt;
&lt;li data-end=&quot;735&quot; data-start=&quot;433&quot;&gt;&lt;b&gt;주요 단계&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;735&quot; data-start=&quot;447&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;497&quot; data-start=&quot;447&quot;&gt;&lt;b&gt;Loading&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;497&quot; data-start=&quot;469&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;497&quot; data-start=&quot;469&quot;&gt;클래스 파일을 읽어 Method Area에 로드&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;678&quot; data-start=&quot;500&quot;&gt;&lt;b&gt;Linking&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;678&quot; data-start=&quot;522&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;565&quot; data-start=&quot;522&quot;&gt;&lt;b&gt;Verification&lt;/b&gt;: 바이트코드가 JVM 규격에 맞는지 검사&lt;/li&gt;
&lt;li data-end=&quot;619&quot; data-start=&quot;571&quot;&gt;&lt;b&gt;Preparation&lt;/b&gt;: static 변수에 메모리 할당 &amp;amp; 기본값 초기화&lt;/li&gt;
&lt;li data-end=&quot;678&quot; data-start=&quot;625&quot;&gt;&lt;b&gt;Resolution&lt;/b&gt;: 심볼릭 참조(클래스명, 메소드명 등)를 실제 메모리 주소로 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;735&quot; data-start=&quot;681&quot;&gt;&lt;b&gt;Initialization&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;735&quot; data-start=&quot;710&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;735&quot; data-start=&quot;710&quot;&gt;static 변수와 static 블록 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;740&quot; data-start=&quot;737&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;779&quot; data-start=&quot;742&quot; data-ke-size=&quot;size26&quot;&gt;2️⃣ 런타임 데이터 영역 (Runtime Data Area)&lt;/h2&gt;
&lt;p data-end=&quot;822&quot; data-start=&quot;780&quot; data-ke-size=&quot;size16&quot;&gt;JVM 프로세스 안에서 데이터를 저장하고 관리하는 &lt;b&gt;메모리 영역&lt;/b&gt;이에요.&lt;/p&gt;
&lt;h3 data-end=&quot;851&quot; data-start=&quot;824&quot; data-ke-size=&quot;size23&quot;&gt;  [공유 영역 - 모든 스레드가 공유]&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1289&quot; data-start=&quot;852&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;999&quot; data-start=&quot;852&quot;&gt;&lt;b&gt;Method Area (또는 MetaSpace, JDK 8 이후)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;999&quot; data-start=&quot;901&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;936&quot; data-start=&quot;901&quot;&gt;클래스 구조, 메소드, 상수 풀, static 변수 저장&lt;/li&gt;
&lt;li data-end=&quot;999&quot; data-start=&quot;940&quot;&gt;JDK 8 이전에는 PermGen 영역이었으나, 이후 MetaSpace로 교체 (네이티브 메모리 사용)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1289&quot; data-start=&quot;1001&quot;&gt;&lt;b&gt;Heap Area&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1289&quot; data-start=&quot;1023&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1050&quot; data-start=&quot;1023&quot;&gt;모든 객체 인스턴스와 배열이 저장되는 영역&lt;/li&gt;
&lt;li data-end=&quot;1067&quot; data-start=&quot;1054&quot;&gt;GC의 주요 대상&lt;/li&gt;
&lt;li data-end=&quot;1247&quot; data-start=&quot;1071&quot;&gt;세분화 구조
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1247&quot; data-start=&quot;1085&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1187&quot; data-start=&quot;1085&quot;&gt;&lt;b&gt;Young Generation&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1187&quot; data-start=&quot;1115&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1138&quot; data-start=&quot;1115&quot;&gt;Eden Space: 새로 생성된 객체&lt;/li&gt;
&lt;li data-end=&quot;1187&quot; data-start=&quot;1146&quot;&gt;Survivor Space (S0/S1): GC에서 살아남은 객체 이동&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1247&quot; data-start=&quot;1193&quot;&gt;&lt;b&gt;Old Generation (Tenured)&lt;/b&gt;: 여러 번 GC를 거쳐 살아남은 장수 객체&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1289&quot; data-start=&quot;1251&quot;&gt;Heap은 JVM 성능 튜닝의 핵심 (-Xmx, -Xms)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;1294&quot; data-start=&quot;1291&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1325&quot; data-start=&quot;1296&quot; data-ke-size=&quot;size23&quot;&gt;  [스레드별 영역 - 각 스레드마다 생성]&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1714&quot; data-start=&quot;1326&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1402&quot; data-start=&quot;1326&quot;&gt;&lt;b&gt;PC Register (Program Counter Register)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1402&quot; data-start=&quot;1377&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1402&quot; data-start=&quot;1377&quot;&gt;현재 실행 중인 JVM 명령어의 주소 보관&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1624&quot; data-start=&quot;1404&quot;&gt;&lt;b&gt;JVM Stack&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1624&quot; data-start=&quot;1426&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1452&quot; data-start=&quot;1426&quot;&gt;메서드 호출 시 생성되는 Frame 저장&lt;/li&gt;
&lt;li data-end=&quot;1600&quot; data-start=&quot;1456&quot;&gt;Frame 구조
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1600&quot; data-start=&quot;1472&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1512&quot; data-start=&quot;1472&quot;&gt;&lt;b&gt;Local Variables Array&lt;/b&gt;: 매개변수 &amp;amp; 지역변수&lt;/li&gt;
&lt;li data-end=&quot;1547&quot; data-start=&quot;1518&quot;&gt;&lt;b&gt;Operand Stack&lt;/b&gt;: 연산 중간 결과&lt;/li&gt;
&lt;li data-end=&quot;1600&quot; data-start=&quot;1553&quot;&gt;&lt;b&gt;Frame Data&lt;/b&gt;: 메서드/클래스 정보, Exception 처리기 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1624&quot; data-start=&quot;1604&quot;&gt;스레드 종료 시 스택도 함께 제거&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1714&quot; data-start=&quot;1626&quot;&gt;&lt;b&gt;Native Method Stack&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1714&quot; data-start=&quot;1658&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1714&quot; data-start=&quot;1658&quot;&gt;JNI (Java Native Interface)로 호출되는 C/C++ 같은 네이티브 코드용 스택&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;1719&quot; data-start=&quot;1716&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1752&quot; data-start=&quot;1721&quot; data-ke-size=&quot;size26&quot;&gt;3️⃣ 실행 엔진 (Execution Engine)&lt;/h2&gt;
&lt;p data-end=&quot;1783&quot; data-start=&quot;1753&quot; data-ke-size=&quot;size16&quot;&gt;클래스 로더가 적재한 바이트코드를 실제로 실행하는 부분&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;2284&quot; data-start=&quot;1785&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1853&quot; data-start=&quot;1785&quot;&gt;&lt;b&gt;인터프리터&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1853&quot; data-start=&quot;1803&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1826&quot; data-start=&quot;1803&quot;&gt;바이트코드를 한 줄씩 해석 후 실행&lt;/li&gt;
&lt;li data-end=&quot;1853&quot; data-start=&quot;1830&quot;&gt;빠른 시작 가능하지만 실행 속도는 느림&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1995&quot; data-start=&quot;1855&quot;&gt;&lt;b&gt;JIT 컴파일러 (Just-In-Time Compiler)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1995&quot; data-start=&quot;1900&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1935&quot; data-start=&quot;1900&quot;&gt;자주 실행되는 바이트코드를 &lt;b&gt;기계어로 변환 후 캐시&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1967&quot; data-start=&quot;1939&quot;&gt;이후에는 인터프리팅 없이 네이티브 코드 실행&lt;/li&gt;
&lt;li data-end=&quot;1995&quot; data-start=&quot;1971&quot;&gt;HotSpot JVM의 핵심 성능 최적화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2284&quot; data-start=&quot;1997&quot;&gt;&lt;b&gt;Garbage Collector (GC)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2284&quot; data-start=&quot;2032&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2058&quot; data-start=&quot;2032&quot;&gt;Heap 영역의 불필요한 객체 자동 해제&lt;/li&gt;
&lt;li data-end=&quot;2284&quot; data-start=&quot;2062&quot;&gt;대표 알고리즘
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2284&quot; data-start=&quot;2077&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2101&quot; data-start=&quot;2077&quot;&gt;&lt;b&gt;Serial GC&lt;/b&gt; (단일 스레드)&lt;/li&gt;
&lt;li data-end=&quot;2139&quot; data-start=&quot;2107&quot;&gt;&lt;b&gt;Parallel GC&lt;/b&gt; (여러 스레드 병렬 수집)&lt;/li&gt;
&lt;li data-end=&quot;2199&quot; data-start=&quot;2145&quot;&gt;&lt;b&gt;CMS (Concurrent Mark-Sweep)&lt;/b&gt; &amp;rarr; JDK 9부터 deprecated&lt;/li&gt;
&lt;li data-end=&quot;2247&quot; data-start=&quot;2205&quot;&gt;&lt;b&gt;G1 GC (Garbage-First)&lt;/b&gt; &amp;rarr; 대용량 Heap에 유리&lt;/li&gt;
&lt;li data-end=&quot;2284&quot; data-start=&quot;2253&quot;&gt;&lt;b&gt;ZGC, Shenandoah&lt;/b&gt; &amp;rarr; 초저지연 목적&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;2289&quot; data-start=&quot;2286&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2314&quot; data-start=&quot;2291&quot; data-ke-size=&quot;size26&quot;&gt;4️⃣ 네이티브 인터페이스 (JNI)&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2418&quot; data-start=&quot;2315&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2360&quot; data-start=&quot;2315&quot;&gt;Java에서 네이티브 라이브러리(C/C++)를 호출할 수 있게 하는 인터페이스&lt;/li&gt;
&lt;li data-end=&quot;2388&quot; data-start=&quot;2361&quot;&gt;OS API나 고성능 라이브러리 호출 시 사용&lt;/li&gt;
&lt;li data-end=&quot;2418&quot; data-start=&quot;2389&quot;&gt;Native Method Libraries와 연동&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2423&quot; data-start=&quot;2420&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2439&quot; data-start=&quot;2425&quot; data-ke-size=&quot;size26&quot;&gt;⚙️ 실행 흐름 예시&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1753967527065&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[.java 파일] &amp;rarr; javac &amp;rarr; [.class 파일]
         &amp;darr;
    Class Loader
         &amp;darr;
   Runtime Data Area
         &amp;darr;
   Execution Engine
     ↳ Interpreter &amp;amp; JIT
     ↳ GC 관리
         &amp;darr;
   Native Interface
         &amp;darr;
       OS / 하드웨어&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-end=&quot;2677&quot; data-start=&quot;2674&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2694&quot; data-start=&quot;2679&quot; data-ke-size=&quot;size26&quot;&gt;  성능/튜닝 포인트&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;2932&quot; data-start=&quot;2695&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;2733&quot; data-start=&quot;2695&quot;&gt;&lt;b&gt;Heap 크기 조정&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2733&quot; data-start=&quot;2716&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2733&quot; data-start=&quot;2716&quot;&gt;-Xmx / -Xms&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2788&quot; data-start=&quot;2734&quot;&gt;&lt;b&gt;GC 알고리즘 선택&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2788&quot; data-start=&quot;2755&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2788&quot; data-start=&quot;2755&quot;&gt;대규모 데이터 처리 시 G1GC, 저지연 필요 시 ZGC&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2826&quot; data-start=&quot;2789&quot;&gt;&lt;b&gt;Thread Stack 크기&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2826&quot; data-start=&quot;2815&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2826&quot; data-start=&quot;2815&quot;&gt;-Xss 옵션&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2874&quot; data-start=&quot;2827&quot;&gt;&lt;b&gt;Metaspace 크기&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2874&quot; data-start=&quot;2850&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2874&quot; data-start=&quot;2850&quot;&gt;-XX:MaxMetaspaceSize&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2932&quot; data-start=&quot;2875&quot;&gt;&lt;b&gt;JIT Warm-up 시간 고려&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2932&quot; data-start=&quot;2903&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2932&quot; data-start=&quot;2903&quot;&gt;서버 앱은 장시간 실행 시 JIT 최적화 효과 큼&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;2937&quot; data-start=&quot;2934&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;2952&quot; data-start=&quot;2939&quot; data-ke-size=&quot;size16&quot;&gt;✅ 요약&lt;br /&gt;JVM은&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3099&quot; data-start=&quot;2953&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2984&quot; data-start=&quot;2953&quot;&gt;&lt;b&gt;클래스 로더&lt;/b&gt;로 바이트코드를 메모리에 올리고&lt;/li&gt;
&lt;li data-end=&quot;3024&quot; data-start=&quot;2985&quot;&gt;&lt;b&gt;런타임 데이터 영역&lt;/b&gt;에서 객체와 스레드별 메모리를 관리하며&lt;/li&gt;
&lt;li data-end=&quot;3069&quot; data-start=&quot;3025&quot;&gt;&lt;b&gt;실행 엔진&lt;/b&gt;이 인터프리터 &amp;amp; JIT &amp;amp; GC를 통해 코드를 실행하고&lt;/li&gt;
&lt;li data-end=&quot;3099&quot; data-start=&quot;3070&quot;&gt;필요 시 &lt;b&gt;JNI&lt;/b&gt;로 네이티브 코드와 통신&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programing Language/JAVA</category>
      <author>칼쵸쵸</author>
      <guid isPermaLink="true">https://chalchichi.tistory.com/135</guid>
      <comments>https://chalchichi.tistory.com/135#entry135comment</comments>
      <pubDate>Thu, 31 Jul 2025 22:12:45 +0900</pubDate>
    </item>
    <item>
      <title>파이썬의 동작 과정</title>
      <link>https://chalchichi.tistory.com/134</link>
      <description>&lt;h1 data-end=&quot;141&quot; data-start=&quot;119&quot; data-section-id=&quot;1or7bxv&quot;&gt;  파이썬 &amp;harr; C 관계 &amp;amp; 가상환경&lt;/h1&gt;
&lt;h2 data-end=&quot;159&quot; data-start=&quot;143&quot; data-section-id=&quot;a71hu5&quot; data-ke-size=&quot;size26&quot;&gt;1. 파이썬과 C의 관계&lt;/h2&gt;
&lt;p data-end=&quot;205&quot; data-start=&quot;161&quot; data-ke-size=&quot;size16&quot;&gt;파이썬(특히 &lt;b&gt;CPython&lt;/b&gt;)은 사실상 &lt;b&gt;C로 구현된 인터프리터&lt;/b&gt;예요.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;380&quot; data-start=&quot;207&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;255&quot; data-start=&quot;207&quot;&gt;&lt;b&gt;CPython&lt;/b&gt;: 가장 널리 쓰이는 파이썬 구현체 (Python 공식 배포판)&lt;/li&gt;
&lt;li data-end=&quot;349&quot; data-start=&quot;256&quot;&gt;핵심 원리:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;349&quot; data-start=&quot;267&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;303&quot; data-start=&quot;267&quot;&gt;파이썬 소스 코드 &amp;rarr; **바이트코드(.pyc)**로 컴파일&lt;/li&gt;
&lt;li data-end=&quot;349&quot; data-start=&quot;306&quot;&gt;이 바이트코드를 **C로 작성된 인터프리터(CPython VM)**가 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;380&quot; data-start=&quot;350&quot;&gt;파이썬 객체(PyObject)는 C 구조체로 관리됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;384&quot; data-start=&quot;382&quot; data-ke-size=&quot;size16&quot;&gt;즉:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;432&quot; data-start=&quot;385&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;407&quot; data-start=&quot;385&quot;&gt;파이썬은 &quot;문법과 문화를 가진 언어&quot;&lt;/li&gt;
&lt;li data-end=&quot;432&quot; data-start=&quot;408&quot;&gt;CPython은 &quot;C로 만들어진 실행기&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1753797170772&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = 10&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;521&quot; data-start=&quot;463&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;481&quot; data-start=&quot;463&quot;&gt;a는 스택에 참조 저장&lt;/li&gt;
&lt;li data-end=&quot;521&quot; data-start=&quot;482&quot;&gt;10은 힙에 PyLongObject라는 C 구조체로 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;576&quot; data-start=&quot;523&quot; data-ke-size=&quot;size16&quot;&gt;  파이썬에서 int, list 같은 객체들은 실제로 &lt;b&gt;C 언어 구조체&lt;/b&gt;에 불과함.&lt;/p&gt;
&lt;p data-end=&quot;576&quot; data-start=&quot;523&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;576&quot; data-start=&quot;523&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;603&quot; data-start=&quot;583&quot; data-section-id=&quot;17lhys5&quot; data-ke-size=&quot;size26&quot;&gt;2. 왜 C 기반으로 동작할까?&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;747&quot; data-start=&quot;605&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;644&quot; data-start=&quot;605&quot;&gt;&lt;b&gt;성능&lt;/b&gt;: C는 저수준 언어라서 메모리와 CPU 제어에 강함&lt;/li&gt;
&lt;li data-end=&quot;715&quot; data-start=&quot;645&quot;&gt;&lt;b&gt;확장성&lt;/b&gt;: 파이썬 라이브러리 중 NumPy, Pandas, TensorFlow 등이 내부적으로 C/C++로 구현됨&lt;/li&gt;
&lt;li data-end=&quot;747&quot; data-start=&quot;716&quot;&gt;&lt;b&gt;호환성&lt;/b&gt;: 운영체제 API와 쉽게 연동 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;792&quot; data-start=&quot;749&quot; data-ke-size=&quot;size16&quot;&gt;따라서, 파이썬은 &lt;b&gt;편리한 문법 + C의 성능&lt;/b&gt;을 동시에 가져가는 구조임.&lt;/p&gt;
&lt;hr data-end=&quot;797&quot; data-start=&quot;794&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;834&quot; data-start=&quot;799&quot; data-section-id=&quot;1xlzy5&quot; data-ke-size=&quot;size26&quot;&gt;3. 가상환경(virtual environment)의 개념&lt;/h2&gt;
&lt;p data-end=&quot;870&quot; data-start=&quot;836&quot; 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-end=&quot;970&quot; data-start=&quot;872&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;906&quot; data-start=&quot;872&quot;&gt;일반적으로 파이썬은 전역(Global) 환경에 설치되는데,&lt;/li&gt;
&lt;li data-end=&quot;948&quot; data-start=&quot;907&quot;&gt;프로젝트마다 필요한 패키지 버전이 다르기 때문에 &lt;b&gt;충돌 문제&lt;/b&gt; 발생&lt;/li&gt;
&lt;li data-end=&quot;970&quot; data-start=&quot;949&quot;&gt;이를 해결하기 위해 가상환경을 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;978&quot; data-start=&quot;972&quot; data-ke-size=&quot;size16&quot;&gt;  장점:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1046&quot; data-start=&quot;979&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1006&quot; data-start=&quot;979&quot;&gt;프로젝트별 &lt;b&gt;패키지/라이브러리 버전 격리&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1026&quot; data-start=&quot;1007&quot;&gt;시스템 파이썬에 영향 주지 않음&lt;/li&gt;
&lt;li data-end=&quot;1046&quot; data-start=&quot;1027&quot;&gt;배포 시 &lt;b&gt;환경 복제 용이&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1051&quot; data-start=&quot;1048&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1069&quot; data-start=&quot;1053&quot; data-section-id=&quot;1l3rqz3&quot; data-ke-size=&quot;size26&quot;&gt;4. 가상환경 동작 원리&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1242&quot; data-start=&quot;1071&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1188&quot; data-start=&quot;1071&quot;&gt;가상환경을 만들면 특정 디렉토리에
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1188&quot; data-start=&quot;1096&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1129&quot; data-start=&quot;1096&quot;&gt;bin (또는 Scripts): 파이썬 실행 파일&lt;/li&gt;
&lt;li data-end=&quot;1152&quot; data-start=&quot;1133&quot;&gt;lib: 설치된 패키지 저장&lt;/li&gt;
&lt;li data-end=&quot;1188&quot; data-start=&quot;1156&quot;&gt;pyvenv.cfg: 가상환경 설정&lt;br /&gt;이 생성됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1242&quot; data-start=&quot;1190&quot;&gt;활성화 시, &lt;b&gt;PATH 환경변수&lt;/b&gt;가 바뀌어 해당 디렉토리 안의 파이썬을 사용하게 됨.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1753797235177&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 가상환경 생성
python -m venv myenv

# 활성화
source myenv/bin/activate   # macOS/Linux
myenv\Scripts\activate      # Windows&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 종료 시에는 PATH가 원래대로 돌아옴.&lt;/p&gt;
&lt;pre id=&quot;code_1753797246357&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;deactivate&lt;/code&gt;&lt;/pre&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;1448&quot; data-start=&quot;1431&quot; data-section-id=&quot;1lvbbqx&quot; data-ke-size=&quot;size26&quot;&gt;5. 가상환경과 C의 관계&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1605&quot; data-start=&quot;1450&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1528&quot; data-start=&quot;1450&quot;&gt;가상환경은 &lt;b&gt;파이썬 실행 파일&lt;/b&gt;과 **해당 실행기에 필요한 라이브러리(C 기반 모듈 포함)**를 &lt;b&gt;격리된 디렉토리&lt;/b&gt;에 모아둔 것.&lt;/li&gt;
&lt;li data-end=&quot;1605&quot; data-start=&quot;1529&quot;&gt;예를 들어, NumPy 같은 패키지는 내부적으로 C 코드로 되어 있는데, 가상환경 안에 설치되면 &lt;b&gt;그 환경 안에서만 접근 가능&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1753797258051&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[시스템 파이썬] ----+
                   |
                   +--&amp;gt; [가상환경 myenv]
                   |        ├─ bin/python (별도 실행기)
                   |        ├─ lib/site-packages (패키지들)
                   |        └─ C 기반 모듈 (numpy, pandas 등)
                   |
                   +--&amp;gt; [가상환경 projectX]
                            ├─ bin/python
                            ├─ lib/site-packages
                            └─ 다른 버전의 패키지들&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ 정리&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2180&quot; data-start=&quot;2081&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2129&quot; data-start=&quot;2081&quot;&gt;파이썬은 C로 만들어진 CPython 위에서 동작하며, 실제 객체는 C 구조체임&lt;/li&gt;
&lt;li data-end=&quot;2180&quot; data-start=&quot;2130&quot;&gt;가상환경은 프로젝트별로 &lt;b&gt;파이썬 인터프리터와 라이브러리를 격리&lt;/b&gt;시켜주는 시스템임&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-end=&quot;194&quot; data-start=&quot;155&quot; data-section-id=&quot;iw92kw&quot;&gt;  파이썬 실행 과정 (C, 인터프리터, 컴파일러, 메모리 관점)&lt;/h1&gt;
&lt;h2 data-end=&quot;218&quot; data-start=&quot;196&quot; data-section-id=&quot;12ju7a9&quot; data-ke-size=&quot;size26&quot;&gt;1. 파이썬 코드 &amp;rarr; 실행까지 흐름&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1753797280067&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;.py 파일 작성
   &amp;darr;
[컴파일러] Python Compiler
   &amp;darr; 바이트코드(.pyc) 생성
[인터프리터] CPython Virtual Machine
   &amp;darr; 바이트코드 해석
[메모리] 스택/힙에 객체 배치
   &amp;darr;
CPU에서 실행&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;382&quot; data-start=&quot;370&quot; data-section-id=&quot;1evn5lc&quot; data-ke-size=&quot;size26&quot;&gt;2. 단계별 설명&lt;/h2&gt;
&lt;h3 data-end=&quot;399&quot; data-start=&quot;384&quot; data-section-id=&quot;nr5tyu&quot; data-ke-size=&quot;size23&quot;&gt;(1) 소스코드 작성&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;430&quot; data-start=&quot;400&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;430&quot; data-start=&quot;400&quot;&gt;우리가 작성한 .py 파일은 &lt;b&gt;순수 텍스트&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1753797295261&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;x = 10
y = 20
print(x + y)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;498&quot; data-start=&quot;482&quot; data-section-id=&quot;1dbfoa1&quot; data-ke-size=&quot;size23&quot;&gt;(2) 파이썬 컴파일러&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;597&quot; data-start=&quot;499&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;545&quot; data-start=&quot;499&quot;&gt;파이썬도 &lt;b&gt;컴파일러&lt;/b&gt;를 갖고 있음 (단, 기계어가 아니라 바이트코드로 변환)&lt;/li&gt;
&lt;li data-end=&quot;570&quot; data-start=&quot;546&quot;&gt;결과물: &lt;b&gt;바이트코드(.pyc)&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;597&quot; data-start=&quot;571&quot;&gt;보통 __pycache__ 폴더에 저장됨&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1753797314332&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python -m py_compile script.py&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바이트코드 예시 (추상화):&lt;/p&gt;
&lt;pre id=&quot;code_1753797326437&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;LOAD_CONST 10
STORE_NAME x
LOAD_CONST 20
STORE_NAME y
LOAD_NAME print
CALL_FUNCTION 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;780&quot; data-start=&quot;759&quot; data-section-id=&quot;tkd98z&quot; data-ke-size=&quot;size23&quot;&gt;(3) CPython 인터프리터&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;881&quot; data-start=&quot;781&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;802&quot; data-start=&quot;781&quot;&gt;바이트코드를 한 줄씩 읽어 실행&lt;/li&gt;
&lt;li data-end=&quot;847&quot; data-start=&quot;803&quot;&gt;이때 내부적으로는 **C로 구현된 가상머신 (CPython VM)**이 동작&lt;/li&gt;
&lt;li data-end=&quot;881&quot; data-start=&quot;848&quot;&gt;eval_frame 같은 C 함수가 바이트코드를 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;885&quot; data-start=&quot;883&quot; data-ke-size=&quot;size16&quot;&gt;즉:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;932&quot; data-start=&quot;886&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;908&quot; data-start=&quot;886&quot;&gt;컴파일러: .py &amp;rarr; .pyc&lt;/li&gt;
&lt;li data-end=&quot;932&quot; data-start=&quot;909&quot;&gt;인터프리터: .pyc &amp;rarr; 실제 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;937&quot; data-start=&quot;934&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;956&quot; data-start=&quot;939&quot; data-section-id=&quot;t8l33e&quot; data-ke-size=&quot;size23&quot;&gt;(4) 메모리 구조 활용&lt;/h3&gt;
&lt;p data-end=&quot;970&quot; data-start=&quot;958&quot; data-ke-size=&quot;size16&quot;&gt;실행 시 메모리 구성:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1228&quot; data-start=&quot;972&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1055&quot; data-start=&quot;972&quot;&gt;&lt;b&gt;스택 (Stack)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1055&quot; data-start=&quot;993&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1032&quot; data-start=&quot;993&quot;&gt;함수 호출 시 로컬 변수 이름과 &lt;b&gt;객체 참조(포인터)&lt;/b&gt; 저장&lt;/li&gt;
&lt;li data-end=&quot;1055&quot; data-start=&quot;1035&quot;&gt;x, y 같은 변수명 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1164&quot; data-start=&quot;1057&quot;&gt;&lt;b&gt;힙 (Heap)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1164&quot; data-start=&quot;1076&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1112&quot; data-start=&quot;1076&quot;&gt;실제 객체 데이터 저장 (10, 20, 리스트 등)&lt;/li&gt;
&lt;li data-end=&quot;1135&quot; data-start=&quot;1115&quot;&gt;모든 파이썬 객체는 힙에 있음&lt;/li&gt;
&lt;li data-end=&quot;1164&quot; data-start=&quot;1138&quot;&gt;객체는 C 구조체(PyObject) 형태&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1228&quot; data-start=&quot;1166&quot;&gt;&lt;b&gt;GC (Garbage Collector)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1228&quot; data-start=&quot;1199&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1228&quot; data-start=&quot;1199&quot;&gt;참조 카운트 + 세대별 수집으로 메모리 해제 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1233&quot; data-start=&quot;1230&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1247&quot; data-start=&quot;1235&quot; data-section-id=&quot;osr9uv&quot; data-ke-size=&quot;size26&quot;&gt;3. C와의 관계&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1350&quot; data-start=&quot;1249&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1289&quot; data-start=&quot;1249&quot;&gt;CPython은 C로 작성됨 &amp;rarr; 바이트코드를 &lt;b&gt;C 함수들이 해석&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1312&quot; data-start=&quot;1290&quot;&gt;파이썬 객체는 모두 &lt;b&gt;C 구조체&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1350&quot; data-start=&quot;1313&quot;&gt;수학 연산이나 리스트 조작 등은 결국 &lt;b&gt;C 코드 함수 호출&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1753797343749&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = [1,2,3]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1453&quot; data-start=&quot;1386&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1404&quot; data-start=&quot;1386&quot;&gt;a (스택에 저장된 이름)&lt;/li&gt;
&lt;li data-end=&quot;1453&quot; data-start=&quot;1405&quot;&gt;[1,2,3] (힙에 저장된 PyListObject &amp;rarr; 내부적으로 C 배열)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 그림으로 이해하기&lt;/h3&gt;
&lt;pre id=&quot;code_1753797374253&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[파이썬 코드] .py
   &amp;darr; 컴파일러
[바이트코드] .pyc
   &amp;darr; 인터프리터(CPython VM)
 ┌─────────────────────┐
 │   C로 구현된 가상머신 │
 │   (eval_frame 등)   │
 └─────────┬───────────┘
           │
      ┌────┴─────┐
      │ 메모리 구조│
      │           │
      │ [스택]    │ &amp;rarr; 변수 참조 저장
      │ [힙]      │ &amp;rarr; 객체(PyObject) 저장
      │ [GC]      │ &amp;rarr; 참조 카운트 &amp;amp; 순환 수집
      └───────────┘&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;1842&quot; data-start=&quot;1834&quot; data-section-id=&quot;zezzaf&quot; data-ke-size=&quot;size26&quot;&gt;5. 정리&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2049&quot; data-start=&quot;1844&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1884&quot; data-start=&quot;1844&quot;&gt;&lt;b&gt;컴파일러&lt;/b&gt;: .py를 **바이트코드(.pyc)**로 변환&lt;/li&gt;
&lt;li data-end=&quot;1927&quot; data-start=&quot;1885&quot;&gt;&lt;b&gt;인터프리터&lt;/b&gt;: 바이트코드를 &lt;b&gt;C로 작성된 가상머신&lt;/b&gt;에서 실행&lt;/li&gt;
&lt;li data-end=&quot;2003&quot; data-start=&quot;1928&quot;&gt;&lt;b&gt;메모리 구조&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2003&quot; data-start=&quot;1946&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1963&quot; data-start=&quot;1946&quot;&gt;스택 &amp;rarr; 변수 참조 저장&lt;/li&gt;
&lt;li data-end=&quot;1982&quot; data-start=&quot;1966&quot;&gt;힙 &amp;rarr; 실제 객체 저장&lt;/li&gt;
&lt;li data-end=&quot;2003&quot; data-start=&quot;1985&quot;&gt;GC &amp;rarr; 메모리 자동 해제&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2049&quot; data-start=&quot;2004&quot;&gt;&lt;b&gt;C의 역할&lt;/b&gt;: CPython 구현, 객체 구조 정의, 핵심 함수 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2054&quot; data-start=&quot;2051&quot; data-ke-style=&quot;style1&quot; /&gt;</description>
      <category>Programing Language/Python</category>
      <author>칼쵸쵸</author>
      <guid isPermaLink="true">https://chalchichi.tistory.com/134</guid>
      <comments>https://chalchichi.tistory.com/134#entry134comment</comments>
      <pubDate>Tue, 29 Jul 2025 22:56:37 +0900</pubDate>
    </item>
    <item>
      <title>파이썬 메모리 구조 개요</title>
      <link>https://chalchichi.tistory.com/133</link>
      <description>&lt;h1&gt;  파이썬 메모리 구조 &amp;amp; GC 정리&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 메모리 구조 개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬 인터프리터(CPython 기준) 메모리 구성:&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;스택(Stack)&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;/li&gt;
&lt;li&gt;실제 데이터가 아닌 객체 &lt;b&gt;참조(포인터)&lt;/b&gt; 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;힙(Heap)&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;list&lt;/code&gt;, &lt;code&gt;dict&lt;/code&gt;, 사용자 정의 객체 등) 저장&lt;/li&gt;
&lt;li&gt;GC와 메모리 풀(Pymalloc) 관리&lt;/li&gt;
&lt;li&gt;크기 동적 할당&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 힙 메모리와 객체 구조&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 객체는 &lt;b&gt;PyObject&lt;/b&gt; 구조체로 관리됨.&lt;/p&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;typedef struct {
    Py_ssize_t ob_refcnt;        // 참조 카운트
    struct _typeobject *ob_type; // 객체 타입
} PyObject;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;ob_refcnt&lt;/code&gt;: 참조 횟수 (GC 관리 기준)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ob_type&lt;/code&gt;: 객체 타입 정보&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p 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 data-ke-size=&quot;size26&quot;&gt;3. 메모리 관리 전략&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;① 참조 카운팅 (Reference Counting)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 객체가 참조될 때마다 카운트 증가&lt;/li&gt;
&lt;li&gt;참조가 0이 되면 즉시 해제&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;a = [1,2,3]
b = a
del a
del b  # refcount=0 &amp;rarr; 해제&lt;/code&gt;&lt;/pre&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;단점&lt;/b&gt;: 순환 참조 해결 불가&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;② 가비지 컬렉터 (GC)&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;세대별 수집(Generational GC)&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;0세대&lt;/b&gt;: 새 객체&lt;/li&gt;
&lt;li&gt;&lt;b&gt;1세대&lt;/b&gt;: 한 번 생존&lt;/li&gt;
&lt;li&gt;&lt;b&gt;2세대&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;/p&gt;
&lt;pre class=&quot;capnproto&quot;&gt;&lt;code&gt;import gc
gc.collect()  # 강제 GC 실행&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;③ 메모리 풀 (Pymalloc)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;작은 객체(512바이트 이하)는 메모리 풀에서 관리&lt;/li&gt;
&lt;li&gt;큰 객체는 OS malloc/free 직접 호출&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 가비지 컬렉션 동작 과정&lt;/h2&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;li&gt;주기적으로 순환 참조 탐색&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gc.collect()&lt;/code&gt;로 강제 실행 가능&lt;/li&gt;
&lt;li&gt;GC 주기 튜닝 가능&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;import gc
gc.set_threshold(700, 10, 10)&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 메모리 구조 시각화&lt;/h2&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;[스택]              &amp;rarr;  함수 호출 시 참조 저장
   └─ a ───────┐
   └─ b ───┐   │
            │   │
[힙]        │   │
   [List]───┘   │
      ├── 1     │
      ├── 2     │
      └── 3     │
                 │
[GC] &amp;larr; refcount 관리 및 순환 참조 탐색&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 메모리 최적화 팁&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;code&gt;__slots__&lt;/code&gt; 사용&lt;/b&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;code&gt;del&lt;/code&gt; 명시적 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Numpy/Pandas&lt;/b&gt;: 메모리 효율적(C 기반)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;GC 주기 조절&lt;/b&gt;: Spark/Airflow 등 대규모 파이프라인에서 유용&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Programing Language/Python</category>
      <author>칼쵸쵸</author>
      <guid isPermaLink="true">https://chalchichi.tistory.com/133</guid>
      <comments>https://chalchichi.tistory.com/133#entry133comment</comments>
      <pubDate>Tue, 29 Jul 2025 22:48:53 +0900</pubDate>
    </item>
    <item>
      <title>Apache Iceberg 기본 동작 확인 및 실습 정리</title>
      <link>https://chalchichi.tistory.com/132</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNP2gS/btsPEOaRy3H/l6FFi34Gq3Q4cyaBRlZdpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNP2gS/btsPEOaRy3H/l6FFi34Gq3Q4cyaBRlZdpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNP2gS/btsPEOaRy3H/l6FFi34Gq3Q4cyaBRlZdpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNP2gS%2FbtsPEOaRy3H%2Fl6FFi34Gq3Q4cyaBRlZdpk%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;1536&quot; height=&quot;1024&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  demo.analytics_users 테이블 상태 변화 요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Snapshot 단계 작업 내용 테이블 상태 (id, name)&lt;/p&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;INSERT (Alice, Bob)&lt;/th&gt;
&lt;th&gt;(1, 'Alice'), (2, 'Bob')&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Snapshot 2&lt;/td&gt;
&lt;td&gt;DELETE id = 2&lt;/td&gt;
&lt;td&gt;(1, 'Alice')&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snapshot 3&lt;/td&gt;
&lt;td&gt;UPDATE id = 1&lt;/td&gt;
&lt;td&gt;(1, 'Charlie')&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snapshot 4&lt;/td&gt;
&lt;td&gt;MERGE INTO (id = 3)&lt;/td&gt;
&lt;td&gt;(1, 'Charlie'), (3, 'David')&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snapshot 5&lt;/td&gt;
&lt;td&gt;ROLLBACK to Snap 1&lt;/td&gt;
&lt;td&gt;(1, 'Alice'), (2, 'Bob')&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snapshot 6&lt;/td&gt;
&lt;td&gt;INSERT (Eve)&lt;/td&gt;
&lt;td&gt;(1, 'Alice'), (2, 'Bob'), (4, 'Eve')&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;✅ 1. Iceberg 테이블 생성 및 데이터 삽입&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  Spark SQL&lt;/h3&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;CREATE TABLE demo.analytics_users (
  id INT,
  name STRING
)
USING ICEBERG
TBLPROPERTIES ('format-version' = '2');

INSERT INTO demo.analytics_users VALUES
  (1, 'Alice'),
  (2, 'Bob');&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  Trino&lt;/h3&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;CREATE TABLE iceberg.demo.analytics_users (
  id INT,
  name VARCHAR
)
WITH (
  format_version = 2
);

INSERT INTO iceberg.demo.analytics_users VALUES
  (1, 'Alice'),
  (2, 'Bob');&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  예상 결과&lt;/b&gt;: 테이블이 정상 생성되고, snapshot 1개가 생성됨 (예: [(1, 'Alice'), (2, 'Bob')])&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;h3 data-ke-size=&quot;size23&quot;&gt;  Spark SQL&lt;/h3&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;SELECT * FROM growth.demo.analytics_users.snapshots;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  Trino&lt;/h3&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT * FROM iceberg.demo.&quot;analytics_users$snapshots&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  예상 결과&lt;/b&gt;: 최소 1개 이상의 snapshot ID, timestamp, operation(insert 등)이 조회됨&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✅ 3. 타임트래블 (Time Travel)&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  Spark (PySpark)&lt;/h3&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;spark.read \
  .format(&quot;iceberg&quot;) \
  .option(&quot;snapshot-id&quot;, &quot;1234567890123&quot;) \
  .load(&quot;demo.analytics_users&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  Trino&lt;/h3&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT * FROM iceberg.demo.analytics_users
FOR VERSION AS OF 1234567890123;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  예상 결과&lt;/b&gt;: 해당 snapshot 시점의 데이터만 조회됨 (예: [(1, 'Alice'), (2, 'Bob')])&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✅ 4. Snapshot 간 데이터 차이 확인&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  Spark (PySpark)&lt;/h3&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;old_df = spark.read.option(&quot;snapshot-id&quot;, &quot;old_id&quot;).format(&quot;iceberg&quot;).load(&quot;demo.analytics_users&quot;)
new_df = spark.read.format(&quot;iceberg&quot;).load(&quot;demo.analytics_users&quot;)

added = new_df.subtract(old_df)
removed = old_df.subtract(new_df)&lt;/code&gt;&lt;/pre&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;added: 새로 추가된 행만 출력됨 (예: [(3, 'Charlie')])&lt;/li&gt;
&lt;li&gt;removed: 삭제된 행만 출력됨 (예: [(2, 'Bob')])&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✅ 5. 시스템 테이블 $changes 조회 (Trino 전용)&lt;/h2&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT * FROM iceberg.demo.&quot;analytics_users$changes&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;❗ DELETE, MERGE, UPDATE 등의 작업이 수행되지 않으면 $changes 테이블은 존재하지 않습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  예상 결과&lt;/b&gt;: 변경 기록(snapshot_id, change_type 등)이 담긴 row가 조회됨 (예: INSERT &amp;rarr; id=3, name='Charlie')&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✅ 6. Row-level 작업 (UPDATE / DELETE / MERGE)&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  Trino&lt;/h3&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;-- DELETE
DELETE FROM iceberg.demo.analytics_users WHERE id = 2;

-- UPDATE
UPDATE iceberg.demo.analytics_users
SET name = 'Charlie' WHERE id = 1;

-- MERGE
MERGE INTO iceberg.demo.analytics_users t
USING (SELECT 3 AS id, 'David' AS name) s
ON t.id = s.id
WHEN MATCHED THEN UPDATE SET name = s.name
WHEN NOT MATCHED THEN INSERT (id, name);&lt;/code&gt;&lt;/pre&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;DELETE: (2, 'Bob') 제거됨&lt;/li&gt;
&lt;li&gt;UPDATE: (1, 'Alice') &amp;rarr; (1, 'Charlie')로 변경&lt;/li&gt;
&lt;li&gt;MERGE: 새로운 행 (3, 'David') 추가됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✅ 7. 롤백 (Rollback)&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  Spark SQL&lt;/h3&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;CALL growth.system.rollback_to_snapshot(
  'demo.analytics_users',
  1234567890123
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  예상 결과&lt;/b&gt;: 테이블의 현재 상태가 지정한 snapshot 시점으로 되돌아감 (예: UPDATE 및 DELETE 이전 상태)&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;</description>
      <category>Tools/Iceberg</category>
      <author>칼쵸쵸</author>
      <guid isPermaLink="true">https://chalchichi.tistory.com/132</guid>
      <comments>https://chalchichi.tistory.com/132#entry132comment</comments>
      <pubDate>Sun, 6 Jul 2025 21:18:42 +0900</pubDate>
    </item>
    <item>
      <title>Trino와 HyperLogLog 알고리즘</title>
      <link>https://chalchichi.tistory.com/131</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;167&quot; data-start=&quot;154&quot; data-ke-size=&quot;size26&quot;&gt;  HyperLogLog&lt;/h2&gt;
&lt;h3 data-end=&quot;167&quot; data-start=&quot;154&quot; data-ke-size=&quot;size23&quot;&gt;핵심 아이디어&lt;/h3&gt;
&lt;h3 data-end=&quot;167&quot; data-start=&quot;154&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&quot;해시값에서 가장 긴 앞자리 0의 개수를 보면, 얼마나 많은 고유 값이 있었는지 추정할 수 있다.&quot;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;365&quot; data-start=&quot;232&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;255&quot; data-start=&quot;232&quot;&gt;원소들을 &lt;b&gt;해시 함수로 변환&lt;/b&gt;하고,&lt;/li&gt;
&lt;li data-end=&quot;314&quot; data-start=&quot;256&quot;&gt;해시값의 **이진 표현에서 가장 앞의 연속된 0의 길이(max leading zeros)**를 기록,&lt;/li&gt;
&lt;li data-end=&quot;365&quot; data-start=&quot;315&quot;&gt;이를 여러 버킷(bucket)에 나눠서 평균/보정하면 전체 고유 수를 추정할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;386&quot; data-start=&quot;372&quot; data-ke-size=&quot;size23&quot;&gt;  왜 효과적인가?&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;491&quot; data-start=&quot;388&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;450&quot; data-start=&quot;388&quot;&gt;해시값은 고유하게 퍼지기 때문에, 많은 고유 값이 들어오면 &lt;b&gt;더 긴 연속된 0이 나타날 확률&lt;/b&gt;이 높아짐.&lt;/li&gt;
&lt;li data-end=&quot;491&quot; data-start=&quot;451&quot;&gt;이걸 통계적으로 계산하면 &lt;b&gt;거의 선형적 정확도&lt;/b&gt;를 얻을 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;506&quot; data-start=&quot;498&quot; data-ke-size=&quot;size23&quot;&gt;  장점&lt;/h3&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 76px;&quot; border=&quot;1&quot; data-end=&quot;702&quot; data-start=&quot;508&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style5&quot;&gt;
&lt;tbody data-end=&quot;702&quot; data-start=&quot;536&quot;&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;575&quot; data-start=&quot;536&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;545&quot; data-start=&quot;536&quot;&gt;메모리 효율&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-end=&quot;575&quot; data-start=&quot;545&quot; data-col-size=&quot;sm&quot;&gt;수십억 개 데이터를 추정하는 데 수 KB만 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;612&quot; data-start=&quot;576&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;581&quot; data-start=&quot;576&quot;&gt;속도&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-end=&quot;612&quot; data-start=&quot;581&quot; data-col-size=&quot;sm&quot;&gt;입력값 처리 시 해시 &amp;rarr; 배열 업데이트만 하면 됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;661&quot; data-start=&quot;613&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;624&quot; data-start=&quot;613&quot;&gt;병렬 처리 용이&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;661&quot; data-start=&quot;624&quot;&gt;HLL 스케치는 쉽게 merge 가능 &amp;rarr; 분산 시스템에 적합&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;702&quot; data-start=&quot;662&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;677&quot; data-start=&quot;662&quot;&gt;추정 정확도 조절 가능&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-end=&quot;702&quot; data-start=&quot;677&quot; data-col-size=&quot;sm&quot;&gt;파라미터로 &amp;plusmn;1% ~ &amp;plusmn;5% 조절 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;717&quot; data-start=&quot;709&quot; data-ke-size=&quot;size23&quot;&gt;  단점&lt;/h3&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;856&quot; data-start=&quot;719&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style5&quot;&gt;
&lt;tbody data-end=&quot;856&quot; data-start=&quot;747&quot;&gt;
&lt;tr data-end=&quot;776&quot; data-start=&quot;747&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;753&quot; data-start=&quot;747&quot;&gt;추정치&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;776&quot; data-start=&quot;753&quot;&gt;정확하지는 않음 (신뢰 구간 존재)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;823&quot; data-start=&quot;777&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;790&quot; data-start=&quot;777&quot;&gt;고유 수가 작을 때&lt;/td&gt;
&lt;td data-end=&quot;823&quot; data-start=&quot;790&quot; data-col-size=&quot;sm&quot;&gt;정확도가 낮아질 수 있음 (bias 보정 기법 존재)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;856&quot; data-start=&quot;824&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;832&quot; data-start=&quot;824&quot;&gt;해시 충돌&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;856&quot; data-start=&quot;832&quot;&gt;극단적인 충돌 가능성 존재하지만 희박&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;861&quot; data-start=&quot;858&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;883&quot; data-start=&quot;863&quot; data-ke-size=&quot;size23&quot;&gt;⚙️ 작동 예시 (단순화 버전)&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1008&quot; data-start=&quot;885&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;921&quot; data-start=&quot;885&quot;&gt;각 입력값에 대해 hash(x)를 계산 &amp;rarr; 이진수로 표현&lt;/li&gt;
&lt;li data-end=&quot;952&quot; data-start=&quot;922&quot;&gt;해시값을 m개의 버킷으로 나눔 (보통 2^k 개)&lt;/li&gt;
&lt;li data-end=&quot;987&quot; data-start=&quot;953&quot;&gt;각 버킷에 대해 leading zeros 개수를 기록&lt;/li&gt;
&lt;li data-end=&quot;1008&quot; data-start=&quot;988&quot;&gt;전체 평균을 통해 추정치 계산:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;628&quot; data-origin-height=&quot;140&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wtYWp/btsN7wCnmRG/5v1rJxEHBTKg2Gf1OY6Xt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wtYWp/btsN7wCnmRG/5v1rJxEHBTKg2Gf1OY6Xt0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wtYWp/btsN7wCnmRG/5v1rJxEHBTKg2Gf1OY6Xt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwtYWp%2FbtsN7wCnmRG%2F5v1rJxEHBTKg2Gf1OY6Xt0%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;628&quot; height=&quot;140&quot; data-origin-width=&quot;628&quot; data-origin-height=&quot;140&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;1062&quot; data-start=&quot;1058&quot; data-ke-size=&quot;size16&quot;&gt;여기서:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1128&quot; data-start=&quot;1063&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1101&quot; data-start=&quot;1063&quot;&gt;R[i]: i번 버킷에 기록된 max leading zeros&lt;/li&gt;
&lt;li data-end=&quot;1128&quot; data-start=&quot;1102&quot;&gt;&amp;alpha;_m: 보정 상수 (m값에 따라 다름)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;1154&quot; data-start=&quot;1135&quot; data-ke-size=&quot;size23&quot;&gt;  예를 들어 Trino에서&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1747802318718&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT approx_distinct(user_id) FROM logs;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1277&quot; data-start=&quot;1211&quot; data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 내부적으로는 각 user_id를 해시하고, 그 해시값으로 HLL 스케치를 만들어서 최종 카디널리티를 추정합니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1295&quot; data-start=&quot;1284&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;1295&quot; data-start=&quot;1284&quot; data-ke-size=&quot;size23&quot;&gt;✅ 사용되는 곳&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1450&quot; data-start=&quot;1297&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1324&quot; data-start=&quot;1297&quot;&gt;Trino (approx_distinct)&lt;/li&gt;
&lt;li data-end=&quot;1361&quot; data-start=&quot;1325&quot;&gt;BigQuery (APPROX_COUNT_DISTINCT)&lt;/li&gt;
&lt;li data-end=&quot;1380&quot; data-start=&quot;1362&quot;&gt;Redis (HLL 자료구조)&lt;/li&gt;
&lt;li data-end=&quot;1407&quot; data-start=&quot;1381&quot;&gt;Elasticsearch (카디널리티 집계)&lt;/li&gt;
&lt;li data-end=&quot;1450&quot; data-start=&quot;1408&quot;&gt;Flink, Druid, ClickHouse 등 모든 대용량 분석 플랫폼&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1658&quot; data-origin-height=&quot;622&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d5FmDt/btsN5ejduOx/9MJO5e3iJzaJljffApkWaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d5FmDt/btsN5ejduOx/9MJO5e3iJzaJljffApkWaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d5FmDt/btsN5ejduOx/9MJO5e3iJzaJljffApkWaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd5FmDt%2FbtsN5ejduOx%2F9MJO5e3iJzaJljffApkWaK%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;1658&quot; height=&quot;622&quot; data-origin-width=&quot;1658&quot; data-origin-height=&quot;622&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div data-message-model-slug=&quot;gpt-4o&quot; data-message-id=&quot;e9eedeb2-4e03-4fed-958e-8e210c30cc4a&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-end=&quot;52&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;52&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;위 시뮬레이션은 &lt;b&gt;HyperLogLog(HLL)&lt;/b&gt; 알고리즘이 어떻게 동작하는지 보여줍니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;247&quot; data-start=&quot;54&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;111&quot; data-start=&quot;54&quot;&gt;실제로는 user_0부터 user_9999까지 &lt;b&gt;10,000개의 고유 값&lt;/b&gt;을 넣었습니다.&lt;/li&gt;
&lt;li data-end=&quot;180&quot; data-start=&quot;112&quot;&gt;해시값을 바탕으로 &lt;b&gt;64개의 버킷&lt;/b&gt;으로 나누고, 각 버킷마다 &lt;b&gt;해시값의 앞쪽 연속된 0의 개수&lt;/b&gt;를 기록했습니다.&lt;/li&gt;
&lt;li data-end=&quot;247&quot; data-start=&quot;181&quot;&gt;최종적으로 HLL이 추정한 고유 개수는 약 &lt;b&gt;14,025&lt;/b&gt;개로, &lt;b&gt;약간 과대 추정&lt;/b&gt;된 것을 볼 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;310&quot; data-start=&quot;249&quot; data-ke-size=&quot;size16&quot;&gt;이는 HyperLogLog의 특성상 약 &amp;plusmn;2~5%의 오차가 있으며, 데이터 수가 많을수록 정확도가 향상됩니다.&lt;/p&gt;
&lt;p data-end=&quot;403&quot; data-start=&quot;312&quot; data-ke-size=&quot;size16&quot;&gt;그래프는 각 버킷이 저장한 &quot;가장 긴 leading zeros&quot; 값을 나타낸 것으로, 분산된 해시값들이 어떻게 카디널리티 추정에 기여하는지를 시각적으로 보여줍니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;177&quot; data-start=&quot;143&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-end=&quot;177&quot; data-start=&quot;143&quot; data-ke-size=&quot;size26&quot;&gt;✅ Trino의 대표적인 Approximate 함수 목록&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;함수설명예시
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;799&quot; data-start=&quot;179&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;799&quot; data-start=&quot;219&quot;&gt;
&lt;tr data-end=&quot;311&quot; data-start=&quot;219&quot;&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;248&quot; data-start=&quot;219&quot;&gt;approx_distinct(x [, e])&lt;/td&gt;
&lt;td data-end=&quot;281&quot; data-start=&quot;248&quot; data-col-size=&quot;sm&quot;&gt;고유 개수 추정 (COUNT(DISTINCT x))&lt;/td&gt;
&lt;td data-end=&quot;311&quot; data-start=&quot;281&quot; data-col-size=&quot;md&quot;&gt;approx_distinct(user_id)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;422&quot; data-start=&quot;312&quot;&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;362&quot; data-start=&quot;312&quot;&gt;approx_percentile(x, percentage [, accuracy])&lt;/td&gt;
&lt;td data-end=&quot;383&quot; data-start=&quot;362&quot; data-col-size=&quot;sm&quot;&gt;퍼센타일 추정 (e.g. 95%)&lt;/td&gt;
&lt;td data-end=&quot;422&quot; data-start=&quot;383&quot; data-col-size=&quot;md&quot;&gt;approx_percentile(duration, 0.95)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;538&quot; data-start=&quot;423&quot;&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;467&quot; data-start=&quot;423&quot;&gt;approx_percentile(x, percentages ARRAY)&lt;/td&gt;
&lt;td data-end=&quot;482&quot; data-start=&quot;467&quot; data-col-size=&quot;sm&quot;&gt;여러 퍼센타일 한 번에&lt;/td&gt;
&lt;td data-end=&quot;538&quot; data-start=&quot;482&quot; data-col-size=&quot;md&quot;&gt;approx_percentile(duration, ARRAY[0.5, 0.9, 0.99])&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;619&quot; data-start=&quot;539&quot;&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;557&quot; data-start=&quot;539&quot;&gt;approx_set(x)&lt;/td&gt;
&lt;td data-end=&quot;594&quot; data-start=&quot;557&quot; data-col-size=&quot;sm&quot;&gt;HLL 구조 리턴 (post-aggregation 처리 가능)&lt;/td&gt;
&lt;td data-end=&quot;619&quot; data-start=&quot;594&quot; data-col-size=&quot;md&quot;&gt;approx_set(user_id)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;716&quot; data-start=&quot;620&quot;&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;648&quot; data-start=&quot;620&quot;&gt;cardinality(approx_set)&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;678&quot; data-start=&quot;648&quot;&gt;approx_set() 결과의 고유 개수 추정&lt;/td&gt;
&lt;td data-end=&quot;716&quot; data-start=&quot;678&quot; data-col-size=&quot;md&quot;&gt;cardinality(approx_set(user_id))&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;799&quot; data-start=&quot;717&quot;&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;739&quot; data-start=&quot;717&quot;&gt;merge(approx_set)&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;769&quot; data-start=&quot;739&quot;&gt;여러 노드에서 나온 approx_set을 병합&lt;/td&gt;
&lt;td data-end=&quot;799&quot; data-start=&quot;769&quot; data-col-size=&quot;md&quot;&gt;cardinality(merge(sets))&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;821&quot; data-start=&quot;806&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;821&quot; data-start=&quot;806&quot; data-ke-size=&quot;size23&quot;&gt;  함수별 상세 설명&lt;/h3&gt;
&lt;h4 data-end=&quot;856&quot; data-start=&quot;823&quot; data-ke-size=&quot;size20&quot;&gt;1. approx_distinct(x [, e])&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;952&quot; data-start=&quot;857&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;873&quot; data-start=&quot;857&quot;&gt;HyperLogLog 기반&lt;/li&gt;
&lt;li data-end=&quot;904&quot; data-start=&quot;874&quot;&gt;e: 상대 오차율 (default: 0.023)&lt;/li&gt;
&lt;li data-end=&quot;952&quot; data-start=&quot;905&quot;&gt;예: approx_distinct(user_id, 0.01) &amp;rarr; 약 1% 오차&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;1004&quot; data-start=&quot;959&quot; data-ke-size=&quot;size20&quot;&gt;2. approx_percentile(x, p [, accuracy])&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1062&quot; data-start=&quot;1005&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1036&quot; data-start=&quot;1005&quot;&gt;큰 데이터셋에서 &lt;b&gt;퍼센타일 추정치&lt;/b&gt; 구할 때 사용&lt;/li&gt;
&lt;li data-end=&quot;1062&quot; data-start=&quot;1037&quot;&gt;예: 평균보다 &lt;b&gt;상위 95% 사용시간&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1747802395293&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT approx_percentile(duration, 0.95) FROM sessions;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1147&quot; data-start=&quot;1130&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1147&quot; data-start=&quot;1130&quot;&gt;여러 퍼센타일 계산도 가능:&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1747802400651&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT approx_percentile(duration, ARRAY[0.5, 0.9, 0.99]) FROM sessions;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-end=&quot;1260&quot; data-start=&quot;1238&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;1260&quot; data-start=&quot;1238&quot; data-ke-size=&quot;size20&quot;&gt;3. approx_set(x)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1306&quot; data-start=&quot;1261&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1301&quot; data-start=&quot;1261&quot;&gt;user_id들을 HLL 형식으로 집계 (나중에 merge 가능)&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1747802408948&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT approx_set(user_id) FROM logs;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1396&quot; data-start=&quot;1356&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1396&quot; data-start=&quot;1356&quot;&gt;cardinality()와 함께 쓰면 추정 고유 수 구할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;1429&quot; data-start=&quot;1403&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;1429&quot; data-start=&quot;1403&quot; data-ke-size=&quot;size20&quot;&gt;4. merge(approx_set)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1462&quot; data-start=&quot;1430&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1462&quot; data-start=&quot;1430&quot;&gt;분산 환경에서 approx_set들을 합칠 때 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1747802421038&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT cardinality(merge(sets)) FROM ( SELECT approx_set(user_id) AS sets FROM logs GROUP BY region );&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;1595&quot; data-start=&quot;1585&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;1595&quot; data-start=&quot;1585&quot; data-ke-size=&quot;size23&quot;&gt;  요약 표&lt;/h3&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1864&quot; data-start=&quot;1597&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style6&quot;&gt;
&lt;tbody data-end=&quot;1864&quot; data-start=&quot;1660&quot;&gt;
&lt;tr data-end=&quot;1714&quot; data-start=&quot;1660&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1668&quot; data-start=&quot;1660&quot;&gt;고유 개수&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1690&quot; data-start=&quot;1668&quot;&gt;COUNT(DISTINCT x)&lt;/td&gt;
&lt;td data-end=&quot;1714&quot; data-start=&quot;1690&quot; data-col-size=&quot;sm&quot;&gt;approx_distinct(x)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1772&quot; data-start=&quot;1715&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1722&quot; data-start=&quot;1715&quot;&gt;퍼센타일&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1743&quot; data-start=&quot;1722&quot;&gt;percentile(x, p)&lt;/td&gt;
&lt;td data-end=&quot;1772&quot; data-start=&quot;1743&quot; data-col-size=&quot;sm&quot;&gt;approx_percentile(x, p)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1808&quot; data-start=&quot;1773&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1784&quot; data-start=&quot;1773&quot;&gt;유니크 값 집합&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1789&quot; data-start=&quot;1784&quot;&gt;없음&lt;/td&gt;
&lt;td data-end=&quot;1808&quot; data-start=&quot;1789&quot; data-col-size=&quot;sm&quot;&gt;approx_set(x)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1864&quot; data-start=&quot;1809&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1818&quot; data-start=&quot;1809&quot;&gt;집합 합치기&lt;/td&gt;
&lt;td data-end=&quot;1823&quot; data-start=&quot;1818&quot; data-col-size=&quot;sm&quot;&gt;없음&lt;/td&gt;
&lt;td data-end=&quot;1864&quot; data-start=&quot;1823&quot; data-col-size=&quot;sm&quot;&gt;merge(approx_set) + cardinality()&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;</description>
      <category>Tools/ETC</category>
      <author>칼쵸쵸</author>
      <guid isPermaLink="true">https://chalchichi.tistory.com/131</guid>
      <comments>https://chalchichi.tistory.com/131#entry131comment</comments>
      <pubDate>Wed, 21 May 2025 13:40:57 +0900</pubDate>
    </item>
    <item>
      <title>PyTorch, Hugging Face Trainer를 활용한 분산 환경 학습</title>
      <link>https://chalchichi.tistory.com/130</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;606&quot; data-origin-height=&quot;350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xzjTV/btsMJlWu8A1/N7KkXuUsegeBMoTTwoyy71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xzjTV/btsMJlWu8A1/N7KkXuUsegeBMoTTwoyy71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xzjTV/btsMJlWu8A1/N7KkXuUsegeBMoTTwoyy71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxzjTV%2FbtsMJlWu8A1%2FN7KkXuUsegeBMoTTwoyy71%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;606&quot; height=&quot;350&quot; data-origin-width=&quot;606&quot; data-origin-height=&quot;350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-end=&quot;88&quot; data-start=&quot;74&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-end=&quot;88&quot; data-start=&quot;74&quot; data-ke-size=&quot;size26&quot;&gt;LLM 모델 분산 학습의 구성요소&lt;/h2&gt;
&lt;h3 data-end=&quot;88&quot; data-start=&quot;74&quot; data-ke-size=&quot;size23&quot;&gt;1. PyTorch&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;357&quot; data-start=&quot;89&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;182&quot; data-start=&quot;89&quot;&gt;&lt;b&gt;개요:&lt;/b&gt;&lt;br /&gt;PyTorch는 Facebook AI Research(FAIR)에서 개발한 오픈 소스 딥러닝 프레임워크로, 연구와 산업계에서 널리 사용됩니다.&lt;/li&gt;
&lt;li data-end=&quot;357&quot; data-start=&quot;183&quot;&gt;&lt;b&gt;특징:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;357&quot; data-start=&quot;197&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;241&quot; data-start=&quot;197&quot;&gt;&lt;b&gt;동적 계산 그래프:&lt;/b&gt; 모델을 개발하고 디버깅할 때 유연성이 뛰어납니다.&lt;/li&gt;
&lt;li data-end=&quot;287&quot; data-start=&quot;244&quot;&gt;&lt;b&gt;GPU 가속:&lt;/b&gt; 손쉽게 GPU를 활용하여 연산을 가속할 수 있습니다.&lt;/li&gt;
&lt;li data-end=&quot;357&quot; data-start=&quot;290&quot;&gt;&lt;b&gt;커뮤니티와 생태계:&lt;/b&gt; 다양한 라이브러리와 도구들이 활발히 개발되고 있으며, 풍부한 문서와 튜토리얼이 제공됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;362&quot; data-start=&quot;359&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;391&quot; data-start=&quot;364&quot; data-ke-size=&quot;size23&quot;&gt;2. Hugging Face Trainer&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;692&quot; data-start=&quot;392&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;482&quot; data-start=&quot;392&quot;&gt;&lt;b&gt;개요:&lt;/b&gt;&lt;br /&gt;Hugging Face의 Transformers 라이브러리에서 제공하는 고수준 학습 인터페이스로, 복잡한 학습 루프를 단순화시켜 줍니다.&lt;/li&gt;
&lt;li data-end=&quot;692&quot; data-start=&quot;483&quot;&gt;&lt;b&gt;특징:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;692&quot; data-start=&quot;497&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;555&quot; data-start=&quot;497&quot;&gt;&lt;b&gt;자동화:&lt;/b&gt; 학습 루프, 평가, 로깅, 체크포인트 저장 등 반복되는 작업들을 자동으로 처리합니다.&lt;/li&gt;
&lt;li data-end=&quot;632&quot; data-start=&quot;558&quot;&gt;&lt;b&gt;사용 편의성:&lt;/b&gt; 복잡한 딥러닝 모델도 몇 줄의 코드로 학습시킬 수 있어, 연구자나 개발자가 모델 실험에 집중할 수 있습니다.&lt;/li&gt;
&lt;li data-end=&quot;692&quot; data-start=&quot;635&quot;&gt;&lt;b&gt;분산 학습 지원:&lt;/b&gt; PyTorch의 분산 학습 기능과 연동되어 대규모 모델 학습도 지원합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;697&quot; data-start=&quot;694&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;723&quot; data-start=&quot;699&quot; data-ke-size=&quot;size23&quot;&gt;3. rdzv (Rendezvous)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1215&quot; data-start=&quot;724&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;823&quot; data-start=&quot;724&quot;&gt;&lt;b&gt;개요:&lt;/b&gt;&lt;br /&gt;rdzv는 &amp;ldquo;rendezvous&amp;rdquo;의 약자로, 분산 학습 환경에서 여러 프로세스나 노드가 서로를 인식하고 동기화하는 초기 단계에서 사용되는 메커니즘입니다.&lt;/li&gt;
&lt;li data-end=&quot;999&quot; data-start=&quot;824&quot;&gt;&lt;b&gt;역할:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;999&quot; data-start=&quot;838&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;908&quot; data-start=&quot;838&quot;&gt;&lt;b&gt;프로세스 동기화:&lt;/b&gt; 분산 학습을 시작할 때, 각 학습 프로세스가 서로 연결되어 통신할 수 있도록 초기 설정을 합니다.&lt;/li&gt;
&lt;li data-end=&quot;999&quot; data-start=&quot;911&quot;&gt;&lt;b&gt;노드 연결:&lt;/b&gt; rdzv를 통해 모든 참여 프로세스가 공통의 &amp;ldquo;만남의 장소&amp;rdquo;(endpoint)를 사용하여 서로를 찾고, 이후에 작업을 분배받게 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1215&quot; data-start=&quot;1000&quot;&gt;&lt;b&gt;Hugging Face Trainer와의 관계:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1215&quot; data-start=&quot;1037&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1162&quot; data-start=&quot;1037&quot;&gt;Trainer는 내부적으로 PyTorch의 분산 학습 기능을 사용하며, 이때 rdzv 설정(예: rdzv_endpoint, rdzv_backend 등)을 활용하여 다수의 프로세스가 원활히 협력할 수 있도록 합니다.&lt;/li&gt;
&lt;li data-end=&quot;1215&quot; data-start=&quot;1165&quot;&gt;이를 통해 대규모 모델을 여러 GPU나 노드에 분산하여 효율적으로 학습할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1220&quot; data-start=&quot;1217&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1228&quot; data-start=&quot;1222&quot; data-ke-size=&quot;size23&quot;&gt;요약&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1485&quot; data-start=&quot;1229&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1290&quot; data-start=&quot;1229&quot;&gt;&lt;b&gt;PyTorch:&lt;/b&gt; 강력하고 유연한 딥러닝 프레임워크로, 동적 계산 그래프와 GPU 가속을 지원합니다.&lt;/li&gt;
&lt;li data-end=&quot;1382&quot; data-start=&quot;1291&quot;&gt;&lt;b&gt;Hugging Face Trainer:&lt;/b&gt; PyTorch 기반의 모델 학습을 단순화하는 고수준 API로, 자동화된 학습 루프와 분산 학습 기능을 제공합니다.&lt;/li&gt;
&lt;li data-end=&quot;1485&quot; data-start=&quot;1383&quot;&gt;&lt;b&gt;rdzv (Rendezvous):&lt;/b&gt; 분산 학습 환경에서 여러 프로세스가 초기 동기화 및 연결을 할 수 있도록 하는 메커니즘으로, 대규모 모델 학습 시 필수적인 역할을 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드 예시&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;train.py&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1741758558885&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import os
import torch
from transformers import Trainer, TrainingArguments, BertForSequenceClassification, BertTokenizerFast
from datasets import load_dataset

def main():
    # 데이터셋 불러오기 (예시로 GLUE의 MRPC 사용)
    dataset = load_dataset(&quot;glue&quot;, &quot;mrpc&quot;)
    tokenizer = BertTokenizerFast.from_pretrained(&quot;bert-base-uncased&quot;)
    
    def tokenize_function(examples):
        return tokenizer(examples[&quot;sentence1&quot;], examples[&quot;sentence2&quot;], truncation=True)
    
    tokenized_datasets = dataset.map(tokenize_function, batched=True)
    # 불필요한 컬럼 제거 및 텐서 포맷 지정
    tokenized_datasets = tokenized_datasets.remove_columns([&quot;sentence1&quot;, &quot;sentence2&quot;, &quot;idx&quot;])
    tokenized_datasets.set_format(&quot;torch&quot;)

    # 모델 초기화
    model = BertForSequenceClassification.from_pretrained(&quot;bert-base-uncased&quot;, num_labels=2)

    # TrainingArguments: torchrun 환경변수(예: LOCAL_RANK, RANK, WORLD_SIZE)를 활용해 분산 학습이 자동 인식됩니다.
    training_args = TrainingArguments(
        output_dir=&quot;./results&quot;,
        num_train_epochs=3,
        per_device_train_batch_size=8,
        per_device_eval_batch_size=8,
        evaluation_strategy=&quot;epoch&quot;,
        save_strategy=&quot;epoch&quot;,
        logging_dir=&quot;./logs&quot;,
        logging_steps=10,
    )

    trainer = Trainer(
        model=model,
        args=training_args,
        train_dataset=tokenized_datasets[&quot;train&quot;],
        eval_dataset=tokenized_datasets[&quot;validation&quot;],
    )

    trainer.train()

if __name__ == &quot;__main__&quot;:
    # torchrun으로 실행하면 환경변수에 따라 분산 학습 설정이 전달됩니다.
    # 이미 초기화되지 않은 경우, 아래와 같이 명시적으로 프로세스 그룹을 초기화할 수 있습니다.
    if &quot;RANK&quot; in os.environ and &quot;WORLD_SIZE&quot; in os.environ:
        backend = &quot;nccl&quot; if torch.cuda.is_available() else &quot;gloo&quot;
        torch.distributed.init_process_group(backend=backend)
    main()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;1944&quot; data-start=&quot;1922&quot; data-ke-size=&quot;size26&quot;&gt;실행 방법 (3개 노드 분산 학습)&lt;/h2&gt;
&lt;p data-end=&quot;2048&quot; data-start=&quot;1946&quot; data-ke-size=&quot;size16&quot;&gt;각 노드에서는 아래와 같이 torchrun 명령어를 사용하여 실행합니다. 예를 들어, 마스터 노드의 IP가 192.168.1.1이고 포트 29500을 사용한다고 가정합니다.&lt;/p&gt;
&lt;p data-end=&quot;2048&quot; data-start=&quot;1946&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2048&quot; data-start=&quot;1946&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;노드 0 (node_rank=0):&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1741758610894&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;torchrun --nproc_per_node=1 --nnodes=3 --node_rank=0 --rdzv_backend=c10d --rdzv_endpoint=192.168.1.1:29500 train.py&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;2048&quot; data-start=&quot;1946&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2048&quot; data-start=&quot;1946&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;노드 1 (node_rank=1):&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1741758629263&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;torchrun --nproc_per_node=1 --nnodes=3 --node_rank=1 --rdzv_backend=c10d --rdzv_endpoint=192.168.1.1:29500 train.py&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;2048&quot; data-start=&quot;1946&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2048&quot; data-start=&quot;1946&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;노드 2 (node_rank=2):&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1741758647455&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;torchrun --nproc_per_node=1 --nnodes=3 --node_rank=2 --rdzv_backend=c10d --rdzv_endpoint=192.168.1.1:29500 train.py&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 노드에서 --nproc_per_node 옵션은 해당 노드에서 사용할 GPU(혹은 프로세스) 수를 지정합니다. 이 예제에서는 각 노드당 1개의 프로세스를 사용합니다.&lt;/p&gt;
&lt;hr data-end=&quot;2633&quot; data-start=&quot;2630&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2655&quot; data-start=&quot;2635&quot; data-ke-size=&quot;size26&quot;&gt;내부 통신 및 리소스 할당 과정&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;3623&quot; data-start=&quot;2657&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;3042&quot; data-start=&quot;2657&quot;&gt;&lt;b&gt;Rendezvous 단계 (rdzv):&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3042&quot; data-start=&quot;2691&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2802&quot; data-start=&quot;2691&quot;&gt;&lt;b&gt;초기 등록:&lt;/b&gt;&lt;br /&gt;각 노드는 torchrun 명령어를 통해 실행되며, --rdzv_endpoint로 지정된 마스터(또는 공용) IP와 포트에 접속하여 자신의 존재를 알립니다.&lt;/li&gt;
&lt;li data-end=&quot;2916&quot; data-start=&quot;2806&quot;&gt;&lt;b&gt;환경 변수 설정:&lt;/b&gt;&lt;br /&gt;torchrun은 각 노드에 RANK, WORLD_SIZE, LOCAL_RANK 등의 환경 변수를 설정하여 전체 분산 환경 정보를 전달합니다.&lt;/li&gt;
&lt;li data-end=&quot;3042&quot; data-start=&quot;2920&quot;&gt;&lt;b&gt;프로세스 그룹 초기화:&lt;/b&gt;&lt;br /&gt;코드 내에서 torch.distributed.init_process_group를 호출하여, 각 노드가 rdzv를 통해 서로를 확인하고 동일한 프로세스 그룹에 가입합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;3317&quot; data-start=&quot;3044&quot;&gt;&lt;b&gt;통신 방식:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3317&quot; data-start=&quot;3063&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3199&quot; data-start=&quot;3063&quot;&gt;&lt;b&gt;백엔드 선택:&lt;/b&gt;&lt;br /&gt;GPU가 사용 가능하면 nccl, 그렇지 않으면 gloo 백엔드를 사용해 통신합니다. 이 백엔드는 TCP/IP를 기반으로 각 프로세스 간의 데이터(예: gradient) 교환 및 동기화를 담당합니다.&lt;/li&gt;
&lt;li data-end=&quot;3317&quot; data-start=&quot;3203&quot;&gt;&lt;b&gt;All-Reduce 연산:&lt;/b&gt;&lt;br /&gt;학습 과정에서 각 프로세스가 계산한 gradient는 All-Reduce 방식으로 집계되어, 모든 프로세스가 동일한 모델 파라미터 업데이트를 받게 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;3623&quot; data-start=&quot;3319&quot;&gt;&lt;b&gt;리소스 할당:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3623&quot; data-start=&quot;3339&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3486&quot; data-start=&quot;3339&quot;&gt;&lt;b&gt;노드별 할당:&lt;/b&gt;&lt;br /&gt;각 노드는 실행 시 LOCAL_RANK에 따라 특정 GPU에 할당됩니다. Hugging Face Trainer 및 PyTorch는 이를 자동으로 인식하여, 각 프로세스가 자신에게 할당된 GPU에서 연산을 수행하도록 합니다.&lt;/li&gt;
&lt;li data-end=&quot;3623&quot; data-start=&quot;3490&quot;&gt;&lt;b&gt;동기화 및 학습:&lt;/b&gt;&lt;br /&gt;모든 노드가 초기 rdzv 과정을 마치면, 각 노드는 동기화된 상태에서 학습 루프를 시작합니다. 모델의 파라미터 업데이트와 gradient 계산은 분산 환경에서 통신 및 동기화를 통해 이루어집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;3628&quot; data-start=&quot;3625&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3635&quot; data-start=&quot;3630&quot; data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3967&quot; data-start=&quot;3637&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3757&quot; data-start=&quot;3637&quot;&gt;&lt;b&gt;rdzv (Rendezvous):&lt;/b&gt;&lt;br /&gt;각 노드가 중앙의 rendezvous 엔드포인트를 통해 서로를 인식하고, 환경 변수(RANK, WORLD_SIZE 등)를 기반으로 분산 프로세스 그룹을 형성합니다.&lt;/li&gt;
&lt;li data-end=&quot;3855&quot; data-start=&quot;3759&quot;&gt;&lt;b&gt;통신:&lt;/b&gt;&lt;br /&gt;선택된 백엔드(nccl/gloo)를 통해 각 노드 간에 gradient와 모델 업데이트 정보를 All-Reduce 등의 집계 연산으로 동기화합니다.&lt;/li&gt;
&lt;li data-end=&quot;3967&quot; data-start=&quot;3857&quot;&gt;&lt;b&gt;리소스 할당 및 학습 진행:&lt;/b&gt;&lt;br /&gt;각 노드는 자신에게 할당된 GPU에서 학습을 진행하며, 모든 노드가 동기화되어 동일한 모델 파라미터를 업데이트하면서 분산 학습이 효율적으로 수행됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;4058&quot; data-start=&quot;3969&quot; data-ke-size=&quot;size16&quot;&gt;이와 같이 Hugging Face Trainer는 torchrun과 rdzv 메커니즘을 활용해 여러 노드에서 분산 학습을 원활하게 수행할 수 있도록 도와줍니다.&lt;/p&gt;</description>
      <category>AI/LLM</category>
      <author>칼쵸쵸</author>
      <guid isPermaLink="true">https://chalchichi.tistory.com/130</guid>
      <comments>https://chalchichi.tistory.com/130#entry130comment</comments>
      <pubDate>Wed, 12 Mar 2025 15:05:16 +0900</pubDate>
    </item>
    <item>
      <title>Docker 이미지, 캐시, 데몬,  빌드 프로세스</title>
      <link>https://chalchichi.tistory.com/129</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;397&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGkrWY/btsMHRVfJIU/UAaLAkk5f7vTuY2FdEmfL0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGkrWY/btsMHRVfJIU/UAaLAkk5f7vTuY2FdEmfL0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGkrWY/btsMHRVfJIU/UAaLAkk5f7vTuY2FdEmfL0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGkrWY%2FbtsMHRVfJIU%2FUAaLAkk5f7vTuY2FdEmfL0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1269&quot; height=&quot;397&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;397&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-end=&quot;42&quot; data-start=&quot;0&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;(1) Docker 이미지란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;206&quot; data-start=&quot;70&quot; data-ke-size=&quot;size16&quot;&gt;Docker 이미지는 컨테이너를 실행하는 데 필요한 모든 것을 포함한 &lt;b&gt;불변(immutable)한 패키지&lt;/b&gt;입니다.&lt;br /&gt;이는 &lt;b&gt;레이어(layer) 기반 파일 시스템&lt;/b&gt;으로 구성되어 있으며, 각 레이어는 아래와 같은 명령어에 의해 생성됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;369&quot; data-start=&quot;208&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;249&quot; data-start=&quot;208&quot;&gt;FROM &amp;rarr; 베이스 이미지 정의 (예: ubuntu:20.04)&lt;/li&gt;
&lt;li data-end=&quot;309&quot; data-start=&quot;250&quot;&gt;RUN &amp;rarr; 명령어 실행 후 파일 시스템 변경 (예: apt-get install -y curl)&lt;/li&gt;
&lt;li data-end=&quot;334&quot; data-start=&quot;310&quot;&gt;COPY / ADD &amp;rarr; 파일 복사&lt;/li&gt;
&lt;li data-end=&quot;369&quot; data-start=&quot;335&quot;&gt;CMD / ENTRYPOINT &amp;rarr; 실행 명령어 지정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;442&quot; data-start=&quot;371&quot; data-ke-size=&quot;size16&quot;&gt;각 명령어(RUN, COPY 등)는 &lt;b&gt;새로운 레이어를 생성&lt;/b&gt;하며, 이러한 레이어는 Docker가 저장하고 관리합니다.&lt;/p&gt;
&lt;hr data-end=&quot;447&quot; data-start=&quot;444&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;486&quot; data-start=&quot;449&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;(2) Docker 데몬(Docker Daemon)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;552&quot; data-start=&quot;487&quot; data-ke-size=&quot;size16&quot;&gt;Docker 데몬(dockerd)은 컨테이너를 관리하는 &lt;b&gt;백그라운드 프로세스&lt;/b&gt;로, 다음과 같은 역할을 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;666&quot; data-start=&quot;554&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;598&quot; data-start=&quot;554&quot;&gt;Docker &lt;b&gt;이미지 저장&lt;/b&gt; 및 관리 (docker image ls)&lt;/li&gt;
&lt;li data-end=&quot;623&quot; data-start=&quot;599&quot;&gt;컨테이너 실행 (docker run)&lt;/li&gt;
&lt;li data-end=&quot;638&quot; data-start=&quot;624&quot;&gt;네트워크 및 볼륨 관리&lt;/li&gt;
&lt;li data-end=&quot;666&quot; data-start=&quot;639&quot;&gt;Docker API를 통해 CLI 명령어 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;760&quot; data-start=&quot;668&quot; data-ke-size=&quot;size16&quot;&gt;Docker CLI (docker)는 명령을 실행하면 &lt;b&gt;Docker 데몬&lt;/b&gt;에게 요청을 보내고, 데몬이 이를 처리하여 컨테이너를 실행하거나 이미지를 빌드합니다.&lt;/p&gt;
&lt;hr data-end=&quot;765&quot; data-start=&quot;762&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;794&quot; data-start=&quot;767&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;(3) Docker 빌드 캐시란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;893&quot; data-start=&quot;795&quot; data-ke-size=&quot;size16&quot;&gt;Docker는 &lt;b&gt;레이어(layer) 캐싱&lt;/b&gt;을 활용하여 빌드를 최적화합니다.&lt;br /&gt;즉, 이전 빌드에서 변경되지 않은 레이어는 **재사용(캐싱)**하여 빌드 속도를 향상시킵니다.&lt;/p&gt;
&lt;p data-end=&quot;926&quot; data-start=&quot;895&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Docker 캐시는 다음과 같은 규칙을 따릅니다.&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1048&quot; data-start=&quot;927&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;955&quot; data-start=&quot;927&quot;&gt;FROM 명령어가 같은 경우 캐시를 재사용&lt;/li&gt;
&lt;li data-end=&quot;1014&quot; data-start=&quot;956&quot;&gt;RUN, COPY, ADD 명령어가 동일하고, 입력 파일이 변경되지 않았다면 캐시 재사용&lt;/li&gt;
&lt;li data-end=&quot;1048&quot; data-start=&quot;1015&quot;&gt;변경된 명령어 이후의 모든 레이어는 &lt;b&gt;다시 실행됨&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;1058&quot; data-start=&quot;1050&quot; data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;예제&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741616150989&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 베이스 이미지
FROM ubuntu:20.04 

# 패키지 업데이트 및 설치 (RUN 명령어 실행)
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y curl

# 실행 파일 복사
COPY app /usr/local/bin/app&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1233&quot; data-start=&quot;1222&quot; 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-end=&quot;1419&quot; data-start=&quot;1234&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1267&quot; data-start=&quot;1234&quot;&gt;FROM ubuntu:20.04 &amp;rarr; 캐시 사용 가능&lt;/li&gt;
&lt;li data-end=&quot;1337&quot; data-start=&quot;1268&quot;&gt;RUN apt-get update &amp;amp;&amp;amp; apt-get install -y curl &amp;rarr; 변경 없음 &amp;rarr; 캐시 사용 가능&lt;/li&gt;
&lt;li data-end=&quot;1419&quot; data-start=&quot;1338&quot;&gt;COPY app /usr/local/bin/app &amp;rarr; app 파일이 변경되면 캐시 무효화 ❌&lt;br /&gt;(이후 모든 레이어 다시 빌드)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;1484&quot; data-start=&quot;1421&quot; data-ke-size=&quot;size16&quot;&gt;➡ &lt;b&gt;해결책&lt;/b&gt;&lt;br /&gt;&lt;b&gt;자주 변경되는 COPY 명령어를 나중에 배치하여 캐시를 최대한 활용&lt;/b&gt;하면 좋습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741616165981&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM ubuntu:20.04
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y curl
COPY app /usr/local/bin/app&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1660&quot; data-start=&quot;1595&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 하면 app만 변경되었을 때, &lt;b&gt;패키지 설치(RUN)&lt;/b&gt; 단계는 캐시를 유지하여 빌드 속도가 빨라집니다.&lt;/p&gt;
&lt;hr data-end=&quot;1665&quot; data-start=&quot;1662&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1694&quot; data-start=&quot;1667&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;b&gt;(4) &lt;/b&gt;고정된 태그와 Digest란?&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-end=&quot;1726&quot; data-start=&quot;1695&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 고정된 태그 (Fixed Tag)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1830&quot; data-start=&quot;1727&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FROM ubuntu:latest&lt;/b&gt; 같은 **태그(Tag)**는 변할 수 있습니다.&lt;br /&gt;즉, &lt;b&gt;ubuntu:latest&lt;/b&gt;는 오늘은 20.04지만 내일은 22.04일 수도 있음.&lt;/p&gt;
&lt;p data-end=&quot;1861&quot; data-start=&quot;1832&quot; data-ke-size=&quot;size16&quot;&gt;  그래서 &lt;b&gt;버전을 명확히 지정하는 것이 좋음&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741616192420&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM ubuntu:20.04 # 고정된 태그 사용&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1947&quot; data-start=&quot;1911&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1947&quot; data-start=&quot;1911&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 하면 빌드 시 항상 같은 20.04 버전이 사용됩니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1970&quot; data-start=&quot;1949&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) Digest란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;2015&quot; data-start=&quot;1971&quot; data-ke-size=&quot;size16&quot;&gt;Digest는 이미지의 변경을 방지하는 &lt;b&gt;고유한 SHA256 해시값&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-end=&quot;2025&quot; data-start=&quot;2017&quot; data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;예제&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741616234444&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM ubuntu@sha256:e5c01b00c3e3e87db...&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2129&quot; data-start=&quot;2084&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 하면 &lt;b&gt;어떤 태그든 변경이 발생해도, 정확한 동일한 이미지가 사용됨&lt;/b&gt;.&lt;/p&gt;
&lt;p data-end=&quot;2147&quot; data-start=&quot;2131&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1741616246132&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker pull ubuntu:20.04
docker inspect ubuntu:20.04 | grep -i sha256&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2250&quot; data-start=&quot;2228&quot; data-ke-size=&quot;size16&quot;&gt;➡ 고유한 SHA256 해시값이 표시됨.&lt;/p&gt;
&lt;hr data-end=&quot;2255&quot; data-start=&quot;2252&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2298&quot; data-start=&quot;2257&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;(5)&amp;nbsp; 멀티스테이지 빌드(Multi-stage Build)란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;2385&quot; data-start=&quot;2299&quot; data-ke-size=&quot;size16&quot;&gt;Docker에서 빌드 과정에서 필요하지만, &lt;b&gt;최종 컨테이너에는 불필요한 파일이나 도구를 포함하지 않도록&lt;/b&gt; 여러 개의 FROM을 사용하는 기법입니다.&lt;/p&gt;
&lt;h3 data-end=&quot;2413&quot; data-start=&quot;2387&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 스테이지(Stage)란?&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2503&quot; data-start=&quot;2414&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2457&quot; data-start=&quot;2414&quot;&gt;FROM이 실행될 때마다 **새로운 스테이지(Stage)**가 생성됨.&lt;/li&gt;
&lt;li data-end=&quot;2503&quot; data-start=&quot;2458&quot;&gt;이전 스테이지의 결과물을 &lt;b&gt;최종 이미지에 필요한 부분만 복사&lt;/b&gt;할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2527&quot; data-start=&quot;2505&quot; data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;예제: Go 애플리케이션 빌드&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1741616264022&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 빌드 스테이지 (컴파일러 포함)
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

# 실행 스테이지 (최소한의 런타임 환경)
FROM ubuntu:20.04
COPY --from=builder /app/myapp /usr/local/bin/myapp
CMD [&quot;myapp&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;2774&quot; data-start=&quot;2748&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 멀티스테이지 빌드의 장점&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;2866&quot; data-start=&quot;2775&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;2809&quot; data-start=&quot;2775&quot;&gt;&lt;b&gt;최종 이미지가 작아짐&lt;/b&gt; &amp;rarr; 빌드 도구 포함되지 않음&lt;/li&gt;
&lt;li data-end=&quot;2835&quot; data-start=&quot;2810&quot;&gt;&lt;b&gt;보안 강화&lt;/b&gt; &amp;rarr; 불필요한 파일 제거&lt;/li&gt;
&lt;li data-end=&quot;2866&quot; data-start=&quot;2836&quot;&gt;&lt;b&gt;캐시 최적화&lt;/b&gt; &amp;rarr; 불필요한 중간 레이어 제거&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;2871&quot; data-start=&quot;2868&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2910&quot; data-start=&quot;2873&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;b&gt;(6) &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;도커 캐시, 고정 태그, 멀티스테이지 빌드 정리&lt;/b&gt;&lt;/h2&gt;
&lt;p 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-end=&quot;3254&quot; data-start=&quot;2911&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;3254&quot; data-start=&quot;2939&quot;&gt;
&lt;tr data-end=&quot;2984&quot; data-start=&quot;2939&quot;&gt;
&lt;td&gt;&lt;b&gt;Docker 이미지&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;컨테이너 실행을 위한 패키지 (레이어 기반)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3035&quot; data-start=&quot;2985&quot;&gt;
&lt;td&gt;&lt;b&gt;Docker 데몬&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;컨테이너 및 이미지 관리를 담당하는 백그라운드 프로세스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3081&quot; data-start=&quot;3036&quot;&gt;
&lt;td&gt;&lt;b&gt;Docker 캐시&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;이전 빌드된 레이어를 재사용하여 속도를 최적화&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3137&quot; data-start=&quot;3082&quot;&gt;
&lt;td&gt;&lt;b&gt;고정된 태그&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;ubuntu:20.04처럼 특정 버전을 사용하여 예측 가능성 증가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3199&quot; data-start=&quot;3138&quot;&gt;
&lt;td&gt;&lt;b&gt;Digest&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;sha256:e5c01b00...과 같이 해시를 사용하여 정확한 이미지 보장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3254&quot; data-start=&quot;3200&quot;&gt;
&lt;td&gt;&lt;b&gt;멀티스테이지 빌드&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;FROM을 여러 번 사용하여 빌드와 실행을 분리하여 최적화&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-end=&quot;3259&quot; data-start=&quot;3256&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;3272&quot; data-start=&quot;3261&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;마무리&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3482&quot; data-start=&quot;3273&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3313&quot; data-start=&quot;3273&quot;&gt;&lt;b&gt;Docker 이미지&lt;/b&gt;는 여러 개의 &lt;b&gt;불변 레이어&lt;/b&gt;로 구성됨.&lt;/li&gt;
&lt;li data-end=&quot;3371&quot; data-start=&quot;3314&quot;&gt;&lt;b&gt;Docker 캐시&lt;/b&gt;는 빌드 속도를 높이지만, 특정 단계가 변경되면 이후 모든 단계가 재빌드됨.&lt;/li&gt;
&lt;li data-end=&quot;3421&quot; data-start=&quot;3372&quot;&gt;&lt;b&gt;고정된 태그(Fixed Tag)나 Digest&lt;/b&gt;를 사용하여 빌드 안정성을 보장.&lt;/li&gt;
&lt;li data-end=&quot;3482&quot; data-start=&quot;3422&quot;&gt;&lt;b&gt;멀티스테이지 빌드&lt;/b&gt;는 빌드와 실행 환경을 분리하여 &lt;b&gt;보안, 성능, 크기 최적화&lt;/b&gt;를 가능하게 함.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Tools/Docker</category>
      <author>칼쵸쵸</author>
      <guid isPermaLink="true">https://chalchichi.tistory.com/129</guid>
      <comments>https://chalchichi.tistory.com/129#entry129comment</comments>
      <pubDate>Mon, 10 Mar 2025 23:19:55 +0900</pubDate>
    </item>
    <item>
      <title>NVIDIA의 GPU, CUDA, PyTorch, TensorRT</title>
      <link>https://chalchichi.tistory.com/128</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;351&quot; data-origin-height=&quot;259&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QfKBA/btsME7y0XKO/qhKOIgeRrGD45tyQuvg1f1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QfKBA/btsME7y0XKO/qhKOIgeRrGD45tyQuvg1f1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QfKBA/btsME7y0XKO/qhKOIgeRrGD45tyQuvg1f1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQfKBA%2FbtsME7y0XKO%2FqhKOIgeRrGD45tyQuvg1f1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;351&quot; height=&quot;259&quot; data-origin-width=&quot;351&quot; data-origin-height=&quot;259&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;172&quot; data-start=&quot;141&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;NVIDIA GPU와 CUDA의 관계&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;331&quot; data-start=&quot;174&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;CUDA(Compute Unified Device Architecture)는 NVIDIA에서 개발한 병렬 컴퓨팅 플랫폼으로, GPU의 강력한 병렬 처리 능력을 활용하여 일반적인 계산 작업을 가속화합니다.&lt;/span&gt; &lt;span&gt;이는 그래픽 처리뿐만 아니라 과학 계산, 머신 러닝 등 다양한 분야에서 활용됩니다.&lt;/span&gt; ​&lt;/p&gt;
&lt;p data-end=&quot;331&quot; data-start=&quot;174&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1025&quot; data-start=&quot;333&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1025&quot; data-start=&quot;333&quot;&gt;&lt;b&gt;GPU 아키텍처별 지원하는 CUDA 버전:&lt;/b&gt;GPU 모델아키텍처지원 가능한 CUDA 최소 버전
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1025&quot; data-start=&quot;366&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody data-end=&quot;1025&quot; data-start=&quot;447&quot;&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;GPU 모델&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;아키텍처&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;지원 가능한 CUDA 최소 버전&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;574&quot; data-start=&quot;447&quot;&gt;
&lt;td&gt;&lt;span&gt;P40&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Pascal&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;CUDA 8.0 이상&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;709&quot; data-start=&quot;577&quot;&gt;
&lt;td&gt;&lt;span&gt;T4&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Turing&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;CUDA 10.0 이상&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;844&quot; data-start=&quot;712&quot;&gt;
&lt;td&gt;&lt;span&gt;A100&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Ampere&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;CUDA 11.0 이상&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1025&quot; data-start=&quot;847&quot;&gt;
&lt;td&gt;&lt;span&gt;H100&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Hopper&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;CUDA 12.0 이상&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&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; &lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;최신 CUDA 버전은 이전 GPU 아키텍처와의 호환성을 유지하지만, 최신 GPU의 기능을 완전히 활용하려면 해당 GPU가 요구하는 최소 CUDA 버전을 사용하는 것이 중요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1120&quot; data-start=&quot;1027&quot; data-ke-size=&quot;size16&quot;&gt;​&lt;/p&gt;
&lt;p data-end=&quot;150&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;​&lt;span&gt;NVIDIA는 다양한 용도와 성능 요구 사항을 충족시키기 위해 여러 세대의 GPU를 출시해 왔습니다.&lt;/span&gt; 아래는 P40, T4, A100, H100을 포함한 주요 NVIDIA GPU의 성능과 특징을 정리한 표입니다.​&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1855&quot; data-start=&quot;152&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;span&gt;GPU 모델&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;아키텍처&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;출시일&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;CUDA 코어 수&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;메모리&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;대역폭&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp;주요 특징&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;589&quot; data-start=&quot;295&quot;&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;P40&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Pascal&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;2016년&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;3,840&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;24GB GDDR5&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;346 GB/s&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;고성능 컴퓨팅 및 딥러닝 추론에 최적화&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;897&quot; data-start=&quot;590&quot;&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;T4&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Turing&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;2018년&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;2,560&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;16GB GDDR6&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;320 GB/s&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;에너지 효율성이 높으며, AI 추론 및 그래픽 작업에 적합&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1202&quot; data-start=&quot;898&quot;&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;A100&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Ampere&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;2020년&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;6,912&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;40GB 또는 80GB HBM2e&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;1,555 GB/s&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;고성능 컴퓨팅, AI 학습 및 추론에 최적화&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1508&quot; data-start=&quot;1203&quot;&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;H100&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Hopper&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;2022년&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;8,192&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;80GB HBM3&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;2,000 GB/s&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;차세대 고성능 컴퓨팅 및 AI 워크로드에 최적화&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1855&quot; data-start=&quot;1509&quot;&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;RTX 5090&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Blackwell&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;2025년&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;21,760&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;32GB GDDR7&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;1,792 GB/s&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;최고 수준의 게임 및 그래픽 성능 제공&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;1867&quot; data-start=&quot;1857&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1867&quot; data-start=&quot;1857&quot; 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-end=&quot;2403&quot; data-start=&quot;1869&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1965&quot; data-start=&quot;1869&quot;&gt;&lt;b&gt;P40&lt;/b&gt;: &lt;span&gt;Pascal 아키텍처 기반으로, 딥러닝 추론 및 고성능 컴퓨팅 작업에 사용되었습니다.&lt;/span&gt;​&lt;/li&gt;
&lt;li data-end=&quot;2062&quot; data-start=&quot;1967&quot;&gt;&lt;b&gt;T4&lt;/b&gt;: &lt;span&gt;Turing 아키텍처를 채택하여 에너지 효율성이 높고, AI 추론 및 그래픽 작업에 널리 활용되었습니다.&lt;/span&gt;​&lt;/li&gt;
&lt;li data-end=&quot;2161&quot; data-start=&quot;2064&quot;&gt;&lt;b&gt;A100&lt;/b&gt;: &lt;span&gt;Ampere 아키텍처 기반으로, 대규모 AI 학습 및 추론, 고성능 컴퓨팅에 최적화되었습니다.&lt;/span&gt;​&lt;/li&gt;
&lt;li data-end=&quot;2260&quot; data-start=&quot;2163&quot;&gt;&lt;b&gt;H100&lt;/b&gt;: &lt;span&gt;Hopper 아키텍처를 적용하여 이전 세대보다 향상된 성능과 메모리 대역폭을 제공합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;CPU 코어와 CUDA 코어&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;​&lt;span&gt;CPU 코어와 CUDA 코어는 모두 연산 작업을 수행하는 프로세서의 기본 단위이지만, 그 설계 목적과 구조에는 차이가 있습니다.&lt;/span&gt;​&lt;/p&gt;
&lt;p data-end=&quot;101&quot; data-start=&quot;90&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;101&quot; data-start=&quot;90&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CPU 코어:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;383&quot; data-start=&quot;103&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;197&quot; data-start=&quot;103&quot;&gt;&lt;b&gt;설계 목적:&lt;/b&gt; &lt;span&gt;순차적 작업 처리와 낮은 지연 시간에 최적화되어 있습니다.&lt;/span&gt;​&lt;/li&gt;
&lt;li data-end=&quot;290&quot; data-start=&quot;199&quot;&gt;&lt;b&gt;구조:&lt;/b&gt; &lt;span&gt;상대적으로 적은 수의 코어(일반적으로 4~16개)를 가지고 있으며, 각 코어는 복잡한 제어 로직과 큰 캐시 메모리를 포함하여 다양한 작업을 빠르게 처리할 수 있습니다.&lt;/span&gt;​&lt;/li&gt;
&lt;li data-end=&quot;383&quot; data-start=&quot;292&quot;&gt;&lt;b&gt;특징:&lt;/b&gt; &lt;span&gt;높은 클럭 속도와 복잡한 연산 처리를 통해 단일 또는 소수의 스레드를 효율적으로 처리합니다.&lt;/span&gt;​&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;397&quot; data-start=&quot;385&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CUDA 코어:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;687&quot; data-start=&quot;399&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;493&quot; data-start=&quot;399&quot;&gt;&lt;b&gt;설계 목적:&lt;/b&gt; &lt;span&gt;대규모 병렬 처리를 통해 높은 처리량을 제공하도록 최적화되어 있습니다.&lt;/span&gt;​&lt;/li&gt;
&lt;li data-end=&quot;590&quot; data-start=&quot;495&quot;&gt;&lt;b&gt;구조:&lt;/b&gt; &lt;span&gt;수백에서 수천 개의 간단한 코어로 구성되어 있으며, 각 코어는 단순한 연산을 수행하도록 설계되어 대량의 데이터를 동시에 처리할 수 있습니다.&lt;/span&gt;​&lt;/li&gt;
&lt;li data-end=&quot;687&quot; data-start=&quot;592&quot;&gt;&lt;b&gt;특징:&lt;/b&gt; &lt;span&gt;낮은 클럭 속도와 단순한 제어 로직을 통해 에너지 효율성을 높이고, 대규모 병렬 연산을 효율적으로 수행합니다.&lt;/span&gt;​&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;699&quot; data-start=&quot;689&quot; 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-end=&quot;995&quot; data-start=&quot;701&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;798&quot; data-start=&quot;701&quot;&gt;&lt;b&gt;코어 수:&lt;/b&gt; &lt;span&gt;CPU는 적은 수의 복잡한 코어를, GPU는 많은 수의 단순한 코어를 가집니다.&lt;/span&gt;​&lt;/li&gt;
&lt;li data-end=&quot;898&quot; data-start=&quot;800&quot;&gt;&lt;b&gt;처리 방식:&lt;/b&gt; &lt;span&gt;CPU는 순차적 처리에, GPU는 병렬 처리에 최적화되어 있습니다.&lt;/span&gt;​&lt;/li&gt;
&lt;li data-end=&quot;995&quot; data-start=&quot;900&quot;&gt;&lt;b&gt;용도:&lt;/b&gt; &lt;span&gt;CPU는 일반적인 컴퓨팅 작업에, GPU는 그래픽 처리 및 병렬 연산이 필요한 작업에 주로 사용됩니다.&lt;/span&gt;​&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1082&quot; data-start=&quot;997&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이러한 차이로 인해 CPU와 GPU는 각기 다른 작업 부하에 대해 최적의 성능을 발휘하며, 현대 컴퓨팅 환경에서는 두 프로세서의 협업을 통해 다양한 작업을 효율적으로 처리합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-end=&quot;1155&quot; data-start=&quot;1127&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;PyTorch와 CUDA의 관계&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;1322&quot; data-start=&quot;1157&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;PyTorch는 Python 기반의 오픈 소스 머신 러닝 라이브러리로, 자연어 처리와 컴퓨터 비전과 같은 분야에서 널리 사용됩니다.&lt;/span&gt; &lt;span&gt;PyTorch는 CUDA를 지원하여 NVIDIA GPU를 활용한 고속 연산을 가능하게 합니다.&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2316&quot; data-start=&quot;1324&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2316&quot; data-start=&quot;1324&quot;&gt;&lt;b&gt;PyTorch 버전별 지원하는 CUDA 버전:&lt;/b&gt;PyTorch 버전지원하는 CUDA 버전
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;2316&quot; data-start=&quot;1359&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody data-end=&quot;2316&quot; data-start=&quot;1431&quot;&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;span&gt;PyTorch 버전&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;&lt;span&gt;지원하는 CUDA 버전&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1533&quot; data-start=&quot;1431&quot;&gt;
&lt;td&gt;&lt;span&gt;1.8&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;10.2, 11.1&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1638&quot; data-start=&quot;1536&quot;&gt;
&lt;td&gt;&lt;span&gt;1.9&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;10.2, 11.1&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1742&quot; data-start=&quot;1641&quot;&gt;
&lt;td&gt;&lt;span&gt;1.10&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;10.2, 11.3&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1846&quot; data-start=&quot;1745&quot;&gt;
&lt;td&gt;&lt;span&gt;1.11&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;10.2, 11.3&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1950&quot; data-start=&quot;1849&quot;&gt;
&lt;td&gt;&lt;span&gt;1.12&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;10.2, 11.6&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2060&quot; data-start=&quot;1953&quot;&gt;
&lt;td&gt;&lt;span&gt;1.13&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;11.6&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2165&quot; data-start=&quot;2063&quot;&gt;
&lt;td&gt;&lt;span&gt;2.0&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;11.7, 11.8&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2316&quot; data-start=&quot;2168&quot;&gt;
&lt;td&gt;&lt;span&gt;2.1&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;11.8, 12.1&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2451&quot; data-start=&quot;2318&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고:&lt;/b&gt; &lt;span&gt;PyTorch는 CUDA와의 호환성을 위해 다양한 버전의 빌드를 제공합니다.&lt;/span&gt; &lt;span&gt;따라서, 사용 중인 GPU와 CUDA 버전에 맞는 PyTorch 버전을 선택하여 설치하는 것이 중요합니다.&lt;/span&gt;​&lt;/p&gt;
&lt;hr data-end=&quot;2456&quot; data-start=&quot;2453&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2482&quot; data-start=&quot;2458&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;TensorRT와의 통합&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;2649&quot; data-start=&quot;2484&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;TensorRT는 NVIDIA의 딥러닝 추론 최적화 라이브러리로, 모델의 추론 속도를 크게 향상시킵니다.&lt;/span&gt; &lt;span&gt;PyTorch와 TensorRT의 통합은 Torch-TensorRT를 통해 이루어지며, 이는 PyTorch에서 학습한 모델을 TensorRT로 변환하여 추론 성능을 최대 6배까지 향상시킬 수 있습니다.&lt;/span&gt; ​&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2979&quot; data-start=&quot;2651&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2975&quot; data-start=&quot;2651&quot;&gt;&lt;b&gt;Torch-TensorRT 사용 예시:&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1741612789206&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import torch
import torch_tensorrt

model = MyModel().eval().cuda()  # 모델 정의
inputs = [torch.randn((1, 3, 224, 224)).cuda()]  # 입력 데이터 정의

# Torch-TensorRT를 사용하여 모델 최적화
optimized_model = torch_tensorrt.compile(model, inputs=inputs, enabled_precisions={torch.float})&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;3065&quot; data-start=&quot;2980&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3065&quot; data-start=&quot;2980&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;​&lt;/p&gt;
&lt;h2 data-end=&quot;3100&quot; data-start=&quot;3072&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;nvidia/pytorch 컨테이너 버전별 주요 변경 사항&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;# NVIDIA PyTorch 최신 컨테이너 사용
FROM nvcr.io/nvidia/pytorch:25.02-py3&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3221&quot; data-start=&quot;3102&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3221&quot; data-start=&quot;3102&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;NVIDIA는 딥러닝 프레임워크와 라이브러리의 호환성을 유지하기 위해 정기적으로 컨테이너를 업데이트합니다.&lt;/span&gt; 아래는 주요 변경 사항이 있었던 컨테이너 버전의 목록입니다:​&lt;/p&gt;
&lt;p data-end=&quot;3221&quot; data-start=&quot;3102&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3221&quot; data-start=&quot;3102&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.nvidia.com/deeplearning/frameworks/pytorch-release-notes/rel-25-02.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.nvidia.com/deeplearning/frameworks/pytorch-release-notes/rel-25-02.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1741614869941&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;PyTorch Release 25.02 - NVIDIA Docs&quot; data-og-description=&quot;NVIDIA Optimized Frameworks&quot; data-og-host=&quot;docs.nvidia.com&quot; data-og-source-url=&quot;https://docs.nvidia.com/deeplearning/frameworks/pytorch-release-notes/rel-25-02.html&quot; data-og-url=&quot;https://docs.nvidia.com/deeplearning/frameworks/pytorch-release-notes/rel-25-02.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.nvidia.com/deeplearning/frameworks/pytorch-release-notes/rel-25-02.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.nvidia.com/deeplearning/frameworks/pytorch-release-notes/rel-25-02.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;PyTorch Release 25.02 - NVIDIA Docs&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;NVIDIA Optimized Frameworks&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.nvidia.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;5461&quot; data-start=&quot;3223&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody data-end=&quot;5461&quot; data-start=&quot;3413&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;&lt;b&gt;&lt;span&gt;컨테이너 버전&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 11.0465%;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Ubuntu 버전&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Python 버전&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.1163%;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;CUDA 버전&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 11.5116%;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;PyTorch 버전&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 15.6977%;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;TensorRT 버전&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;주요 변경 사항&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3738&quot; data-start=&quot;3413&quot;&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;&lt;span&gt;25.02&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 11.0465%;&quot;&gt;&lt;span&gt;24.04&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;&lt;span&gt;3.12&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.1163%;&quot;&gt;&lt;span&gt;12.8.0.38&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 11.5116%;&quot;&gt;&lt;span&gt;2.7.0a0&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 15.6977%;&quot;&gt;&lt;span&gt;10.8.0.43&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%;&quot;&gt;&lt;span&gt;Ubuntu 24.04 및 Python 3.12로 업그레이드&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;4073&quot; data-start=&quot;3739&quot;&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;&lt;span&gt;23.06&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 11.0465%;&quot;&gt;&lt;span&gt;22.04&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;&lt;span&gt;3.10&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.1163%;&quot;&gt;&lt;span&gt;12.0&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 11.5116%;&quot;&gt;&lt;span&gt;2.1.0a0&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 15.6977%;&quot;&gt;&lt;span&gt;8.6.1&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%;&quot;&gt;&lt;span&gt;CUDA 12.0 지원 시작&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;4407&quot; data-start=&quot;4074&quot;&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;&lt;span&gt;22.08&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 11.0465%;&quot;&gt;&lt;span&gt;22.04&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;&lt;span&gt;3.10&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.1163%;&quot;&gt;&lt;span&gt;11.7&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 11.5116%;&quot;&gt;&lt;span&gt;1.13.0a0&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 15.6977%;&quot;&gt;&lt;span&gt;8.5.2&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%;&quot;&gt;&lt;span&gt;Ubuntu 22.04 및 Python 3.10으로 업그레이드&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;4743&quot; data-start=&quot;4408&quot;&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;&lt;span&gt;21.03&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 11.0465%;&quot;&gt;&lt;span&gt;20.04&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;&lt;span&gt;3.8&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.1163%;&quot;&gt;&lt;span&gt;11.2&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 11.5116%;&quot;&gt;&lt;span&gt;1.8.0a0&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 15.6977%;&quot;&gt;&lt;span&gt;7.2.2&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%;&quot;&gt;&lt;span&gt;Ubuntu 20.04 및 Python 3.8로 업그레이드&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;5079&quot; data-start=&quot;4744&quot;&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;&lt;span&gt;20.06&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 11.0465%;&quot;&gt;&lt;span&gt;18.04&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;&lt;span&gt;3.6&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.1163%;&quot;&gt;&lt;span&gt;11.0&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 11.5116%;&quot;&gt;&lt;span&gt;1.6.0a0&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 15.6977%;&quot;&gt;&lt;span&gt;7.0.0&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%;&quot;&gt;&lt;span&gt;CUDA 11.0 지원 시작&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;5461&quot; data-start=&quot;5080&quot;&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;&lt;span&gt;20.01&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 11.0465%;&quot;&gt;&lt;span&gt;18.04&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.814%;&quot;&gt;&lt;span&gt;3.6&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.1163%;&quot;&gt;&lt;span&gt;10.1&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 11.5116%;&quot;&gt;&lt;span&gt;1.4.0a0&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 15.6977%;&quot;&gt;&lt;span&gt;6.0.1&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%;&quot;&gt;&lt;span&gt;초기 릴리스&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;5589&quot; data-start=&quot;5463&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5589&quot; data-start=&quot;5463&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고:&lt;/b&gt; 각 컨테이너 버전은 해당 시점의 최신 소프트웨어 스택을 포함하고 있으며, 새로운 기능과 성능 향상을 제공합니다. 따라서, 프로젝트의 요구 사항과 사용 중인 하드웨어에 맞게 적절한 버전을 선택하는 것이 중요합니다.&lt;/p&gt;</description>
      <category>AI/ETC</category>
      <author>칼쵸쵸</author>
      <guid isPermaLink="true">https://chalchichi.tistory.com/128</guid>
      <comments>https://chalchichi.tistory.com/128#entry128comment</comments>
      <pubDate>Mon, 10 Mar 2025 22:27:27 +0900</pubDate>
    </item>
  </channel>
</rss>