<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>김신건의 로그 - 위키 / ml</title><description>&apos;ml&apos; 카테고리 위키 페이지 최신 업데이트</description><link>https://shinkeonkim.com/</link><language>ko-KR</language><item><title>[AWS SageMaker] Model Monitor: 모델 및 데이터 드리프트 감지</title><link>https://shinkeonkim.com/wiki/ml/sagemaker-model-monitor/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ml/sagemaker-model-monitor/</guid><pubDate>Mon, 29 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;AWS 공식 발표 (2026)&lt;/strong&gt;: &lt;strong&gt;2026-07-30 부터 SageMaker Model Monitor 는 신규 고객 사용이 중단됩니다.&lt;/strong&gt; 기존 사용 고객은 계속 이용 가능하며 보안/가용성 개선은 유지되지만, &lt;strong&gt;신규 기능 추가는 없습니다.&lt;/strong&gt; 대안으로 &lt;a href=&quot;https://docs.aws.amazon.com/sagemaker/latest/dg/model-monitor-availability-change.html&quot;&gt;Amazon SageMaker AI 통합 모니터링&lt;/a&gt;, 또는 서드파티 (EvidentlyAI, WhyLabs, Arize, Fiddler 등) 를 고려하세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Amazon SageMaker Model Monitor&lt;/strong&gt; 는 SageMaker AI 로 프로덕션 배포된 ML 모델의 &lt;strong&gt;데이터 및 모델 품질을 지속 모니터링&lt;/strong&gt; 하고, 드리프트가 발생하면 알림을 보내는 관리형 서비스입니다. 실시간 endpoint 와 배치 transform 작업 양쪽 모두를 지원합니다.&lt;/p&gt;
&lt;p&gt;핵심 아이디어: &lt;strong&gt;학습 데이터로 baseline 통계&lt;/strong&gt; 를 만들어 두고, 프로덕션 요청/응답을 캡처하여 &lt;strong&gt;주기적으로 baseline 과 비교&lt;/strong&gt;, 위반 (violation) 을 감지합니다.&lt;/p&gt;
&lt;h2 id=&quot;4-가지-모니터-타입&quot;&gt;4 가지 모니터 타입&lt;/h2&gt;
&lt;p&gt;Model Monitor 가 제공하는 네 가지 감시 유형입니다.&lt;/p&gt;
&lt;h3 id=&quot;1-data-quality-monitor&quot;&gt;1. Data Quality Monitor&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;입력 데이터 통계 변화 감지&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;학습 데이터의 통계 (feature 별 평균, 분산, 결측 비율, distinct 개수, 데이터 타입 등) 를 baseline 으로 삼음&lt;/li&gt;
&lt;li&gt;프로덕션 입력이 이 통계에서 크게 벗어나면 위반&lt;/li&gt;
&lt;li&gt;Data drift 라고도 부름&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;2-model-quality-monitor&quot;&gt;2. Model Quality Monitor&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;예측 성능 지표 자체를 모니터링&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Accuracy, F1, precision, recall, MSE, MAE 등 (참고: [[classification-metrics|분류 모델 지표]])&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;정답 라벨 (ground truth)&lt;/strong&gt; 이 나중에 제공되어야 하므로, 프로덕션 예측과 라벨을 매칭하는 파이프라인이 필요&lt;/li&gt;
&lt;li&gt;Concept drift 감지 목적&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-bias-drift-monitor&quot;&gt;3. Bias Drift Monitor&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;인구통계 집단 간 예측 편향 변화&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;SageMaker Clarify 와 통합&lt;/li&gt;
&lt;li&gt;지표: DPPL (Difference in Positive Proportions in Predicted Labels), DI (Disparate Impact) 등&lt;/li&gt;
&lt;li&gt;학습 시점 대비 특정 집단에 대한 편향이 커졌는지 감시&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;4-feature-attribution-drift-monitor&quot;&gt;4. Feature Attribution Drift Monitor&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;feature importance 분포 변화&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;SHAP 값 기반, 각 feature 가 예측에 기여하는 정도가 학습 시점과 달라졌는지&lt;/li&gt;
&lt;li&gt;입력 통계는 안 변했는데 feature 의 역할이 바뀐 미묘한 shift 를 잡음&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;아키텍처&quot;&gt;아키텍처&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;┌──────────────┐    inference    ┌───────────────────┐&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   Client     │ ─────────────&gt;  │  SageMaker        │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;└──────────────┘   request +     │  Endpoint         │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       ▲          response       │  (with            │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                         │   DataCapture)    │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                         └────────┬──────────┘&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                                  │ capture&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                                  ▼&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                          ┌────────────────┐&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                          │   S3 bucket    │  ◀── training data baseline&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                          │   captured/    │      (statistics.json,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                          └────────┬───────┘       constraints.json)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                                   │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                                   ▼&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                          ┌────────────────┐&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                          │  Monitoring    │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                          │  Schedule      │  (hourly / daily)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                          │  (Processing   │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                          │   Job)         │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                          └────────┬───────┘&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                                   │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                                   ▼&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │                          ┌────────────────┐&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       │  alert  ┌────────────┐   │  CloudWatch    │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       └────────┤ SNS/Lambda  ├───┤  Metrics +     │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                └────────────┘    │  Alarms        │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                                  └────────────────┘&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;단계별-컴포넌트&quot;&gt;단계별 컴포넌트&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Data Capture&lt;/strong&gt;: 엔드포인트에 &lt;code&gt;DataCaptureConfig&lt;/code&gt; 활성화, 입력/출력을 S3 에 저장&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Baseline&lt;/strong&gt;: 학습 데이터에서 &lt;code&gt;suggest_baseline()&lt;/code&gt; 실행 → &lt;code&gt;statistics.json&lt;/code&gt; + &lt;code&gt;constraints.json&lt;/code&gt; 생성&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monitoring Schedule&lt;/strong&gt;: cron 또는 hourly 로 Processing Job 자동 실행&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Processing Job&lt;/strong&gt;: 컨테이너에서 캡처 데이터 vs baseline 비교, 위반 리포트 생성&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CloudWatch&lt;/strong&gt;: 위반 개수, 지표를 CloudWatch 메트릭으로 발행. 알람 → SNS → Lambda / Slack / PagerDuty&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;python-sdk-클래스&quot;&gt;Python SDK 클래스&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;sagemaker&lt;/code&gt; Python SDK 의 각 모니터 클래스:&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;클래스&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;모니터 타입&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;sagemaker.model_monitor.DefaultModelMonitor&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Data Quality&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;sagemaker.model_monitor.ModelQualityMonitor&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Model Quality&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;sagemaker.model_monitor.ModelBiasMonitor&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Bias Drift&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;sagemaker.model_monitor.ModelExplainabilityMonitor&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Feature Attribution Drift&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;공통 인터페이스:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;suggest_baseline(...)&lt;/code&gt;: baseline 통계 생성&lt;/li&gt;
&lt;li&gt;&lt;code&gt;create_monitoring_schedule(...)&lt;/code&gt;: 스케줄 등록&lt;/li&gt;
&lt;li&gt;&lt;code&gt;describe_schedule()&lt;/code&gt;, &lt;code&gt;list_executions()&lt;/code&gt;, &lt;code&gt;stop_monitoring_schedule()&lt;/code&gt;, &lt;code&gt;delete_monitoring_schedule()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;실전-코드-data-quality&quot;&gt;실전 코드 (Data Quality)&lt;/h2&gt;
&lt;h3 id=&quot;1-endpoint-에-data-capture-활성화&quot;&gt;1. Endpoint 에 Data Capture 활성화&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sagemaker.model_monitor &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; DataCaptureConfig&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;data_capture_config &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; DataCaptureConfig(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    enable_capture&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    sampling_percentage&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    destination_s3_uri&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;s3://&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;bucket&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/captured/&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    capture_options&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;REQUEST&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;RESPONSE&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    csv_content_types&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;text/csv&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    json_content_types&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;application/json&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;predictor &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; model.deploy(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    initial_instance_count&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    instance_type&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;ml.m5.xlarge&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    data_capture_config&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;data_capture_config,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;2-baseline-생성&quot;&gt;2. Baseline 생성&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sagemaker.model_monitor &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; DefaultModelMonitor&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sagemaker.model_monitor.dataset_format &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; DatasetFormat&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;monitor &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; DefaultModelMonitor(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    role&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;role,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    instance_count&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    instance_type&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;ml.m5.xlarge&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    volume_size_in_gb&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    max_runtime_in_seconds&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;3600&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;monitor.suggest_baseline(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    baseline_dataset&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;s3://&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;bucket&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/training-data.csv&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    dataset_format&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;DatasetFormat.csv(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;header&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    output_s3_uri&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;s3://&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;bucket&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/baselines/&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    wait&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;결과로 &lt;code&gt;statistics.json&lt;/code&gt; (feature 별 mean, std, min, max, distinct_count 등) 과 &lt;code&gt;constraints.json&lt;/code&gt; (허용 범위) 이 생깁니다.&lt;/p&gt;
&lt;h3 id=&quot;3-monitoring-schedule-등록&quot;&gt;3. Monitoring Schedule 등록&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sagemaker.model_monitor &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; CronExpressionGenerator&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;monitor.create_monitoring_schedule(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    monitor_schedule_name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;my-daily-monitor&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    endpoint_input&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;predictor.endpoint_name,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    output_s3_uri&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;s3://&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;bucket&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/monitor-reports/&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    statistics&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;monitor.baseline_statistics(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    constraints&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;monitor.suggested_constraints(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    schedule_cron_expression&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;CronExpressionGenerator.hourly(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    enable_cloudwatch_metrics&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;4-cloudwatch-알람-연결&quot;&gt;4. CloudWatch 알람 연결&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; boto3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;cw &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; boto3.client(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cloudwatch&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;cw.put_metric_alarm(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    AlarmName&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;ModelMonitor-FeatureBaselineDrift&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    MetricName&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;feature_baseline_drift_check_violations&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    Namespace&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;aws/sagemaker/Endpoints/data-metrics&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    Statistic&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Sum&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    Period&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;3600&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    EvaluationPeriods&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    Threshold&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    ComparisonOperator&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;GreaterThanOrEqualToThreshold&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    AlarmActions&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;arn:aws:sns:us-east-1:123:model-alerts&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    Dimensions&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Endpoint&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Value&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: predictor.endpoint_name},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;MonitoringSchedule&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Value&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;my-daily-monitor&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;model-quality-의-ground-truth-연결&quot;&gt;Model Quality 의 ground truth 연결&lt;/h2&gt;
&lt;p&gt;Model Quality Monitor 는 &lt;strong&gt;예측 결과와 실제 정답을 매칭&lt;/strong&gt; 해야 하는 게 특별합니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;예측 시 각 요청에 &lt;code&gt;inference_id&lt;/code&gt; 부여 (헤더 또는 payload 필드)&lt;/li&gt;
&lt;li&gt;나중에 정답 라벨이 확정되면 &lt;code&gt;s3://.../ground_truth/YYYY/MM/DD/HH/data.json&lt;/code&gt; 에 저장&lt;/li&gt;
&lt;li&gt;Model Quality Monitor 가 이 두 소스를 조인해서 accuracy/F1 등 계산&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;라벨 지연이 큰 서비스 (예: 이탈 예측은 30 일 후 결과 확인) 에는 스케줄을 그에 맞게 설정합니다.&lt;/p&gt;
&lt;h2 id=&quot;baseline-파일-형식&quot;&gt;Baseline 파일 형식&lt;/h2&gt;
&lt;h3 id=&quot;statisticsjson-예&quot;&gt;statistics.json (예)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;version&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;dataset&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;item_count&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;10000&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;features&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;age&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;inferred_type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Fractional&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;numerical_statistics&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        &quot;common&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;num_present&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;9980&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;num_missing&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        &quot;mean&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;34.5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;sum&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;344310&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;std_dev&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;12.3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        &quot;min&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;18&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;max&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;88&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        &quot;distribution&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;kll&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; } }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;constraintsjson-예&quot;&gt;constraints.json (예)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;version&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;features&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;age&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;inferred_type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Fractional&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;completeness&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.998&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;num_constraints&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;is_non_negative&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;monitoring_config&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    &quot;evaluate_constraints&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Enabled&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    &quot;datatype_check_threshold&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1.0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    &quot;domain_content_threshold&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1.0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    &quot;distribution_constraints&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;perform_comparison&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Enabled&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;comparison_threshold&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;comparison_method&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Robust&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;comparison_method&lt;/code&gt; 는 &lt;code&gt;Simple&lt;/code&gt; / &lt;code&gt;Robust&lt;/code&gt; / &lt;code&gt;LInfty&lt;/code&gt; 등이 있으며, 통계 비교 방식을 정의합니다.&lt;/p&gt;
&lt;h2 id=&quot;지원-데이터-타입-제한&quot;&gt;지원 데이터 타입 제한&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;tabular 입력만&lt;/strong&gt; 자동 통계 지원. 이미지 분류 모델의 이미지 입력은 통계 계산 불가, 하지만 &lt;strong&gt;출력 라벨은 모니터링 가능&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Multi-model endpoint 미지원&lt;/li&gt;
&lt;li&gt;Data Capture 저장소 disk 사용률 75% 이상이면 캡처 중단 → 정기 정리 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;다른-도구와-비교&quot;&gt;다른 도구와 비교&lt;/h2&gt;















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;도구&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;관리 방식&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;강점&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;약점&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;SageMaker Model Monitor&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;AWS 관리형&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;SageMaker 통합 편함&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;2026-07-30 신규 종료&lt;/strong&gt;, 커스터마이징 제한&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://www.evidentlyai.com/&quot;&gt;EvidentlyAI&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;오픈소스 + 클라우드&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;시각화 강함, 프레임워크 애그노스틱&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;셀프 호스팅 부담&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://whylabs.ai/&quot;&gt;WhyLabs&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;SaaS&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;whylogs 프로파일링 라이브러리 좋음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;유료&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://arize.com/&quot;&gt;Arize AI&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;SaaS&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;LLM 모니터링 강점 (Phoenix)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;유료&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://www.fiddler.ai/&quot;&gt;Fiddler&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;SaaS&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;대기업 규제 산업 대응&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;무거움&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Prometheus + Grafana + 자체 스크립트&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;셀프&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;완전 제어&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;초기 구현 부담&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;비용&quot;&gt;비용&lt;/h2&gt;
&lt;p&gt;Model Monitor 는 &lt;strong&gt;처리 작업 (Processing Job) 실행 비용&lt;/strong&gt; 을 청구합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;인스턴스 타입 (&lt;code&gt;ml.m5.xlarge&lt;/code&gt; 등) × 실행 시간&lt;/li&gt;
&lt;li&gt;하루 24 회 (매 시간) × 30 분씩 실행이면 대략 12 시간분 비용&lt;/li&gt;
&lt;li&gt;S3 저장 (capture, baseline, report), CloudWatch 메트릭 별도&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;프로덕션에서는 하루 1~2 회 스케줄로 충분한 경우가 많습니다.&lt;/p&gt;
&lt;h2 id=&quot;best-practice&quot;&gt;Best Practice&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Baseline 은 학습 데이터가 아니라 최근 검증 데이터&lt;/strong&gt; 로 만들면 편차가 작습니다&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alert threshold 를 여러 심각도로&lt;/strong&gt; (warning: violations&gt;=1, critical: violations&gt;=5)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CloudWatch 대신 EventBridge → Lambda → 슬랙&lt;/strong&gt; 을 자주 사용&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;비용 통제&lt;/strong&gt;: 트래픽 크면 &lt;code&gt;sampling_percentage=10&lt;/code&gt; 정도로 낮춰서 캡처&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Model Quality 는 라벨 지연을 감안&lt;/strong&gt; 하여 스케줄 늦춤&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;위반이 나면 자동 재학습 트리거&lt;/strong&gt; 하는 파이프라인 (SageMaker Pipelines + Step Functions)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;드리프트가 아니라 데이터 파이프라인 문제일 가능성&lt;/strong&gt; 을 먼저 검토 (매핑 코드 변경, 스키마 변경 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;model-drift-개념-정리&quot;&gt;Model Drift 개념 정리&lt;/h2&gt;
&lt;p&gt;Model Monitor 가 감지하려는 것들:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Data Drift&lt;/strong&gt; (Covariate Shift): 입력 $P(X)$ 분포 변화. 데이터 자체가 달라진 경우&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Concept Drift&lt;/strong&gt;: 입력-출력 관계 $P(Y|X)$ 변화. 예측 대상 자체의 성질 변화 (예: 사기 패턴이 진화)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Label Drift&lt;/strong&gt;: $P(Y)$ 변화. 실제 정답 분포가 달라진 경우&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prediction Drift&lt;/strong&gt;: 모델 예측 $P(\hat{Y})$ 변화. 위 셋 중 하나 이상의 결과&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;각각 다른 시그널이며, 4 가지 모니터가 이 시그널들을 부분적으로 커버합니다.&lt;/p&gt;
&lt;h2 id=&quot;대안-2026-신규-종료-이후&quot;&gt;대안 (2026 신규 종료 이후)&lt;/h2&gt;
&lt;p&gt;신규 프로젝트라면 다음을 고려:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Evidently + SageMaker Pipelines&lt;/strong&gt;: 오픈소스, SageMaker 안에서 처리 작업으로 실행&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;whylogs + WhyLabs&lt;/strong&gt;: 데이터 프로파일링 라이브러리, WhyLabs SaaS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;자체 구축&lt;/strong&gt;: Great Expectations 로 데이터 품질, MLflow 로 모델 성능 트래킹&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWS 대체&lt;/strong&gt;: 앞으로 나올 SageMaker AI 의 통합 모니터링 (공지 참고)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;참고&quot;&gt;참고&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;관련 [[classification-metrics|분류 모델 지표]] 는 Model Quality Monitor 의 근간&lt;/li&gt;
&lt;li&gt;관련 [[transfer-learning|Transfer Learning]] fine-tuned 모델도 동일하게 모니터링 대상&lt;/li&gt;
&lt;li&gt;AWS 공식: &lt;a href=&quot;https://docs.aws.amazon.com/sagemaker/latest/dg/model-monitor.html&quot;&gt;Model Monitor&lt;/a&gt;, &lt;a href=&quot;https://docs.aws.amazon.com/sagemaker/latest/dg/model-monitor-availability-change.html&quot;&gt;Availability change&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;참고 아티클: &lt;a href=&quot;https://www.evidentlyai.com/ml-in-production/data-drift&quot;&gt;Model drift 관련 개념&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>aws</category><category>sagemaker</category><category>mlops</category><category>monitoring</category><category>drift</category><author>koa (김신건)</author></item><item><title>Differential Privacy: (ε, δ) 로 정량화하는 프라이버시 보장</title><link>https://shinkeonkim.com/wiki/ml/differential-privacy/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ml/differential-privacy/</guid><pubDate>Mon, 29 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Differential Privacy (DP, 차분 프라이버시)&lt;/strong&gt; 는 데이터셋에 대한 질의 (query) 결과에 &lt;strong&gt;calibrated noise&lt;/strong&gt; 를 추가함으로써, &lt;strong&gt;한 개인의 데이터가 포함되었는지 여부&lt;/strong&gt; 를 결과만 보고서는 알 수 없게 만드는 수학적 프라이버시 프레임워크입니다. Cynthia Dwork 등이 2006 년에 정의했습니다.&lt;/p&gt;
&lt;p&gt;핵심 아이디어: “당신이 데이터셋에 있든 없든, 통계 결과는 거의 같게 보이도록 만든다.”&lt;/p&gt;
&lt;h2 id=&quot;왜-등장했는가&quot;&gt;왜 등장했는가&lt;/h2&gt;
&lt;p&gt;전통적 익명화 (identifier 제거, k-anonymity, l-diversity 등) 는 &lt;strong&gt;linkage attack&lt;/strong&gt; 에 취약합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Netflix Prize (2007)&lt;/strong&gt;: 익명화된 시청 기록이 IMDb 공개 리뷰와 결합되어 사용자 재식별&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AOL 검색 로그 (2006)&lt;/strong&gt;: 사용자 ID 만 익명화했지만 검색 쿼리 자체가 지문 역할&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Massachusetts governor 재식별 (Sweeney, 1997)&lt;/strong&gt;: ZIP + 생년월일 + 성별 3 축만으로 87% 재식별 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;문제의 본질: &lt;strong&gt;관측 가능한 결과가 특정 개인의 데이터에 크게 의존&lt;/strong&gt; 하면, 아무리 이름을 지워도 그 개인이 데이터에 있었다는 사실 자체가 새어 나갑니다. DP 는 이 의존성을 &lt;strong&gt;정량적 상한&lt;/strong&gt; 으로 제어합니다.&lt;/p&gt;
&lt;h2 id=&quot;형식-정의&quot;&gt;형식 정의&lt;/h2&gt;
&lt;h3 id=&quot;인접-데이터셋-adjacent-datasets&quot;&gt;인접 데이터셋 (Adjacent Datasets)&lt;/h3&gt;
&lt;p&gt;두 데이터셋 $D$ 와 $D’$ 이 &lt;strong&gt;정확히 한 레코드만 다를 때&lt;/strong&gt; 인접 (adjacent) 이라고 합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add/Remove 인접: $D’ = D \cup {x}$ 또는 $D’ = D \setminus {x}$&lt;/li&gt;
&lt;li&gt;Replace 인접: $D’$ 이 $D$ 의 한 레코드를 다른 값으로 바꾼 결과&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;정의에 따라 프라이버시 보장 강도가 조금씩 달라지지만, 실용적으로는 큰 차이 없습니다.&lt;/p&gt;
&lt;h3 id=&quot;ε-differential-privacy-pure-dp&quot;&gt;ε-Differential Privacy (pure DP)&lt;/h3&gt;
&lt;p&gt;무작위 알고리즘 $\mathcal{M}$ 이 $\epsilon$-DP 를 만족한다는 것은, 임의의 인접 데이터셋 $D, D’$ 과 임의의 출력 집합 $S$ 에 대해:&lt;/p&gt;
&lt;p&gt;$$
\Pr[\mathcal{M}(D) \in S] \leq e^{\epsilon} \cdot \Pr[\mathcal{M}(D’) \in S]
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\epsilon$ (epsilon): 프라이버시 손실의 상한. 작을수록 강력한 보장.&lt;/li&gt;
&lt;li&gt;$e^\epsilon \approx 1 + \epsilon$ (작은 $\epsilon$ 일 때), 즉 두 확률 분포가 매우 유사.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;ε-δ-differential-privacy-approximate-dp&quot;&gt;(ε, δ)-Differential Privacy (approximate DP)&lt;/h3&gt;
&lt;p&gt;$$
\Pr[\mathcal{M}(D) \in S] \leq e^{\epsilon} \cdot \Pr[\mathcal{M}(D’) \in S] + \delta
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\delta$: 위 부등식이 실패할 확률의 상한. 보통 $\delta \ll 1/n$ (데이터 크기의 역수보다 작게)&lt;/li&gt;
&lt;li&gt;Gaussian mechanism 등은 pure DP 를 만족할 수 없어 approximate DP 를 씀&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Rule of thumb&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\epsilon \leq 1$: 강한 보장&lt;/li&gt;
&lt;li&gt;$1 &amp;#x3C; \epsilon \leq 3$: 중간&lt;/li&gt;
&lt;li&gt;$\epsilon &gt; 10$: 실질적 보장 미미 (경고 신호)&lt;/li&gt;
&lt;li&gt;$\delta &amp;#x3C; 1/n^2$ 정도 권장 (Dwork 의 조언)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;왜-이-정의인가&quot;&gt;왜 이 정의인가&lt;/h2&gt;
&lt;p&gt;DP 의 강력한 점:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;개인 데이터의 존재/부재를 감출 수 있음&lt;/strong&gt;: 공격자가 사전에 알고 있는 정보가 아무리 많아도 (어떤 auxiliary data 를 가지고 있어도) 새 정보를 얻기 어려움&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Composition 가능&lt;/strong&gt;: 여러 DP 쿼리를 합쳐도 여전히 DP 성질 유지 (예산 합산)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Post-processing immunity&lt;/strong&gt;: DP 결과에 어떤 계산을 추가로 해도 여전히 DP 유지&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;미래 공격에 대비&lt;/strong&gt;: 특정 공격을 상정하지 않고 최악 케이스를 다룸&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;핵심-개념-sensitivity&quot;&gt;핵심 개념: Sensitivity&lt;/h2&gt;
&lt;p&gt;함수 $f: \text{Data} \to \mathbb{R}^d$ 의 &lt;strong&gt;global sensitivity&lt;/strong&gt; 는 인접 데이터셋에 대한 함수 값 변화의 상한:&lt;/p&gt;
&lt;p&gt;$$
\Delta f = \max_{D, D’ \text{ adjacent}} | f(D) - f(D’) |_1
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;개수 세기 (count): $\Delta f = 1$ (한 명 추가/제거하면 결과 1 변함)&lt;/li&gt;
&lt;li&gt;평균 (mean) with bounded values in $[0, M]$: $\Delta f = M/n$&lt;/li&gt;
&lt;li&gt;합 (sum) with bounded values in $[0, M]$: $\Delta f = M$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sensitivity 가 클수록 더 많은 노이즈가 필요합니다. &lt;strong&gt;값을 미리 clip 해서 sensitivity 를 제어&lt;/strong&gt; 하는 게 실전에서 매우 흔한 패턴입니다.&lt;/p&gt;
&lt;h2 id=&quot;핵심-메커니즘&quot;&gt;핵심 메커니즘&lt;/h2&gt;
&lt;h3 id=&quot;laplace-mechanism&quot;&gt;Laplace Mechanism&lt;/h3&gt;
&lt;p&gt;$\epsilon$-DP 를 만족하는 가장 단순한 방법. Laplace 분포에서 노이즈 샘플:&lt;/p&gt;
&lt;p&gt;$$
\mathcal{M}(D) = f(D) + \text{Lap}\left( \frac{\Delta f}{\epsilon} \right)
$$&lt;/p&gt;
&lt;p&gt;Laplace 분포는 라플라스 확률 밀도 $\text{Lap}(b): p(x) = \frac{1}{2b} e^{-|x|/b}$.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; numpy &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; np&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; laplace_mechanism&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(true_value, sensitivity, epsilon):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    noise &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; np.random.laplace(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;loc&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;scale&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;sensitivity&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;epsilon)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; true_value &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; noise&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 예: 데이터셋에서 특정 조건 만족하는 사용자 수 세기&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;true_count &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 4321&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;noisy_count &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; laplace_mechanism(true_count, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;sensitivity&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;epsilon&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;gaussian-mechanism&quot;&gt;Gaussian Mechanism&lt;/h3&gt;
&lt;p&gt;$(\epsilon, \delta)$-DP 를 만족. L2 sensitivity 사용:&lt;/p&gt;
&lt;p&gt;$$
\mathcal{M}(D) = f(D) + \mathcal{N}\left(0, \left(\frac{\Delta_2 f \cdot \sqrt{2 \ln(1.25/\delta)}}{\epsilon}\right)^2 \right)
$$&lt;/p&gt;
&lt;p&gt;Gaussian 은 여러 차원의 합성에서 유리하며, DP-SGD 등에서 표준입니다.&lt;/p&gt;
&lt;h3 id=&quot;exponential-mechanism&quot;&gt;Exponential Mechanism&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;범주형/불연속 출력&lt;/strong&gt; 에 사용. Utility 함수 $u(D, r)$ 을 정의하고:&lt;/p&gt;
&lt;p&gt;$$
\Pr[\mathcal{M}(D) = r] \propto \exp\left( \frac{\epsilon \cdot u(D, r)}{2 \Delta u} \right)
$$&lt;/p&gt;
&lt;p&gt;Utility 가 높은 후보를 확률적으로 우선 선택합니다. 경매, 후보 선택 문제에 씀.&lt;/p&gt;
&lt;h2 id=&quot;composition&quot;&gt;Composition&lt;/h2&gt;
&lt;p&gt;여러 DP 쿼리를 순차적으로 하면 프라이버시가 누적됩니다.&lt;/p&gt;
&lt;h3 id=&quot;basic-composition&quot;&gt;Basic Composition&lt;/h3&gt;
&lt;p&gt;$k$ 개의 $(\epsilon_i, \delta_i)$-DP 메커니즘의 순차 합성은:&lt;/p&gt;
&lt;p&gt;$$
\left(\sum \epsilon_i, \sum \delta_i\right)\text{-DP}
$$&lt;/p&gt;
&lt;p&gt;간단하지만 상당히 loose 합니다.&lt;/p&gt;
&lt;h3 id=&quot;advanced-composition-dwork-et-al-2010&quot;&gt;Advanced Composition (Dwork et al., 2010)&lt;/h3&gt;
&lt;p&gt;$k$ 개의 $(\epsilon, \delta)$-DP 메커니즘의 합성은 다음과 같이 tighter:&lt;/p&gt;
&lt;p&gt;$$
\left(\epsilon’ = \epsilon \sqrt{2k \ln(1/\delta’)} + k \epsilon (e^\epsilon - 1), ; k\delta + \delta’\right)\text{-DP}
$$&lt;/p&gt;
&lt;p&gt;Basic 대비 $\sqrt{k}$ 배 정도로 개선됩니다.&lt;/p&gt;
&lt;h3 id=&quot;rényi-dp-를-통한-tighter-composition&quot;&gt;Rényi DP 를 통한 tighter composition&lt;/h3&gt;
&lt;p&gt;Mironov (2017) 의 &lt;strong&gt;Rényi DP&lt;/strong&gt; 는 Rényi divergence 로 프라이버시를 정의합니다. 합성이 매우 tight 하며 최종적으로 $(\epsilon, \delta)$-DP 로 변환합니다. &lt;strong&gt;DP-SGD 의 privacy accounting 은 사실상 Rényi DP + Moments Accountant&lt;/strong&gt; 방식입니다.&lt;/p&gt;
&lt;h2 id=&quot;privacy-budget&quot;&gt;Privacy Budget&lt;/h2&gt;
&lt;p&gt;한 데이터셋에 대해 여러 분석을 하고 싶다면, 각 분석마다 $\epsilon_i$ 를 배분해야 합니다.&lt;/p&gt;
&lt;p&gt;$$
\sum_i \epsilon_i \leq \epsilon_{\text{total}}
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;총 예산 소진 후에는 더 이상 어떤 쿼리도 하면 안 됨&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;프로덕션에서는 accountant 로 남은 예산을 실시간 추적&lt;/li&gt;
&lt;li&gt;예산이 부족하면: 데이터셋 refresh, 사용자 그룹 세분화, 더 세밀한 clipping 으로 sensitivity 감소&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;central-dp-vs-local-dp&quot;&gt;Central DP vs Local DP&lt;/h2&gt;
&lt;h3 id=&quot;central-dp-trusted-curator&quot;&gt;Central DP (Trusted Curator)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;신뢰할 수 있는 데이터 큐레이터 존재&lt;/li&gt;
&lt;li&gt;큐레이터가 원본 데이터를 보고 노이즈 추가 후 결과 공개&lt;/li&gt;
&lt;li&gt;Utility 높음, 프라이버시 보장은 큐레이터를 신뢰한다는 전제&lt;/li&gt;
&lt;li&gt;예: 미국 인구조사국, 대부분의 학술 통계&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;local-dp-ldp&quot;&gt;Local DP (LDP)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;신뢰할 수 있는 큐레이터가 없음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;각 개인이 자기 데이터에 노이즈를 추가하고 서버에 전송&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;서버는 노이즈가 낀 데이터만 받으므로 원본을 알 수 없음&lt;/li&gt;
&lt;li&gt;Utility 매우 낮음 (같은 $\epsilon$ 이면 노이즈가 훨씬 커야 함)&lt;/li&gt;
&lt;li&gt;Apple, Google 이 자주 배포&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;rappor-google-2014&quot;&gt;RAPPOR (Google, 2014)&lt;/h3&gt;
&lt;p&gt;LDP 의 대표 배포. Chrome 사용자의 홈페이지 URL 통계를 수집할 때 각 사용자가 자기 URL 을 Bloom filter 로 인코딩한 뒤 각 비트를 &lt;strong&gt;randomized response&lt;/strong&gt; 로 뒤집어 전송. 서버는 통계만 복원 가능, 개인 URL 은 알 수 없음.&lt;/p&gt;
&lt;h3 id=&quot;비교&quot;&gt;비교&lt;/h3&gt;






























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;구분&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Central DP&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Local DP&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;신뢰 모델&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;큐레이터 신뢰 필요&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Trustless&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;노이즈 위치&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;서버 (집계 후)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;클라이언트 (개별 데이터)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;같은 ε 에서 utility&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;높음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;낮음&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;배포 사례&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;미국 인구조사, 학술&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Apple 이모지, Google RAPPOR&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;dp-sgd-딥러닝-학습의-dp&quot;&gt;DP-SGD, 딥러닝 학습의 DP&lt;/h2&gt;
&lt;p&gt;Abadi et al. (2016) 이 제안한 &lt;strong&gt;DP-SGD (Differentially Private SGD)&lt;/strong&gt; 는 딥러닝 학습에 DP 를 적용하는 표준 방법입니다.&lt;/p&gt;
&lt;p&gt;알고리즘:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Sample&lt;/strong&gt;: 각 step 에서 mini-batch 를 Poisson sampling (각 샘플이 확률 $q = B/N$ 로 포함)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compute per-sample gradients&lt;/strong&gt;: 각 샘플에 대한 gradient 를 개별 계산&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clip&lt;/strong&gt;: 각 gradient 를 L2 norm 상한 $C$ 로 클립
$$
\bar{g}_i = g_i / \max\left(1, \frac{|g_i|_2}{C}\right)
$$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Aggregate + noise&lt;/strong&gt;: 클립된 gradient 를 합산하고 Gaussian noise 추가
$$
\tilde{g} = \frac{1}{B}\left( \sum_i \bar{g}_i + \mathcal{N}(0, \sigma^2 C^2 I) \right)
$$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Update&lt;/strong&gt;: $\theta \leftarrow \theta - \eta \tilde{g}$&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;노이즈 배율 $\sigma$ 와 sampling 확률 $q$, 총 step 수 $T$ 로부터 최종 $(\epsilon, \delta)$ 를 계산합니다 (Moments Accountant 또는 Rényi DP accountant).&lt;/p&gt;
&lt;h3 id=&quot;opacus-pytorch&quot;&gt;Opacus (PyTorch)&lt;/h3&gt;
&lt;p&gt;Facebook Research 의 PyTorch DP 라이브러리:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; opacus &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; PrivacyEngine&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; MyModel()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;optimizer &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; torch.optim.SGD(model.parameters(), &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;lr&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.05&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;data_loader &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; torch.utils.data.DataLoader(dataset, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;batch_size&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;256&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;privacy_engine &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; PrivacyEngine()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model, optimizer, data_loader &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; privacy_engine.make_private(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    module&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    optimizer&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;optimizer,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    data_loader&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;data_loader,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    noise_multiplier&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1.1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,       &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# σ&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    max_grad_norm&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1.0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,          &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# C&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; epoch &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; range&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(N):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; batch, labels &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; data_loader:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        optimizer.zero_grad()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        loss &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; criterion(model(batch), labels)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        loss.backward()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        optimizer.step()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    epsilon &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; privacy_engine.get_epsilon(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;delta&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1e-5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;epoch &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;epoch&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;: (ε=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;epsilon&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:.2f&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;, δ=1e-5)&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;dp-sgd-의-utility-손실&quot;&gt;DP-SGD 의 utility 손실&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;이미지 분류에서 clean 대비 5~15%p accuracy 손실이 흔함&lt;/li&gt;
&lt;li&gt;LLM 파인튜닝에서는 더 심각할 수 있음&lt;/li&gt;
&lt;li&gt;완화: PEFT 와 결합 (파라미터 수가 적으면 노이즈 영향 감소), 사전 학습 모델 재사용, 더 큰 batch&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;실배포-사례&quot;&gt;실배포 사례&lt;/h2&gt;
&lt;h3 id=&quot;apple-2016&quot;&gt;Apple (2016~)&lt;/h3&gt;
&lt;p&gt;iOS 10 부터 emoji 추천, QuickType 같은 기능에 LDP. Randomized response 계열, ε 는 일당 수 단위. WWDC 2016 발표.&lt;/p&gt;
&lt;h3 id=&quot;google&quot;&gt;Google&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RAPPOR&lt;/strong&gt; (Chrome, 2014)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Federated Learning + DP&lt;/strong&gt; (Gboard 다음 단어 예측)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google Health&lt;/strong&gt; 데이터 집계&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;us-census-2020&quot;&gt;US Census (2020)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;2020 년 미국 인구조사가 DP 를 공식 채택.&lt;/strong&gt; 발표된 통계에 Gaussian noise 를 추가한 것이 정치적 논란도 있었지만 역사적 이정표입니다. Epsilon 은 여러 통계별로 배분 (총 예산 약 $\epsilon = 19.6$).&lt;/p&gt;
&lt;h3 id=&quot;microsoft&quot;&gt;Microsoft&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Windows telemetry 에 LDP 적용&lt;/li&gt;
&lt;li&gt;SmartNoise 오픈소스 릴리스&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;학술-데이터셋&quot;&gt;학술 데이터셋&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;OpenDP 프로젝트 (Harvard) 가 공공 데이터셋 릴리스에 DP 도구 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;프레임워크&quot;&gt;프레임워크&lt;/h2&gt;

































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;도구&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;특징&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://opacus.ai/&quot;&gt;Opacus&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;PyTorch, DP-SGD, Facebook&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/tensorflow/privacy&quot;&gt;TensorFlow Privacy&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;TF, DP-SGD, Google&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://opendp.org/&quot;&gt;OpenDP&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Harvard, rigorous verification, Rust core + Python binding&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/IBM/differential-privacy-library&quot;&gt;Diffprivlib&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;IBM, sklearn-호환 인터페이스&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://smartnoise.org/&quot;&gt;SmartNoise&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Microsoft + OpenDP, 통계 쿼리 지향&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/OpenMined/PyDP&quot;&gt;PyDP&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;OpenMined, Google DP C++ 라이브러리 wrapper&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;한계와-유의점&quot;&gt;한계와 유의점&lt;/h2&gt;
&lt;h3 id=&quot;utility-privacy-trade-off&quot;&gt;Utility-Privacy Trade-off&lt;/h3&gt;
&lt;p&gt;강력한 프라이버시 ($\epsilon$ 작게) 는 노이즈 증가 → 정확도 하락. &lt;strong&gt;“공짜 프라이버시” 는 없습니다.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;ε-해석의-어려움&quot;&gt;ε 해석의 어려움&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;실무자에게 ε=1 이 “얼마나 안전한지” 직관 어려움&lt;/li&gt;
&lt;li&gt;$e^\epsilon$ 배 정도의 확률 차이라고 설명해도 감이 안 오는 경우 많음&lt;/li&gt;
&lt;li&gt;최근에는 &lt;strong&gt;Bayesian re-interpretation&lt;/strong&gt; 이나 &lt;strong&gt;membership inference attack&lt;/strong&gt; 성공률로 환산해 설명하려는 시도&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;데이터-카탈로그-문제&quot;&gt;데이터 카탈로그 문제&lt;/h3&gt;
&lt;p&gt;DP 는 &lt;strong&gt;각 쿼리&lt;/strong&gt; 에 대해 보장하는 것이지, 데이터셋 자체를 “완전히 익명” 만드는 것이 아닙니다. 여러 릴리스가 쌓이면 예산이 소진됩니다.&lt;/p&gt;
&lt;h3 id=&quot;결측치와-outlier&quot;&gt;결측치와 outlier&lt;/h3&gt;
&lt;p&gt;극단값이 sensitivity 를 크게 만들어 노이즈가 급증합니다. Clipping 을 잘 설계해야 함.&lt;/p&gt;
&lt;h3 id=&quot;group-privacy-는-다름&quot;&gt;Group Privacy 는 다름&lt;/h3&gt;
&lt;p&gt;DP 는 “한 개인” 을 보호합니다. 가족처럼 상관관계 있는 그룹은 별도 분석 필요.&lt;/p&gt;
&lt;h3 id=&quot;정확한-구현이-어려움&quot;&gt;정확한 구현이 어려움&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Floating-point 구현이 이론과 미묘하게 어긋나 실제로 DP 를 위반하는 사례 보고 (Mironov, 2012)&lt;/li&gt;
&lt;li&gt;Random number generator 품질 중요&lt;/li&gt;
&lt;li&gt;이 때문에 검증된 라이브러리 (Opacus, OpenDP) 사용 강력 권장&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;관련-개념-비교&quot;&gt;관련 개념 비교&lt;/h2&gt;













































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;방법&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;보장 강도&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;특징&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Identifier 제거&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;매우 약함&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Netflix, AOL 사건으로 실패 증명&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;k-anonymity&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;약함&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Quasi-identifier 지정 필요, 조합 attack 취약&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;l-diversity, t-closeness&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;약함~중간&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;k-anonymity 개선판, 실전 여전히 어려움&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Differential Privacy&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;강함, 정량&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Composition 성질, 미래 공격에 대비&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Secure Multi-Party Computation (MPC)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;강함&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;계산 자체는 정확, 프로토콜 비용 큼&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Homomorphic Encryption (HE)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;강함&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;암호화 상태 계산, 매우 느림&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Federated Learning&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;자체 보장 없음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Gradient inversion 취약, DP 와 결합 필요&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;DP + FL + Secure Aggregation&lt;/strong&gt; 조합이 실무의 표준 강화 스택입니다.&lt;/p&gt;
&lt;h2 id=&quot;참고&quot;&gt;참고&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;관련 [[federated-learning|Federated Learning]] 에 DP 를 결합한 학습&lt;/li&gt;
&lt;li&gt;관련 [[transfer-learning|Transfer Learning]] 파인튜닝 시 DP-SGD 로 개인정보 보호&lt;/li&gt;
&lt;li&gt;관련 [[classification-metrics|분류 모델 지표]] DP 학습 모델도 동일 지표로 평가&lt;/li&gt;
&lt;li&gt;정본 교과서: &lt;a href=&quot;https://www.cis.upenn.edu/~aaroth/Papers/privacybook.pdf&quot;&gt;Dwork &amp;#x26; Roth 2014, The Algorithmic Foundations of Differential Privacy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Wikipedia: &lt;a href=&quot;https://en.wikipedia.org/wiki/Differential_privacy&quot;&gt;Differential privacy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;강의 자료: &lt;a href=&quot;https://cs-people.bu.edu/ads22/pubs/lecture-notes-dp.pdf&quot;&gt;Boston University CS 591&lt;/a&gt;, &lt;a href=&quot;https://opendp.org/learning&quot;&gt;Harvard OpenDP&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ml</category><category>privacy</category><category>security</category><category>cryptography</category><category>dp</category><author>koa (김신건)</author></item><item><title>Federated Learning: 분산 학습 without central data</title><link>https://shinkeonkim.com/wiki/ml/federated-learning/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ml/federated-learning/</guid><pubDate>Mon, 29 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Federated Learning (FL)&lt;/strong&gt; 은 데이터를 &lt;strong&gt;중앙에 모으지 않고&lt;/strong&gt; 각 클라이언트 (edge device, 병원, 은행 등) 가 로컬 데이터로 모델을 학습한 뒤 &lt;strong&gt;모델 파라미터의 업데이트 (gradient 또는 weight)&lt;/strong&gt; 만 서버에 전송하여 집계하는 분산 학습 패러다임입니다. 서버는 원본 데이터를 절대 보지 않습니다.&lt;/p&gt;
&lt;p&gt;Google 이 2016~2017년경 Gboard (Android 키보드) 의 다음 단어 예측 학습을 위해 이 패러다임을 대중화했습니다.&lt;/p&gt;
&lt;h2 id=&quot;왜-필요한가&quot;&gt;왜 필요한가&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;개인정보 보호 규정&lt;/strong&gt;: GDPR (EU), HIPAA (US 의료), 국내 개인정보보호법 등이 원시 데이터의 외부 반출을 제한합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;데이터 주권&lt;/strong&gt;: 병원 / 금융사 등 규제 산업의 데이터는 기관 내부에 머물러야 하는 경우가 많습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;엣지 컴퓨팅&lt;/strong&gt;: 모바일/IoT 에서 데이터를 서버로 계속 전송하기엔 대역폭이 부담입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;콜드 데이터&lt;/strong&gt;: 사용자 로컬에만 존재하는 데이터 (키보드 입력, 사진) 는 애초에 서버로 가지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;fedavg-기본-알고리즘&quot;&gt;FedAvg, 기본 알고리즘&lt;/h2&gt;
&lt;p&gt;McMahan et al. (2017) 의 &lt;strong&gt;FedAvg (Federated Averaging)&lt;/strong&gt; 는 FL 의 원형입니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;서버 라운드 $t$&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;서버는 현재 글로벌 모델 $w_t$ 를 가지고 있습니다.&lt;/li&gt;
&lt;li&gt;서버가 $K$ 개 클라이언트를 샘플링 (전체 $N$ 개 중 일부만) 하고 $w_t$ 를 전송합니다.&lt;/li&gt;
&lt;li&gt;각 클라이언트 $k$ 는 로컬 데이터 $D_k$ 에서 $E$ epoch 만큼 SGD 를 돌려 $w_k^{t+1}$ 을 얻습니다.&lt;/li&gt;
&lt;li&gt;클라이언트가 $w_k^{t+1}$ 을 서버에 전송합니다.&lt;/li&gt;
&lt;li&gt;서버가 &lt;strong&gt;가중 평균&lt;/strong&gt;:
$$
w_{t+1} = \sum_{k=1}^{K} \frac{n_k}{n} \cdot w_k^{t+1}
$$
여기서 $n_k$ 는 클라이언트 $k$ 의 데이터 개수, $n = \sum n_k$ 입니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;수백 라운드를 반복하며 글로벌 모델이 수렴합니다.&lt;/p&gt;
&lt;h3 id=&quot;왜-그냥-gradient-를-보내지-않는가&quot;&gt;왜 그냥 gradient 를 보내지 않는가&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;FedSGD&lt;/strong&gt; (1 step gradient 만 보내는 방식) 도 가능하지만 통신량이 많아집니다. FedAvg 는 &lt;strong&gt;로컬에서 여러 epoch 을 돌리고 나서 weight 을 보내므로 통신 횟수를 크게 줄입니다&lt;/strong&gt; (핵심 통찰).&lt;/p&gt;
&lt;h2 id=&quot;배포-유형&quot;&gt;배포 유형&lt;/h2&gt;
&lt;h3 id=&quot;cross-device-fl&quot;&gt;Cross-device FL&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;수백만 ~ 수억 대의 모바일/IoT 기기&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;각 기기의 데이터는 소량 (수~수백 샘플)&lt;/li&gt;
&lt;li&gt;기기의 가용성은 불안정 (배터리, 네트워크)&lt;/li&gt;
&lt;li&gt;실제 예: &lt;strong&gt;Google Gboard&lt;/strong&gt;, &lt;strong&gt;Apple Siri&lt;/strong&gt;, &lt;strong&gt;Meta Ranking&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Sampling 이 필수 (한 라운드에 전체 클라이언트 대상 불가능)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;cross-silo-fl&quot;&gt;Cross-silo FL&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;소수 (2~100 개) 의 신뢰할 수 있는 기관&lt;/strong&gt; (병원, 은행)&lt;/li&gt;
&lt;li&gt;각 사일로의 데이터는 대량&lt;/li&gt;
&lt;li&gt;통신 인프라 안정적&lt;/li&gt;
&lt;li&gt;실제 예: &lt;strong&gt;NVIDIA Clara&lt;/strong&gt; (병원간 의료 영상), &lt;strong&gt;WeBank FATE&lt;/strong&gt; (금융 컨소시엄)&lt;/li&gt;
&lt;li&gt;모든 사일로가 매 라운드 참여 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;주요-도전-과제&quot;&gt;주요 도전 과제&lt;/h2&gt;
&lt;h3 id=&quot;1-non-iid-데이터-statistical-heterogeneity&quot;&gt;1. Non-IID 데이터 (Statistical Heterogeneity)&lt;/h3&gt;
&lt;p&gt;클라이언트마다 데이터 분포가 다릅니다. 예: 어떤 사용자는 영어로만, 어떤 사용자는 한국어로만 타이핑. 이 경우:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;각 클라이언트의 local update 가 서로 다른 방향을 가리킴 (&lt;strong&gt;client drift&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;단순 평균이 잘못된 방향으로 이동&lt;/li&gt;
&lt;li&gt;수렴 속도 저하, 최종 성능 하락&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;2-system-heterogeneity&quot;&gt;2. System Heterogeneity&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;클라이언트마다 컴퓨팅 성능 다름 (고사양 폰 vs 저사양 폰)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Straggler&lt;/strong&gt;: 느린 클라이언트 때문에 라운드가 지연됨&lt;/li&gt;
&lt;li&gt;배터리, 네트워크 상태로 라운드 중 이탈 (&lt;strong&gt;client dropout&lt;/strong&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-communication-cost&quot;&gt;3. Communication Cost&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;대형 모델 (수 GB) 을 매 라운드 수백만 클라이언트가 다운로드/업로드&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Model compression&lt;/strong&gt;, &lt;strong&gt;quantization&lt;/strong&gt;, &lt;strong&gt;sparsification&lt;/strong&gt; 으로 완화&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FetchSGD&lt;/strong&gt;, &lt;strong&gt;top-K sparsification&lt;/strong&gt; 등 통신 최적화 알고리즘&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;4-privacy-공격&quot;&gt;4. Privacy 공격&lt;/h3&gt;
&lt;p&gt;Raw 데이터를 보내지 않아도 gradient 자체에서 정보가 새어 나올 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Gradient inversion&lt;/strong&gt;: gradient 로부터 원본 이미지 복원 (Zhu et al., 2019 “Deep Leakage from Gradients”)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Membership inference&lt;/strong&gt;: 특정 샘플이 학습에 쓰였는지 추론&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;FL 만으로는 프라이버시가 보장되지 않으며, DP 나 Secure Aggregation 을 함께 써야 합니다.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;주요-변형&quot;&gt;주요 변형&lt;/h2&gt;
&lt;h3 id=&quot;fedprox-li-et-al-2020&quot;&gt;FedProx (Li et al., 2020)&lt;/h3&gt;
&lt;p&gt;Non-IID 대응. 로컬 objective 에 &lt;strong&gt;proximal term&lt;/strong&gt; 추가:&lt;/p&gt;
&lt;p&gt;$$
\min_{w} F_k(w) + \frac{\mu}{2} | w - w_t |^2
$$&lt;/p&gt;
&lt;p&gt;$\mu$ 는 하이퍼파라미터. 로컬 업데이트가 글로벌 모델에서 너무 멀리 벗어나지 못하도록 제약. Client drift 완화.&lt;/p&gt;
&lt;h3 id=&quot;fedyogi--fedadam-reddi-et-al-2020&quot;&gt;FedYogi / FedAdam (Reddi et al., 2020)&lt;/h3&gt;
&lt;p&gt;서버에서 &lt;strong&gt;adaptive optimizer&lt;/strong&gt; 사용. FedAvg 는 서버측에서 단순 평균이지만, FedYogi 는 Yogi (Adam 변형) 를 서버에 적용해 수렴을 안정화합니다.&lt;/p&gt;
&lt;h3 id=&quot;scaffold-karimireddy-et-al-2020&quot;&gt;SCAFFOLD (Karimireddy et al., 2020)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Control variate&lt;/strong&gt; 를 도입하여 client drift 를 correction. 클라이언트가 로컬 gradient 방향을 조정하는 벡터 $c_k$ 를 관리:&lt;/p&gt;
&lt;p&gt;$$
w_k \leftarrow w_k - \eta (g_k - c_k + c)
$$&lt;/p&gt;
&lt;p&gt;Non-IID 에서 FedAvg 보다 훨씬 빨리 수렴.&lt;/p&gt;
&lt;h3 id=&quot;개인화-fl-personalized-fl&quot;&gt;개인화 FL (Personalized FL)&lt;/h3&gt;
&lt;p&gt;모든 클라이언트가 같은 글로벌 모델을 쓰는 대신, &lt;strong&gt;글로벌 모델 + 로컬 튜닝&lt;/strong&gt; 형태:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Per-FedAvg&lt;/strong&gt;: MAML 계열, 글로벌 모델을 각 클라이언트가 한 step 파인튜닝&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pFedMe&lt;/strong&gt;: 클라이언트가 자기 모델 + 정규화 (글로벌 근처)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ditto&lt;/strong&gt;: 글로벌 + 개인 모델 병존, 두 목적을 함께 최적화&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;privacy-enhancing-techniques&quot;&gt;Privacy-Enhancing Techniques&lt;/h2&gt;
&lt;h3 id=&quot;differential-privacy-dp&quot;&gt;Differential Privacy (DP)&lt;/h3&gt;
&lt;p&gt;Gradient/weight 에 &lt;strong&gt;calibrated noise&lt;/strong&gt; 를 추가하여, 특정 개인의 데이터가 있었는지 확률적으로 알 수 없게 만듭니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DP-SGD&lt;/strong&gt; (Abadi et al., 2016):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Gradient 를 클립 (norm 상한 $C$)&lt;/li&gt;
&lt;li&gt;Gaussian noise $\mathcal{N}(0, \sigma^2 C^2)$ 추가&lt;/li&gt;
&lt;li&gt;Privacy budget $(\epsilon, \delta)$ 로 정량 관리&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;FL 에서는 &lt;strong&gt;client-level DP&lt;/strong&gt; (한 클라이언트 전체가 있었는지 감추기) 와 &lt;strong&gt;sample-level DP&lt;/strong&gt; (한 샘플이 있었는지 감추기) 두 가지 granularity 가 있습니다.&lt;/p&gt;
&lt;h3 id=&quot;secure-aggregation&quot;&gt;Secure Aggregation&lt;/h3&gt;
&lt;p&gt;Bonawitz et al. (2017) 의 프로토콜. 클라이언트들이 자기 업데이트를 &lt;strong&gt;cryptographic masking&lt;/strong&gt; 으로 감춰서 서버가 볼 때는 &lt;strong&gt;합만&lt;/strong&gt; 보이고 개별 값은 못 봅니다.&lt;/p&gt;
&lt;p&gt;핵심 아이디어: 클라이언트 쌍 사이에 secret share 를 교환하여 서로의 mask 가 합쳐지면 상쇄되도록 설계. Dropout 이 발생해도 threshold secret sharing 으로 복구 가능합니다.&lt;/p&gt;
&lt;h3 id=&quot;homomorphic-encryption-he&quot;&gt;Homomorphic Encryption (HE)&lt;/h3&gt;
&lt;p&gt;암호화된 상태로 덧셈/곱셈 연산 가능. Gradient 를 암호화한 채로 서버가 집계, 클라이언트만 복호화. 계산 비용이 매우 크지만 강력한 프라이버시 보장.&lt;/p&gt;
&lt;h2 id=&quot;프레임워크&quot;&gt;프레임워크&lt;/h2&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;프레임워크&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;개발/유지&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;특징&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://flower.dev/&quot;&gt;Flower&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;오픈소스 (Adap)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;프레임워크 애그노스틱 (PyTorch, TF, JAX), 실전 배포 지향&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://www.tensorflow.org/federated&quot;&gt;TensorFlow Federated (TFF)&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Google&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;시뮬레이션 중심, Federated Analytics 강점&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/OpenMined/PySyft&quot;&gt;PySyft&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;OpenMined&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;프라이버시 도구 통합 (HE, MPC, DP)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://fate.fedai.org/&quot;&gt;FATE&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;WeBank&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Cross-silo 산업용, Chinese fintech 배포 사례 다수&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/NVIDIA/NVFlare&quot;&gt;NVFlare&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;NVIDIA&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Clara/의료 도메인, 프로덕션 지향&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://fedml.ai/&quot;&gt;FedML&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;FedML Inc.&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;학술 + 산업 겸용 플랫폼&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;실전-코드-flower-예시&quot;&gt;실전 코드 (Flower 예시)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; flwr &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; fl&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; torch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 클라이언트 정의&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; MyClient&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;fl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;NumPyClient&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; get_parameters&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(self, config):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [p.detach().cpu().numpy() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; p &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; model.parameters()]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; set_parameters&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(self, parameters):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; p, new &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; zip&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(model.parameters(), parameters):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            p.data &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; torch.tensor(new)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fit&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(self, parameters, config):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.set_parameters(parameters)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        train(model, local_dataloader, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;epochs&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;config[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;local_epochs&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.get_parameters({}), &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(local_dataset), {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; evaluate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(self, parameters, config):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.set_parameters(parameters)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        loss, acc &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; test(model, val_dataloader)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; float&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(loss), &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(val_dataset), {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;accuracy&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: acc}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;fl.client.start_numpy_client(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;server_address&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;server:8080&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;MyClient())&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 서버 정의&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;strategy &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; fl.server.strategy.FedAvg(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    fraction_fit&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,          &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 매 라운드 10% 샘플링&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    min_fit_clients&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    min_available_clients&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    on_fit_config_fn&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=lambda&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; rnd: {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;local_epochs&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;fl.server.start_server(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    server_address&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0.0.0.0:8080&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    config&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;fl.server.ServerConfig(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;num_rounds&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    strategy&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;strategy,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;실전-배포-사례&quot;&gt;실전 배포 사례&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Google Gboard&lt;/strong&gt;: 다음 단어 예측, 이모지 추천 모두 FL 로 학습 (2017~)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple&lt;/strong&gt;: Differential Privacy 기반 Emoji 추천, Siri 개선&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NVIDIA Clara&lt;/strong&gt;: COVID-19 흉부 CT 진단 모델을 30 개 병원 협업 학습 (2020)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WeBank FATE&lt;/strong&gt;: 은행간 신용평가 모델&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Meta&lt;/strong&gt;: 광고 랭킹 모델의 프라이버시 강화 학습&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;한계와-유의점&quot;&gt;한계와 유의점&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;극심한 non-IID&lt;/strong&gt; 에서는 개인화 FL 을 쓰거나 centralized 로 회귀하는 것이 낫습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;모델 성능&lt;/strong&gt; 은 대개 centralized 대비 몇% 낮습니다. 프라이버시 규제 만족이 목적일 때 받아들일 만한 트레이드오프입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;디버깅이 어렵습니다&lt;/strong&gt;. 클라이언트 데이터를 볼 수 없으므로 로컬 이슈 진단이 힘듭니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;공격 모델을 명시&lt;/strong&gt; 해야 합니다. Honest-but-curious 서버 vs malicious 서버, 개별 클라이언트 vs 담합 공격 등.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;참고&quot;&gt;참고&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;관련 [[differential-privacy|Differential Privacy]] 를 결합하면 client-level / sample-level 프라이버시가 정량 보장됩니다&lt;/li&gt;
&lt;li&gt;관련 [[transfer-learning|Transfer Learning]] 을 클라이언트별 개인화에 결합하기도 합니다&lt;/li&gt;
&lt;li&gt;관련 [[classification-metrics|분류 모델 지표]] 로 각 라운드 성능 평가&lt;/li&gt;
&lt;li&gt;Google AI Blog: &lt;a href=&quot;https://ai.googleblog.com/2017/04/federated-learning-collaborative.html&quot;&gt;Federated Learning: Collaborative Machine Learning without Centralized Training Data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Kairouz et al. 2021, &lt;a href=&quot;https://arxiv.org/abs/1912.04977&quot;&gt;Advances and Open Problems in Federated Learning&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ml</category><category>distributed</category><category>privacy</category><category>federated-learning</category><category>edge</category><author>koa (김신건)</author></item><item><title>GPU: 그래픽/ML 병렬 프로세서</title><link>https://shinkeonkim.com/wiki/ml/gpu/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ml/gpu/</guid><pubDate>Mon, 29 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;GPU (Graphics Processing Unit)&lt;/strong&gt; 는 원래 그래픽 렌더링용이었지만, &lt;strong&gt;massively parallel&lt;/strong&gt; 아키텍처가 딥러닝과 HPC 에도 이상적. NVIDIA, AMD, Intel 이 3 대 제조사.&lt;/p&gt;
&lt;h2 id=&quot;아키텍처-개요&quot;&gt;아키텍처 개요&lt;/h2&gt;
&lt;h3 id=&quot;streaming-multiprocessor-sm&quot;&gt;Streaming Multiprocessor (SM)&lt;/h3&gt;
&lt;p&gt;NVIDIA GPU 의 병렬 유닛. 각 SM 은 수십~수백 개 CUDA 코어 + 공유 메모리 + register file.&lt;/p&gt;
&lt;p&gt;H100 (Hopper): 132 개 SM × 128 FP32 코어 = 16896 CUDA cores.&lt;/p&gt;
&lt;h3 id=&quot;simt-single-instruction-multiple-thread&quot;&gt;SIMT (Single Instruction Multiple Thread)&lt;/h3&gt;
&lt;p&gt;Warp (32 스레드) 단위로 같은 명령 실행. Warp 내부는 SIMD 유사, warp 간은 독립.&lt;/p&gt;
&lt;h2 id=&quot;메모리-계층&quot;&gt;메모리 계층&lt;/h2&gt;









































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;층&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;크기&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;지연&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;대역폭&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Register&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;스레드별&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~1 cycle&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;최고&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Shared memory&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;SM 당 ~100KB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~1 cycle&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;매우 높음&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;L1 cache&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;SM 당&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~10 cycles&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;높음&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;L2 cache&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;GPU 전체&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~200 cycles&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;중간&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Global memory (HBM)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;40-80 GB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~500 cycles&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;~3 TB/s (H100)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;딥러닝-특화&quot;&gt;딥러닝 특화&lt;/h2&gt;
&lt;h3 id=&quot;tensor-core&quot;&gt;Tensor Core&lt;/h3&gt;
&lt;p&gt;행렬곱 전용 유닛. FP16/BF16/FP8 지원. Ampere+ 는 sparse tensor 지원.&lt;/p&gt;
&lt;h3 id=&quot;정밀도&quot;&gt;정밀도&lt;/h3&gt;
&lt;p&gt;FP32 → FP16/BF16 → FP8 → INT8/INT4.
낮은 정밀도 = 큰 처리량 + 낮은 메모리. &lt;strong&gt;혼합 정밀도 학습&lt;/strong&gt; (mixed precision) 이 표준.&lt;/p&gt;
&lt;h2 id=&quot;세대&quot;&gt;세대&lt;/h2&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;center&quot;&gt;년도&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;NVIDIA&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;AMD&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;2020&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;A100 (Ampere)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;MI100&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;2022&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;H100 (Hopper)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;MI250&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;2024&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;B200 (Blackwell)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;MI300X&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;소프트웨어-스택&quot;&gt;소프트웨어 스택&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CUDA&lt;/strong&gt;: NVIDIA 독점 API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PyTorch, TensorFlow, JAX&lt;/strong&gt;: CUDA/ROCm/XLA 기반&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Triton (OpenAI)&lt;/strong&gt;: Python 에서 CUDA 커널 작성&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;cuDNN, cuBLAS&lt;/strong&gt;: NVIDIA 최적화 라이브러리&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ROCm&lt;/strong&gt;: AMD 대응 스택&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;참고&quot;&gt;참고&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[tpu|TPU]]&lt;/li&gt;
&lt;li&gt;[[npu|NPU]]&lt;/li&gt;
&lt;li&gt;[[hbm|HBM]]&lt;/li&gt;
&lt;li&gt;[[simt|SIMT]]&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ml</category><category>hardware</category><category>gpu</category><category>cuda</category><author>koa (김신건)</author></item><item><title>NPU (Neural Processing Unit): 엣지 AI 칩</title><link>https://shinkeonkim.com/wiki/ml/npu/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ml/npu/</guid><pubDate>Mon, 29 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;NPU (Neural Processing Unit)&lt;/strong&gt; 는 모바일/엣지 디바이스용 저전력 AI 가속기. 스마트폰, 노트북, IoT 에 내장.&lt;/p&gt;
&lt;h2 id=&quot;특징&quot;&gt;특징&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;저전력&lt;/strong&gt;: 배터리 구동 (수 W ~ 수십 W)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;정수 연산 위주&lt;/strong&gt;: INT8, INT4 로 추론 최적화&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;온디바이스 추론&lt;/strong&gt;: 개인정보 보호, 지연시간 낮음&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;대표-npu&quot;&gt;대표 NPU&lt;/h2&gt;
&lt;h3 id=&quot;스마트폰&quot;&gt;스마트폰&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Apple Neural Engine (ANE)&lt;/strong&gt;: A11 (2017) 부터, M-series 도 내장. 15.8 TOPS (A16).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Qualcomm Hexagon&lt;/strong&gt;: Snapdragon 내장&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google Tensor&lt;/strong&gt;: Pixel 시리즈, TPU 아키텍처 계승&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;pc&quot;&gt;PC&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Intel NPU (Meteor Lake+, 2024)&lt;/strong&gt;: 저전력 AI 워크로드 처리&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AMD XDNA&lt;/strong&gt;: Ryzen AI 라인&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple Silicon&lt;/strong&gt;: M-series 내장 ANE&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;자율주행--로봇&quot;&gt;자율주행 / 로봇&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NVIDIA Jetson&lt;/strong&gt;: 엣지 서버급&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google Coral (Edge TPU)&lt;/strong&gt;: USB / M.2 형태&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;gpu-와의-차이&quot;&gt;GPU 와의 차이&lt;/h2&gt;






























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;항목&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;GPU&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;NPU&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;유연성&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;학습 + 추론&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;추론 위주&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;정밀도&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;FP16/32 학습&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;INT4/8 추론&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;전력&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;100-700W&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;1-20W&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;지연시간&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;배치 대기&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;즉각 처리&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;사용&quot;&gt;사용&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;얼굴 인식&lt;/strong&gt; (Face ID)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;사진 처리&lt;/strong&gt; (Portrait mode, Deep Fusion)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;음성 인식&lt;/strong&gt; (Siri, Google Assistant 온디바이스)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;실시간 번역&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM 온디바이스&lt;/strong&gt; (Apple Intelligence, Copilot+)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;참고&quot;&gt;참고&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[tpu|TPU]]&lt;/li&gt;
&lt;li&gt;[[gpu|GPU]]&lt;/li&gt;
&lt;li&gt;[[quantization|Quantization]]&lt;/li&gt;
&lt;li&gt;[[federated-learning|Federated Learning]]&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ml</category><category>hardware</category><category>npu</category><category>edge</category><author>koa (김신건)</author></item><item><title>TPU (Tensor Processing Unit): Google 의 ML ASIC</title><link>https://shinkeonkim.com/wiki/ml/tpu/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ml/tpu/</guid><pubDate>Mon, 29 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;TPU (Tensor Processing Unit)&lt;/strong&gt; 는 Google 이 딥러닝 워크로드용으로 만든 &lt;strong&gt;ASIC (application-specific IC)&lt;/strong&gt;. 2015 년 v1 (추론용), 2017 년 v2 (학습 지원) 발표.&lt;/p&gt;
&lt;h2 id=&quot;핵심-아키텍처&quot;&gt;핵심 아키텍처&lt;/h2&gt;
&lt;h3 id=&quot;systolic-array&quot;&gt;Systolic Array&lt;/h3&gt;
&lt;p&gt;[[systolic-array|Systolic Array]] 를 이용한 대규모 병렬 행렬곱. TPU v4 는 128×128 행렬곱 유닛.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;데이터가 배열을 통과하며 곱셈-누산&lt;/li&gt;
&lt;li&gt;캐시/DRAM 접근 최소화 → &lt;strong&gt;에너지 효율 극대화&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;bfloat16&quot;&gt;bfloat16&lt;/h3&gt;
&lt;p&gt;FP32 exponent + FP16 mantissa. 학습 안정성 유지하며 대역폭 절반.&lt;/p&gt;
&lt;h2 id=&quot;세대&quot;&gt;세대&lt;/h2&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;세대&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;년도&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;특징&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;v1&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;2015&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;추론 전용, INT8&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;v2&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;2017&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;학습 지원, HBM&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;v3&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;2018&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;액체 냉각&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;v4&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;2021&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;4096 chip pod, OCS 상호연결&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;v5e / v5p&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;2023&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;비용/성능 두 트랙&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Trillium (v6)&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;2024&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;5x 컴퓨트 vs v5e&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;tpu-pod&quot;&gt;TPU Pod&lt;/h2&gt;
&lt;p&gt;여러 TPU 를 고속 인터커넥트로 묶은 단위. v4 는 최대 4096 칩 pod, exaflops 급 컴퓨트.&lt;/p&gt;
&lt;h2 id=&quot;사용&quot;&gt;사용&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Google Cloud TPU&lt;/strong&gt;: &lt;code&gt;gcloud compute tpus&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JAX + XLA&lt;/strong&gt;: 표준 스택&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TensorFlow / PyTorch/XLA&lt;/strong&gt;: 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;gpu-와-비교&quot;&gt;GPU 와 비교&lt;/h2&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;항목&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;GPU&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;TPU&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;유연성&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;높음 (그래픽, HPC, ML)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;ML 특화&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;소프트웨어&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;CUDA 광범위&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;XLA 중심&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;병렬 방식&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;SIMT&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Systolic array&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;지연시간&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;낮음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;배치 대기&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;접근성&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;광범위 (AWS, on-prem)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;GCP 만&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;참고&quot;&gt;참고&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[gpu|GPU]]&lt;/li&gt;
&lt;li&gt;[[npu|NPU]]&lt;/li&gt;
&lt;li&gt;[[systolic-array|Systolic Array]]&lt;/li&gt;
&lt;li&gt;[[distributed-training|Distributed Training]]&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ml</category><category>hardware</category><category>tpu</category><category>google</category><author>koa (김신건)</author></item><item><title>Transfer Learning: pre-training, fine-tuning, domain adaptation</title><link>https://shinkeonkim.com/wiki/ml/transfer-learning/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ml/transfer-learning/</guid><pubDate>Mon, 29 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Transfer Learning&lt;/strong&gt; 은 &lt;strong&gt;source task/domain 에서 학습한 지식을 target task/domain 에 재사용&lt;/strong&gt; 하여 학습 효율을 높이는 패러다임입니다. 대규모 데이터로 사전 학습한 모델을 소량의 태스크 특화 데이터로 미세 조정하는 것이 대표적입니다.&lt;/p&gt;
&lt;p&gt;핵심 가정: &lt;strong&gt;저수준 특징 (edge, syllable, phoneme) 은 대체로 도메인/태스크에 관계없이 유용하다.&lt;/strong&gt; 이 가정이 성립할 때 처음부터 학습하는 것보다 훨씬 적은 데이터와 시간으로 좋은 성능을 얻을 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;왜-필요한가&quot;&gt;왜 필요한가&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;데이터 부족&lt;/strong&gt;: target task 데이터가 수천 개인데 처음부터 CNN/Transformer 를 학습하면 과적합 심함&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;계산 비용&lt;/strong&gt;: LLM 을 처음부터 학습하는 것은 조 단위 예산이 필요, 사전 학습 모델 재사용이 현실적&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;범용 표현 학습&lt;/strong&gt;: ImageNet 이나 대규모 웹 코퍼스로 학습한 표현은 이후 대부분의 downstream 태스크에 유용&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;고전-분류-pan--yang-2010&quot;&gt;고전 분류 (Pan &amp;#x26; Yang, 2010)&lt;/h2&gt;
&lt;p&gt;Source 와 target 의 &lt;strong&gt;도메인 (input 분포)&lt;/strong&gt; 과 &lt;strong&gt;태스크 (output/label)&lt;/strong&gt; 차이 여부에 따라:&lt;/p&gt;





































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;유형&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;Source 도메인&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;Source 태스크&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;Target 도메인&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;Target 태스크&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;예&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Inductive Transfer&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;같음/유사&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;다름&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;같음&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;다름 (라벨 있음)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;ImageNet 분류 → 의료 영상 분류&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Transductive Transfer (Domain Adaptation)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;다름&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;같음&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;다름&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;같음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;서구인 얼굴 인식 → 아시아인 얼굴 인식&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Unsupervised Transfer&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;다름&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;다름&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;다름&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;다름 (라벨 없음)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;클러스터링 지식 전이&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;딥러닝 시대에는 이 구분이 흐려지고 있으며, 실질적으로는 &lt;strong&gt;“대규모 사전 학습 + downstream 파인튜닝”&lt;/strong&gt; 이라는 한 가지 패러다임이 지배적입니다.&lt;/p&gt;
&lt;h2 id=&quot;딥러닝-관점-레이어별-전이-가능성&quot;&gt;딥러닝 관점: 레이어별 전이 가능성&lt;/h2&gt;
&lt;p&gt;Yosinski et al. (2014) 는 AlexNet 의 각 레이어를 하나씩 얼려 (freeze) target 태스크에 옮기는 실험으로 다음을 밝혔습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;저수준 레이어 (conv1, conv2)&lt;/strong&gt;: 에지, 색깔 필터. &lt;strong&gt;일반적&lt;/strong&gt; 이라 대부분의 태스크에 잘 전이됩니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;중간 레이어&lt;/strong&gt;: 조각, 형태. &lt;strong&gt;부분적&lt;/strong&gt; 으로 전이됩니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;고수준 레이어 (fc7, fc8)&lt;/strong&gt;: 클래스 특화. 원본 태스크에 강하게 특화되어 있어 &lt;strong&gt;잘 전이되지 않습니다&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 통찰이 오늘날 대부분의 fine-tuning 전략의 근거입니다.&lt;/p&gt;
&lt;h2 id=&quot;fine-tuning-전략&quot;&gt;Fine-tuning 전략&lt;/h2&gt;
&lt;h3 id=&quot;1-feature-extractor&quot;&gt;1. Feature Extractor&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;사전 학습 모델 전체를 freeze&lt;/strong&gt;, 마지막에 새 head (선형 분류기) 만 학습합니다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; torch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; torchvision.models &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; resnet50&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; resnet50(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;weights&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;IMAGENET1K_V2&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; p &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; model.parameters():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    p.requires_grad &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; False&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 새 head&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model.fc &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; torch.nn.Linear(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2048&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, num_target_classes)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# model.fc.parameters() 만 학습&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;데이터가 극히 적을 때 유리&lt;/li&gt;
&lt;li&gt;학습 빠르고 안정적이지만 성능 상한이 낮음&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;2-full-fine-tuning&quot;&gt;2. Full Fine-tuning&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;모든 파라미터를 학습&lt;/strong&gt;, 다만 작은 learning rate (예: 1e-5) 사용.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; p &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; model.parameters():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    p.requires_grad &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; True&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;optimizer &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; torch.optim.AdamW(model.parameters(), &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;lr&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1e-5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;데이터가 충분할 때 최고 성능&lt;/li&gt;
&lt;li&gt;대신 catastrophic forgetting 위험 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-discriminative-fine-tuning-ulmfit&quot;&gt;3. Discriminative Fine-tuning (ULMFiT)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;레이어별로 다른 learning rate&lt;/strong&gt;. 낮은 레이어는 작은 LR, 높은 레이어는 큰 LR.&lt;/p&gt;
&lt;p&gt;$$
\eta^{(l-1)} = \eta^{(l)} / 2.6
$$&lt;/p&gt;
&lt;p&gt;Howard &amp;#x26; Ruder (2018) 이 ULMFiT 에서 제안했고, NLP 파인튜닝의 기준이 되었습니다.&lt;/p&gt;
&lt;h3 id=&quot;4-gradual-unfreezing&quot;&gt;4. Gradual Unfreezing&lt;/h3&gt;
&lt;p&gt;먼저 head 만 학습 (다른 레이어 freeze), 그 다음 마지막 레이어를 unfreeze, 그 다음 그 아래 레이어를 unfreeze 하는 식으로 &lt;strong&gt;레이어별로 서서히 녹입니다&lt;/strong&gt;. Catastrophic forgetting 완화에 효과적입니다.&lt;/p&gt;
&lt;h2 id=&quot;foundation-models&quot;&gt;Foundation Models&lt;/h2&gt;
&lt;p&gt;Bommasani et al. (2021) 는 다음 조건을 만족하는 모델을 &lt;strong&gt;Foundation Model&lt;/strong&gt; 로 명명했습니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;대규모 self-supervised pre-training&lt;/li&gt;
&lt;li&gt;광범위한 downstream 태스크에 적응 가능&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;대표: &lt;strong&gt;BERT, GPT, T5, CLIP, ViT, DINO, SAM, LLaMA&lt;/strong&gt;. Transfer learning 이 이제 특별한 기법이 아니라 &lt;strong&gt;AI 시스템 구축의 기본 방식&lt;/strong&gt; 이 되었다는 관점 전환입니다.&lt;/p&gt;
&lt;h2 id=&quot;peft-parameter-efficient-fine-tuning&quot;&gt;PEFT (Parameter-Efficient Fine-Tuning)&lt;/h2&gt;
&lt;p&gt;Foundation model 이 수십억 파라미터 규모가 되면서 full fine-tuning 은 GPU 메모리도, 저장 공간도 감당하기 어려워졌습니다. &lt;strong&gt;일부 파라미터만 학습&lt;/strong&gt; 하는 기법들이 나왔습니다.&lt;/p&gt;
&lt;h3 id=&quot;adapter-houlsby-et-al-2019&quot;&gt;Adapter (Houlsby et al., 2019)&lt;/h3&gt;
&lt;p&gt;Transformer 블록 안에 &lt;strong&gt;작은 병목 레이어&lt;/strong&gt; 를 삽입, 원본 파라미터는 freeze, adapter 만 학습:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x → [Layer Norm] → [Attention] → [Add] → [Adapter (down → nonlinear → up)] → [FFN] → [Add] → [Adapter] → out&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;전체의 3~5% 정도만 학습해도 full fine-tuning 에 근접한 성능.&lt;/p&gt;
&lt;h3 id=&quot;lora-hu-et-al-2021&quot;&gt;LoRA (Hu et al., 2021)&lt;/h3&gt;
&lt;p&gt;가중치 업데이트 $\Delta W$ 를 &lt;strong&gt;low-rank 분해&lt;/strong&gt; 로 근사:&lt;/p&gt;
&lt;p&gt;$$
W’ = W + \Delta W = W + BA, \quad A \in \mathbb{R}^{r \times k}, B \in \mathbb{R}^{d \times r}
$$&lt;/p&gt;
&lt;p&gt;$r \ll \min(d, k)$ 이면 $BA$ 가 $\Delta W$ 를 근사합니다. 학습 파라미터는 $r(d+k)$ 개로 크게 줄어들고, inference 때는 $W + BA$ 를 병합하면 추가 지연이 없습니다. 오늘날 LLM 파인튜닝의 사실상 표준입니다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# peft 라이브러리 예&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; peft &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; LoraConfig, get_peft_model&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;config &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; LoraConfig(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    r&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,                          &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# rank&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    lora_alpha&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,                &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# scaling factor&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    target_modules&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;q_proj&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;v_proj&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    lora_dropout&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.05&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    bias&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;none&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; get_peft_model(base_model, config)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;QLoRA&lt;/strong&gt; (Dettmers et al., 2023) 는 4-bit 양자화 + LoRA 로 GPU 메모리를 더 줄였습니다.&lt;/p&gt;
&lt;h3 id=&quot;prompt-tuning--prefix-tuning&quot;&gt;Prompt Tuning / Prefix Tuning&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;모델은 완전 freeze&lt;/strong&gt;, 입력에 학습 가능한 &lt;strong&gt;soft token 벡터&lt;/strong&gt; 만 추가:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prompt Tuning&lt;/strong&gt; (Lester et al., 2021): 입력 앞에 학습 가능한 임베딩 몇 개 추가&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prefix Tuning&lt;/strong&gt; (Li &amp;#x26; Liang, 2021): 각 Transformer 레이어의 key/value 앞에 접두 벡터 삽입&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;파라미터 수가 극히 작지만 (&amp;#x3C; 0.1%) 매우 큰 모델에서만 효과적입니다.&lt;/p&gt;
&lt;h3 id=&quot;bitfit-ben-zaken-et-al-2021&quot;&gt;BitFit (Ben-Zaken et al., 2021)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;bias 파라미터만 학습&lt;/strong&gt;. 극단적으로 적은 파라미터로도 특정 태스크에서 경쟁력 있음.&lt;/p&gt;
&lt;h2 id=&quot;domain-adaptation&quot;&gt;Domain Adaptation&lt;/h2&gt;
&lt;p&gt;Source 와 target 의 &lt;strong&gt;입력 분포가 다를 때&lt;/strong&gt; 사용됩니다.&lt;/p&gt;
&lt;h3 id=&quot;feature-alignment&quot;&gt;Feature Alignment&lt;/h3&gt;
&lt;p&gt;두 도메인의 feature 분포를 정렬:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MMD (Maximum Mean Discrepancy)&lt;/strong&gt;: RKHS 에서 두 분포의 평균 벡터 거리 최소화&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CORAL (Correlation Alignment)&lt;/strong&gt;: 공분산 매트릭스 정렬&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;adversarial-domain-adaptation-dann&quot;&gt;Adversarial Domain Adaptation (DANN)&lt;/h3&gt;
&lt;p&gt;Ganin et al. (2015) 의 DANN 은 두 도메인의 feature 를 &lt;strong&gt;discriminator 가 구분 못하게&lt;/strong&gt; 학습시킵니다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;feature extractor → classifier (label 예측, 정상 gradient)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                 → domain discriminator (source vs target, gradient reversal)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Gradient Reversal Layer (GRL) 로 discriminator loss 의 gradient 를 뒤집어 feature 를 domain-invariant 하게 만듭니다.&lt;/p&gt;
&lt;h3 id=&quot;self-training--pseudo-labeling&quot;&gt;Self-training / Pseudo-labeling&lt;/h3&gt;
&lt;p&gt;Target 데이터의 라벨을 모델 예측으로 채우고 (confidence 높은 것만), 다시 학습. 반복.&lt;/p&gt;
&lt;h2 id=&quot;catastrophic-forgetting&quot;&gt;Catastrophic Forgetting&lt;/h2&gt;
&lt;p&gt;Fine-tuning 시 사전 학습에서 얻은 일반 지식이 &lt;strong&gt;소실&lt;/strong&gt; 되는 현상. 특히 target 데이터가 적을 때 심각합니다.&lt;/p&gt;
&lt;p&gt;완화 기법:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;작은 learning rate + 짧은 학습&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Elastic Weight Consolidation (EWC)&lt;/strong&gt; (Kirkpatrick et al., 2017): 원본 파라미터 근처에 머무르도록 L2-regularization, Fisher Information 으로 중요도 가중&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rehearsal&lt;/strong&gt;: 원본 태스크 샘플을 fine-tuning 중에도 계속 노출&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PEFT (adapter, LoRA)&lt;/strong&gt;: 원본 파라미터는 그대로 두므로 자연스럽게 forgetting 방지&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;negative-transfer&quot;&gt;Negative Transfer&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;source 와 target 이 관련 없으면 오히려 성능 하락&lt;/strong&gt;. 예: 자연 이미지 사전 학습 → 위성 이미지 태스크 는 도움이 되지만, 자연 이미지 사전 학습 → 의료 X-ray 태스크는 부정적 전이 사례가 알려져 있습니다.&lt;/p&gt;
&lt;p&gt;방지책:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Source 선택 시 domain similarity 검토 (feature 통계, MMD 로 측정)&lt;/li&gt;
&lt;li&gt;모델 여러 개 후보 중 target 검증으로 선택&lt;/li&gt;
&lt;li&gt;애매하면 사전 학습 도메인이 넓은 foundation model 사용 (CLIP, DINOv2 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;실전-예시&quot;&gt;실전 예시&lt;/h2&gt;
&lt;h3 id=&quot;nlp-bert-fine-tuning&quot;&gt;NLP: BERT fine-tuning&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; transformers &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; BertForSequenceClassification, Trainer, TrainingArguments&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; BertForSequenceClassification.from_pretrained(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;bert-base-uncased&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;num_labels&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;training_args &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; TrainingArguments(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    output_dir&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;./results&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    num_train_epochs&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    per_device_train_batch_size&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;16&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    learning_rate&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2e-5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,           &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# BERT paper 권장&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    warmup_steps&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;500&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    weight_decay&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.01&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;trainer &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Trainer(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;model&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;args&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;training_args, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;train_dataset&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ds, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;trainer.train()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;vision-vit-fine-tuning&quot;&gt;Vision: ViT fine-tuning&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; transformers &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ViTForImageClassification&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ViTForImageClassification.from_pretrained(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &quot;google/vit-base-patch16-224&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    num_labels&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;num_classes,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    ignore_mismatched_sizes&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 새 head 필요&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;llm-lora-fine-tuning&quot;&gt;LLM: LoRA fine-tuning&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; peft &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; LoraConfig, get_peft_model, TaskType&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;config &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; LoraConfig(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    task_type&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;TaskType.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;CAUSAL_LM&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    r&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;16&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    lora_alpha&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    lora_dropout&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    target_modules&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;q_proj&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;k_proj&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;v_proj&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;o_proj&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; get_peft_model(base_llm, config)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model.print_trainable_parameters()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# trainable: ~4M / total: ~7B (0.06%)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;참고&quot;&gt;참고&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;관련 지표: [[classification-metrics|분류 모델 지표]]&lt;/li&gt;
&lt;li&gt;관련 시스템: [[federated-learning|Federated Learning]] 에서도 pretrained model 을 초기점으로 씁니다&lt;/li&gt;
&lt;li&gt;관련 평가: [[helm-llm-benchmark|HELM]] 은 여러 downstream 태스크에서 foundation model 을 평가합니다&lt;/li&gt;
&lt;li&gt;HuggingFace: &lt;a href=&quot;https://github.com/huggingface/peft&quot;&gt;PEFT library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Paper: &lt;a href=&quot;https://arxiv.org/abs/2108.07258&quot;&gt;Bommasani et al. 2021, Foundation Models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Survey: &lt;a href=&quot;https://arxiv.org/abs/1911.02685&quot;&gt;A Comprehensive Survey on Transfer Learning&lt;/a&gt; (Zhuang et al., 2020)&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ml</category><category>deep-learning</category><category>transfer-learning</category><category>fine-tuning</category><category>foundation-model</category><author>koa (김신건)</author></item><item><title>분류 모델 지표: Confusion Matrix, Precision, Recall, F1</title><link>https://shinkeonkim.com/wiki/ml/classification-metrics/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ml/classification-metrics/</guid><pubDate>Mon, 29 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;분류 (classification) 모델의 성능을 정량화하는 지표들입니다. 이진 분류를 기준으로 하며, multi-class 로 확장하는 방법도 함께 다룹니다. 핵심 출발점은 &lt;strong&gt;Confusion Matrix&lt;/strong&gt; 이고, 여기서 accuracy, precision, recall, F1, ROC/PR 등 모든 지표가 유도됩니다.&lt;/p&gt;
&lt;h2 id=&quot;confusion-matrix&quot;&gt;Confusion Matrix&lt;/h2&gt;
&lt;p&gt;이진 분류의 예측 결과를 2x2 표로 정리한 것입니다. 스팸 필터를 예로 들면:&lt;/p&gt;




















&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;예측: Positive (스팸)&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;예측: Negative (정상)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;실제: Positive (스팸)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;strong&gt;TP&lt;/strong&gt; (True Positive)&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;strong&gt;FN&lt;/strong&gt; (False Negative)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;실제: Negative (정상)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;strong&gt;FP&lt;/strong&gt; (False Positive)&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;strong&gt;TN&lt;/strong&gt; (True Negative)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TP (True Positive)&lt;/strong&gt;: 스팸을 스팸이라고 맞춘 경우&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TN (True Negative)&lt;/strong&gt;: 정상을 정상이라고 맞춘 경우&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FP (False Positive)&lt;/strong&gt;: 정상을 스팸이라고 잘못 예측 (Type I error)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FN (False Negative)&lt;/strong&gt;: 스팸을 정상이라고 놓친 경우 (Type II error)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
&lt;strong&gt;First letter (T/F)&lt;/strong&gt; 은 예측이 맞았는가 (True/False), &lt;strong&gt;second letter (P/N)&lt;/strong&gt; 은 모델이 무엇으로 예측했는가 (Positive/Negative) 입니다. “FP = 모델은 Positive 라고 예측, 실제는 반대라 False” 로 읽으면 헷갈리지 않습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;기본-지표&quot;&gt;기본 지표&lt;/h2&gt;
&lt;h3 id=&quot;accuracy&quot;&gt;Accuracy&lt;/h3&gt;
&lt;p&gt;$$
\text{Accuracy} = \frac{TP + TN}{TP + TN + FP + FN}
$$&lt;/p&gt;
&lt;p&gt;전체 예측 중 맞은 비율. 직관적이지만 &lt;strong&gt;class imbalance&lt;/strong&gt; 에 취약합니다. 99% 정상 메일 데이터에서 “모두 정상” 이라고 예측해도 accuracy 99% 가 나옵니다.&lt;/p&gt;
&lt;h3 id=&quot;precision-정밀도&quot;&gt;Precision (정밀도)&lt;/h3&gt;
&lt;p&gt;$$
\text{Precision} = \frac{TP}{TP + FP}
$$&lt;/p&gt;
&lt;p&gt;모델이 Positive 라고 예측한 것 중 실제로 Positive 인 비율. “&lt;strong&gt;모델이 Positive 라고 외칠 때 얼마나 믿을 만한가?&lt;/strong&gt;”&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;스팸 필터: precision 낮으면 정상 메일이 스팸함으로 감 → 사용자 불만&lt;/li&gt;
&lt;li&gt;추천 시스템: precision 낮으면 관심 없는 상품 추천 → 이탈&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;recall-재현율-sensitivity-tpr&quot;&gt;Recall (재현율, Sensitivity, TPR)&lt;/h3&gt;
&lt;p&gt;$$
\text{Recall} = \frac{TP}{TP + FN}
$$&lt;/p&gt;
&lt;p&gt;실제 Positive 중 모델이 맞춘 비율. “&lt;strong&gt;진짜 Positive 를 얼마나 놓치지 않고 잡았는가?&lt;/strong&gt;”&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;암 진단: recall 낮으면 환자를 놓침 → 치명적&lt;/li&gt;
&lt;li&gt;이상 거래 탐지: recall 낮으면 사기를 놓침 → 손실&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;specificity-tnr&quot;&gt;Specificity (TNR)&lt;/h3&gt;
&lt;p&gt;$$
\text{Specificity} = \frac{TN}{TN + FP}
$$&lt;/p&gt;
&lt;p&gt;실제 Negative 중 Negative 로 맞춘 비율. 의료 통계에서 자주 쓰이며 ROC 곡선의 x 축을 구성합니다.&lt;/p&gt;
&lt;h2 id=&quot;precision-vs-recall-트레이드오프&quot;&gt;Precision vs Recall 트레이드오프&lt;/h2&gt;
&lt;p&gt;두 지표는 대체로 상충됩니다. 이유는 대부분의 확률 모델이 &lt;strong&gt;임계값 (threshold)&lt;/strong&gt; 에 따라 결정을 내리기 때문입니다. Threshold 를 낮추면 (더 많이 Positive 로 예측):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Recall ↑ (놓치는 것 감소)&lt;/li&gt;
&lt;li&gt;Precision ↓ (틀린 Positive 증가)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;반대로 threshold 를 높이면:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Precision ↑ (확신 있을 때만 Positive)&lt;/li&gt;
&lt;li&gt;Recall ↓ (놓치는 것 증가)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;어느 쪽을 우선할지는 도메인 비용 함수&lt;/strong&gt; 에 따라 다릅니다.&lt;/p&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;상황&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;우선 지표&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;이유&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;스팸 필터&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Precision&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;정상 메일 놓치는 비용 큼&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;추천 시스템&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Precision&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;관심 없는 추천은 사용자 피로&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;암 진단 스크리닝&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Recall&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;놓치는 비용 (사망) 극심&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;사기 탐지&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Recall&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;놓친 사기의 손실 큼&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;검색 랭킹&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Precision@K&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;상위 K 개만 노출됨&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;f1-score&quot;&gt;F1 Score&lt;/h2&gt;
&lt;p&gt;Precision 과 Recall 의 조화 평균 (harmonic mean):&lt;/p&gt;
&lt;p&gt;$$
F_1 = 2 \cdot \frac{\text{Precision} \cdot \text{Recall}}{\text{Precision} + \text{Recall}}
$$&lt;/p&gt;
&lt;p&gt;산술 평균 대신 조화 평균을 쓰는 이유는 &lt;strong&gt;한쪽이 극단적으로 낮을 때 벌점을 주기 위함&lt;/strong&gt; 입니다. Precision=1.0, Recall=0.01 이면 산술 평균은 0.505 지만 F1 은 0.0198 로 곤두박질칩니다.&lt;/p&gt;
&lt;h3 id=&quot;f-beta&quot;&gt;F-beta&lt;/h3&gt;
&lt;p&gt;Precision 과 Recall 을 다른 비중으로 가중:&lt;/p&gt;
&lt;p&gt;$$
F_\beta = (1 + \beta^2) \cdot \frac{P \cdot R}{\beta^2 \cdot P + R}
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\beta = 1$ → F1 (동일 가중)&lt;/li&gt;
&lt;li&gt;$\beta = 2$ → F2 (recall 을 2 배 중시)&lt;/li&gt;
&lt;li&gt;$\beta = 0.5$ → F0.5 (precision 을 2 배 중시)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$\beta$ 는 “recall 을 precision 대비 몇 배로 중요하게 보는가” 의 계수입니다.&lt;/p&gt;
&lt;h2 id=&quot;roc-곡선과-auc&quot;&gt;ROC 곡선과 AUC&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;ROC (Receiver Operating Characteristic) 곡선&lt;/strong&gt;: 다양한 threshold 에서 (FPR, TPR) 을 그린 곡선.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;x축: &lt;strong&gt;FPR&lt;/strong&gt; (False Positive Rate) = FP / (FP + TN) = 1 - Specificity&lt;/li&gt;
&lt;li&gt;y축: &lt;strong&gt;TPR&lt;/strong&gt; (True Positive Rate) = Recall&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;AUC-ROC&lt;/strong&gt; 는 이 곡선 아래 면적입니다. 0.5 는 random, 1.0 은 완벽. 직관적 해석: &lt;strong&gt;랜덤한 positive 샘플과 negative 샘플을 뽑았을 때, positive 샘플의 점수가 더 높을 확률&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;roc-의-한계-극심한-imbalance&quot;&gt;ROC 의 한계, 극심한 imbalance&lt;/h3&gt;
&lt;p&gt;Negative 가 압도적으로 많을 때 (예: 사기 거래 1% vs 정상 99%), FPR 이 0.01 만 되어도 절대 개수로는 엄청난 오탐입니다. 그러나 ROC 곡선은 FPR 을 %로 표현하므로 오탐의 심각성이 시각적으로 감춰집니다.&lt;/p&gt;
&lt;h2 id=&quot;pr-곡선과-auc-pr&quot;&gt;PR 곡선과 AUC-PR&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Precision-Recall 곡선&lt;/strong&gt;: threshold 별 (Recall, Precision) 을 그린 곡선.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AUC-PR&lt;/strong&gt; 은 그 아래 면적이며, &lt;strong&gt;imbalanced dataset 에서 ROC 보다 정보량이 많습니다&lt;/strong&gt; (&lt;a href=&quot;https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0118432&quot;&gt;Saito &amp;#x26; Rehmsmeier, 2015&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;경험칙:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;양쪽 클래스가 비슷하게 있음 → ROC/AUC 로 충분&lt;/li&gt;
&lt;li&gt;Positive 가 희소함 (예: &amp;#x3C;10%) → &lt;strong&gt;PR 곡선 / AUC-PR&lt;/strong&gt; 을 우선&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;multi-class-확장&quot;&gt;Multi-class 확장&lt;/h2&gt;
&lt;p&gt;이진의 precision/recall/F1 을 여러 클래스로 확장할 때 세 가지 평균 방식이 있습니다.&lt;/p&gt;
&lt;h3 id=&quot;macro-average&quot;&gt;Macro-average&lt;/h3&gt;
&lt;p&gt;각 클래스별 지표를 구한 뒤 &lt;strong&gt;단순 평균&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;$$
\text{Macro-F1} = \frac{1}{K} \sum_{k=1}^{K} F_1^{(k)}
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;각 클래스를 동등하게 취급&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;소수 클래스도 존중&lt;/strong&gt; 하고 싶을 때 적합&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;micro-average&quot;&gt;Micro-average&lt;/h3&gt;
&lt;p&gt;모든 클래스의 TP/FP/FN 을 먼저 합산하고 지표 계산:&lt;/p&gt;
&lt;p&gt;$$
\text{Micro-F1} = 2 \cdot \frac{\sum TP}{\sum TP + \sum FP + \sum FN}
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;전체 샘플을 동등하게 취급 (샘플 많은 클래스가 지배)&lt;/li&gt;
&lt;li&gt;Micro-F1 은 multi-class accuracy 와 같아집니다&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;weighted-average&quot;&gt;Weighted-average&lt;/h3&gt;
&lt;p&gt;각 클래스의 support (샘플 수) 로 가중 평균:&lt;/p&gt;
&lt;p&gt;$$
\text{Weighted-F1} = \sum_{k=1}^{K} \frac{n_k}{n} F_1^{(k)}
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;실제 분포를 반영&lt;/li&gt;
&lt;li&gt;다수 클래스가 편중된 경우 macro 대신 자주 쓰임&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;기타-지표&quot;&gt;기타 지표&lt;/h2&gt;
&lt;h3 id=&quot;cohens-kappa&quot;&gt;Cohen’s Kappa&lt;/h3&gt;
&lt;p&gt;우연히 맞을 확률을 보정한 accuracy:&lt;/p&gt;
&lt;p&gt;$$
\kappa = \frac{p_o - p_e}{1 - p_e}
$$&lt;/p&gt;
&lt;p&gt;$p_o$ 는 실제 관측 accuracy, $p_e$ 는 우연히 일치할 기대 확률. 클래스가 매우 불균형할 때 raw accuracy 보다 신뢰할 만합니다.&lt;/p&gt;
&lt;h3 id=&quot;matthews-correlation-coefficient-mcc&quot;&gt;Matthews Correlation Coefficient (MCC)&lt;/h3&gt;
&lt;p&gt;$$
\text{MCC} = \frac{TP \cdot TN - FP \cdot FN}{\sqrt{(TP+FP)(TP+FN)(TN+FP)(TN+FN)}}
$$&lt;/p&gt;
&lt;p&gt;-1 (완전 반대) ~ 0 (random) ~ 1 (완벽). Confusion Matrix 네 셀 모두를 반영하며, &lt;a href=&quot;https://bmcgenomics.biomedcentral.com/articles/10.1186/s12864-019-6413-7&quot;&gt;Chicco &amp;#x26; Jurman 2020&lt;/a&gt; 은 이진 분류에서 F1/accuracy 보다 MCC 를 권장합니다.&lt;/p&gt;
&lt;h3 id=&quot;log-loss--cross-entropy&quot;&gt;Log Loss / Cross-Entropy&lt;/h3&gt;
&lt;p&gt;확률 출력에 대한 지표:&lt;/p&gt;
&lt;p&gt;$$
\text{LogLoss} = -\frac{1}{N} \sum_{i=1}^{N} \left[ y_i \log \hat{p}_i + (1-y_i) \log (1-\hat{p}_i) \right]
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;예측 확률이 실제 클래스에서 얼마나 벗어났는지 측정&lt;/li&gt;
&lt;li&gt;Calibration (예측 확률이 실제 빈도와 일치하는가) 를 평가할 때 함께 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;scikit-learn-실전-코드&quot;&gt;scikit-learn 실전 코드&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sklearn.metrics &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    confusion_matrix,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    classification_report,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    roc_auc_score,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    precision_recall_curve,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    matthews_corrcoef,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# Confusion matrix&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;cm &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; confusion_matrix(y_true, y_pred)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 종합 리포트 (precision, recall, F1, support 를 각 클래스별로)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(classification_report(y_true, y_pred, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;digits&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 확률 기반 지표 (y_proba 는 positive class 확률)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;auc_roc &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; roc_auc_score(y_true, y_proba)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;precision, recall, thresholds &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; precision_recall_curve(y_true, y_proba)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# MCC&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mcc &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; matthews_corrcoef(y_true, y_pred)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;threshold-튜닝&quot;&gt;threshold 튜닝&lt;/h3&gt;
&lt;p&gt;기본 threshold 0.5 를 그대로 쓰면 안 됩니다. 도메인 비용에 맞춰 조정:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sklearn.metrics &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; f1_score&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; numpy &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; np&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;thresholds &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; np.linspace(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;101&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;f1s &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [f1_score(y_true, y_proba &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; t) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; t &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; thresholds]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;best_t &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; thresholds[np.argmax(f1s)]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;또는 precision 을 최소 몇% 이상 유지하는 조건 아래에서 recall 을 최대화하는 식으로 제약 최적화합니다.&lt;/p&gt;
&lt;h2 id=&quot;참고&quot;&gt;참고&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[federated-learning|Federated Learning]] 에서도 동일 지표를 클라이언트별로 계산합니다.&lt;/li&gt;
&lt;li&gt;[[transfer-learning|Transfer Learning]] downstream 평가에 대부분 이 지표들을 씁니다.&lt;/li&gt;
&lt;li&gt;[[sagemaker-model-monitor|SageMaker Model Monitor]] 의 Model Quality Monitor 가 이 지표들을 모니터링합니다.&lt;/li&gt;
&lt;li&gt;[[helm-llm-benchmark|HELM]] 의 accuracy 축은 여기서 확장된 형태입니다.&lt;/li&gt;
&lt;li&gt;Wikipedia: &lt;a href=&quot;https://en.wikipedia.org/wiki/Precision_and_recall&quot;&gt;Precision and recall&lt;/a&gt;, &lt;a href=&quot;https://en.wikipedia.org/wiki/Receiver_operating_characteristic&quot;&gt;Receiver operating characteristic&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ml</category><category>evaluation</category><category>classification</category><category>metrics</category><author>koa (김신건)</author></item><item><title>SPMD</title><link>https://shinkeonkim.com/wiki/ml/spmd/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ml/spmd/</guid><pubDate>Sun, 14 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;SPMD&lt;/strong&gt; (Single Program, Multiple Data)는 병렬 컴퓨팅의 대표 모델 중 하나. &lt;strong&gt;모든 프로세스(또는 thread)가 같은 프로그램을 실행하되, 각자 다른 데이터를 처리&lt;/strong&gt;한다.&lt;/p&gt;
&lt;p&gt;Frederica Darema 가 1980년대 후반 IBM 에서 정의한 개념. MPI, CUDA, OpenMP 등 거의 모든 병렬 컴퓨팅 프레임워크의 기본 추상화.&lt;/p&gt;
&lt;h2 id=&quot;동작-방식&quot;&gt;동작 방식&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# SPMD 의사 코드 (모든 노드가 같은 코드 실행)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;my_rank &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; get_rank()           &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 0, 1, 2, ..., N-1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;my_data &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; load_data(my_rank)   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 노드마다 다른 데이터 슬라이스&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;result &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process(my_data)      &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 같은 처리 로직&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;all_results &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; collective_op(result)  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 통신 (all-reduce 등)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;각 노드/프로세스는:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;rank (또는 id)&lt;/strong&gt; 로 자기를 식별&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;자기 데이터 슬라이스&lt;/strong&gt;만 처리&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;동기화 지점&lt;/strong&gt; 에서 통신 (barrier, all-reduce, broadcast 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;다른-병렬-모델과의-차이&quot;&gt;다른 병렬 모델과의 차이&lt;/h2&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;모델&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;프로그램&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;데이터&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;동기화&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;대표 사례&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;SIMD&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;1&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;여러 vector&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;매 사이클&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;CPU AVX, SSE&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;[[SIMT]]&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;1&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;thread 마다&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;warp 단위&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;GPU CUDA&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;SPMD&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;1 (인스턴스 N개)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;노드 마다&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;명시적&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;MPI, 분산 학습&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;MIMD&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;여러&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;여러&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;명시적&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;일반 멀티스레드&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;[[SIMT]] 는 SPMD 의 GPU 하드웨어 구현 정도로 볼 수 있다. CUDA 코드를 작성할 때 각 thread 가 자기 &lt;code&gt;threadIdx.x&lt;/code&gt; 로 자기 데이터를 처리하는 패턴이 정확히 SPMD.&lt;/p&gt;
&lt;h2 id=&quot;spmd-의-매력&quot;&gt;SPMD 의 매력&lt;/h2&gt;
&lt;h3 id=&quot;1-프로그래밍-단순함&quot;&gt;1. 프로그래밍 단순함&lt;/h3&gt;
&lt;p&gt;여러 다른 프로그램을 짜는 게 아니라 하나만 짜면 됨. rank 로 분기.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; my_rank &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    coordinator_logic()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    worker_logic()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;2-확장-용이&quot;&gt;2. 확장 용이&lt;/h3&gt;
&lt;p&gt;같은 코드를 100 노드든 10,000 노드든 실행 가능. 노드 수만 바꾸면 끝.&lt;/p&gt;
&lt;h3 id=&quot;3-동기화가-명시적&quot;&gt;3. 동기화가 명시적&lt;/h3&gt;
&lt;p&gt;모든 노드가 같은 코드를 실행하므로 &lt;code&gt;collective_op&lt;/code&gt; 같은 동기화 지점이 자연스럽게 일치.&lt;/p&gt;
&lt;h2 id=&quot;실제-예시&quot;&gt;실제 예시&lt;/h2&gt;
&lt;h3 id=&quot;mpi-message-passing-interface&quot;&gt;MPI (Message Passing Interface)&lt;/h3&gt;
&lt;p&gt;전통적인 HPC 의 SPMD 표준.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;c&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;MPI_Init&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;argc&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;argv&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; rank, size;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;MPI_Comm_rank&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(MPI_COMM_WORLD, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;rank&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;MPI_Comm_size&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(MPI_COMM_WORLD, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;size&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 각 rank 가 자기 데이터 슬라이스 처리&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;double&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; local_sum &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; compute_local_sum&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(rank);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 모든 노드의 합 = global_sum 으로 집계&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;double&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; global_sum;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;MPI_Reduce&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;local_sum&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;global_sum&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, MPI_DOUBLE, MPI_SUM, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, MPI_COMM_WORLD);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;MPI_Finalize&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;cuda-gpu&quot;&gt;CUDA (GPU)&lt;/h3&gt;
&lt;p&gt;GPU 의 SPMD 구현. 각 thread 가 자기 인덱스로 작업.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;cpp&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;__global__ &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_vectors&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;float*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; a, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;float*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; b, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;float*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; c, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; n) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; blockIdx.x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; blockDim.x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; threadIdx.x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; n) c[i] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; a[i] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; b[i];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;pytorch-ddp--fsdp&quot;&gt;PyTorch DDP / FSDP&lt;/h3&gt;
&lt;p&gt;[[분산 학습]] 의 SPMD 패턴. 모든 GPU 가 같은 모델 코드를 실행, 각자 다른 배치 처리, &lt;code&gt;all_reduce&lt;/code&gt; 로 gradient 동기화.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 모든 rank 가 실행&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;dist.init_process_group()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; DDP(model)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; batch &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; dataloader:  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# rank 마다 다른 배치&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    loss &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; model(batch)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    loss.backward()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    # DDP 가 자동으로 all-reduce&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    optimizer.step()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;jax-pmap&quot;&gt;JAX &lt;code&gt;pmap&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;함수형 SPMD.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;@jax.pmap&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; step&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(params, batch):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; params &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; learning_rate &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; grad(loss)(params, batch)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# pmap 은 모든 device 에 같은 함수를 자동 분배&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;new_params &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; step(replicate(params), sharded_batch)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;spmd-의-한계&quot;&gt;SPMD 의 한계&lt;/h2&gt;
&lt;h3 id=&quot;1-heterogeneous-워크로드-어려움&quot;&gt;1. Heterogeneous 워크로드 어려움&lt;/h3&gt;
&lt;p&gt;모든 노드가 같은 일을 한다는 가정. 일부 노드만 다른 작업이 필요한 경우 ([[Pipeline Parallelism]] 등) MIMD 스타일로 전환 필요.&lt;/p&gt;
&lt;h3 id=&quot;2-load-imbalance&quot;&gt;2. Load imbalance&lt;/h3&gt;
&lt;p&gt;각 노드의 작업량이 다르면 빠른 노드가 느린 노드를 기다림. 균형 분할이 중요.&lt;/p&gt;
&lt;h3 id=&quot;3-통신-비용&quot;&gt;3. 통신 비용&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;all_reduce&lt;/code&gt;, &lt;code&gt;all_gather&lt;/code&gt; 같은 collective 가 노드 수에 따라 비용 급증. 100 노드 → 10,000 노드 확장 시 통신 패턴 재설계 필요.&lt;/p&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[SIMT]] - GPU 하드웨어 구현&lt;/li&gt;
&lt;li&gt;[[분산 학습]] - 대규모 모델 학습의 SPMD 패턴&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>parallel-computing</category><category>programming-model</category><category>distributed</category><author>koa (김신건)</author></item><item><title>모델 양자화</title><link>https://shinkeonkim.com/wiki/ml/quantization/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ml/quantization/</guid><pubDate>Sun, 14 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;양자화 (Quantization)&lt;/strong&gt; 는 신경망 모델의 가중치/활성화를 &lt;strong&gt;높은 정밀도 (FP32, FP16) 에서 낮은 정밀도 (INT8, INT4 등) 로 변환&lt;/strong&gt;하여 메모리와 연산량을 줄이는 기법.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;원래 신호 처리 용어. 연속적인 신호 (continuous signal) 를 이산적인 (discrete) 양자 (quantum) 레벨로 변환한다는 뜻에서 “양자(量子)화”라 부른다. 실수 값을 정수 격자에 맞춰 떨어뜨리는 과정.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;FP32 가중치: 0.327891, -1.42876, 0.00123, ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                ↓ 양자화 (4-bit, 16 levels)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;INT4 가중치: 3, -6, 0, ...  (scale 곱해서 복원)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;왜-양자-인가&quot;&gt;왜 “양자” 인가&lt;/h2&gt;
&lt;p&gt;물리학의 양자(quantum) 개념에서 유래. 연속체를 이산적인 단위로 쪼개는 것.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FP32: 약 2^32 가지 값 표현 가능 (사실상 연속)&lt;/li&gt;
&lt;li&gt;INT8: 256 가지 값만 (이산)&lt;/li&gt;
&lt;li&gt;INT4: 16 가지 값만 (매우 이산)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;비유: 아날로그 회전 다이얼 vs 디지털 16 단계 클릭. 16 단계로 “양자화” 된다.&lt;/p&gt;
&lt;h2 id=&quot;왜-필요한가&quot;&gt;왜 필요한가&lt;/h2&gt;
&lt;p&gt;LLM (Large Language Model) 은 메모리와 메모리 대역폭이 가장 큰 병목.&lt;/p&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;모델&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;FP16&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;INT8&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;INT4&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Llama 2 7B&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;13 GB&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;7 GB&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;4 GB&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Llama 2 70B&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;140 GB&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;70 GB&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;40 GB&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;GPT-3 175B&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;350 GB&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;175 GB&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;90 GB&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;INT4 로 양자화하면:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;메모리 4~8 배 절약&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;메모리 대역폭 4~8 배 절약&lt;/strong&gt; (가장 중요, 추론 속도 결정)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;연산 2~4 배 빠름&lt;/strong&gt; (INT 연산이 FP 보다 회로가 작음)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;24 GB RTX 4090 한 장에 70B 모델 INT4 로 돌릴 수 있게 됨.&lt;/p&gt;
&lt;h2 id=&quot;양자화의-수학&quot;&gt;양자화의 수학&lt;/h2&gt;
&lt;p&gt;스칼라 양자화의 기본 공식:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;quantize(x) = round(x / scale) + zero_point&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;dequantize(q) = (q - zero_point) * scale&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;여기서&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  scale = (x_max - x_min) / (q_max - q_min)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  zero_point = q_min - round(x_min / scale)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;예) FP32 가중치 범위 &lt;code&gt;[-2.5, 3.0]&lt;/code&gt; 을 INT8 (&lt;code&gt;[-128, 127]&lt;/code&gt;) 로:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;scale = 5.5 / 255 ≈ 0.0216&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;zero_point = -128 - round(-2.5 / 0.0216) ≈ -12&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0.327 → round(0.327/0.0216) + (-12) = 15 - 12 = 3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;복원: &lt;code&gt;3 * 0.0216 - (-12 * 0.0216) ≈ 0.324&lt;/code&gt; (오차 0.003)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 오차가 누적되면 모델 품질이 떨어진다. 어떻게 오차를 최소화할지가 양자화 기법의 핵심 차이.&lt;/p&gt;
&lt;h2 id=&quot;양자화-방법론&quot;&gt;양자화 방법론&lt;/h2&gt;
&lt;h3 id=&quot;1-post-training-quantization-ptq&quot;&gt;1. Post-Training Quantization (PTQ)&lt;/h3&gt;
&lt;p&gt;이미 학습된 모델을 그대로 양자화. 재학습 필요 없음.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# PyTorch 의사 코드&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model_fp32 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; load_model()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;calibration_data &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; small_dataset_sample()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model_int8 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; quantize_ptq(model_fp32, calibration_data)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;장점&lt;/strong&gt;: 빠름 (수십 분), 학습 데이터 불필요&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;단점&lt;/strong&gt;: 정확도 손실 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;가장 실용적, 가장 널리 사용.&lt;/p&gt;
&lt;h3 id=&quot;2-quantization-aware-training-qat&quot;&gt;2. Quantization-Aware Training (QAT)&lt;/h3&gt;
&lt;p&gt;학습 중에 양자화 효과를 시뮬레이션. 모델이 양자화 오차에 적응.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# fake quantize 삽입&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;y &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; forward_pass(x)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;y_quantized &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; fake_quantize(y)  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 양자화 + 즉시 역양자화&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# backward 에서는 Straight-Through Estimator (STE) 로 gradient 통과&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;장점&lt;/strong&gt;: 가장 정확도 좋음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;단점&lt;/strong&gt;: 재학습 비용 (full training 의 5~30%)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;극한 압축 (4-bit 미만) 시 필수.&lt;/p&gt;
&lt;h3 id=&quot;3-gptq-generative-pre-trained-transformer-quantization&quot;&gt;3. GPTQ (Generative Pre-trained Transformer Quantization)&lt;/h3&gt;
&lt;p&gt;2022년 발표 (&lt;a href=&quot;https://arxiv.org/abs/2210.17323&quot;&gt;arXiv:2210.17323&lt;/a&gt;). LLM 특화 PTQ.&lt;/p&gt;
&lt;h4 id=&quot;동기&quot;&gt;동기&lt;/h4&gt;
&lt;p&gt;기본적인 RTN (Round-To-Nearest) 양자화는 단순하지만 오차가 크다. 한 가중치를 양자화하면 발생한 오차가 이후 출력에 그대로 전파됨. GPTQ 는 &lt;strong&gt;이미 양자화한 가중치의 오차를, 아직 양자화 안 한 가중치들로 보정&lt;/strong&gt;한다.&lt;/p&gt;
&lt;h4 id=&quot;핵심-알고리즘-obq-기반&quot;&gt;핵심 알고리즘 (OBQ 기반)&lt;/h4&gt;
&lt;p&gt;OBQ (Optimal Brain Quantization) 의 LLM-scale 확장. 가중치 행렬 &lt;code&gt;W&lt;/code&gt; 한 행씩 처리:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;1. 입력 데이터로 Hessian 행렬 H = 2·X·X^T 계산&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;2. 각 column (가중치) 을 순서대로 양자화:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   a. quant(w_j) 로 양자화&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   b. 양자화 오차 e_j = (w_j - quant(w_j)) / [H^-1]_jj&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   c. 아직 양자화 안 한 가중치들을 e_j · H^-1_j,k 만큼 조정 (오차 보정)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;3. 모든 column 끝나면 다음 행으로&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;핵심 통찰: Hessian 의 역행렬 정보 (&lt;code&gt;H^-1&lt;/code&gt;) 가 각 가중치를 얼마나 흔들어야 출력 오차가 최소화되는지 알려준다.&lt;/p&gt;
&lt;h4 id=&quot;cholesky-분해-최적화&quot;&gt;Cholesky 분해 최적화&lt;/h4&gt;
&lt;p&gt;원래 OBQ 는 매 column 마다 Hessian 역행렬 갱신이 필요해 매우 느렸다 (175B 모델에 수개월). GPTQ 는 &lt;strong&gt;Cholesky 분해&lt;/strong&gt;로 미리 &lt;code&gt;H^-1&lt;/code&gt; 의 윗삼각 형태를 한 번에 계산하고, blockwise update 로 메모리/시간 최적화. &lt;strong&gt;175B 모델을 4시간&lt;/strong&gt; 으로 단축.&lt;/p&gt;
&lt;h4 id=&quot;옵션-act-order&quot;&gt;옵션: act-order&lt;/h4&gt;
&lt;p&gt;활성화 크기가 큰 column 순으로 양자화하면 7B 모델에서 PPL 7.15 → 6.09 로 개선. 큰 활성화 → 작은 오차 우선 보정 → 후속 column 영향 최소화.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;장점&lt;/strong&gt;: INT4 에서도 정확도 손실 매우 작음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;단점&lt;/strong&gt;: 처리 시간 (1~4시간), 보정용 데이터 128+ 샘플 필요&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;품질&lt;/strong&gt;: LLaMA-7B 기준 FP16 PPL 5.68 vs GPTQ-INT4 6.09 (0.4 차이)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;4-awq-activation-aware-weight-quantization&quot;&gt;4. AWQ (Activation-aware Weight Quantization)&lt;/h3&gt;
&lt;p&gt;2023년 발표 (&lt;a href=&quot;https://arxiv.org/abs/2306.00978&quot;&gt;arXiv:2306.00978&lt;/a&gt;). GPTQ 와 같은 목표지만 완전히 다른 접근.&lt;/p&gt;
&lt;h4 id=&quot;동기-1&quot;&gt;동기&lt;/h4&gt;
&lt;p&gt;GPTQ 의 Hessian 기반 보정은 수학적으로 우아하지만 비싸다. AWQ 의 관찰: &lt;strong&gt;출력 오차의 대부분은 “outlier channels” 가 만든다&lt;/strong&gt;. 일부 채널의 활성화 크기가 매우 크고, 이 채널의 가중치 양자화 오차가 출력 전체를 망친다.&lt;/p&gt;
&lt;h4 id=&quot;핵심-아이디어-activation-aware-scaling&quot;&gt;핵심 아이디어, Activation-aware Scaling&lt;/h4&gt;
&lt;p&gt;수학적 항등식 활용:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Y = (W · diag(s)^-1) · (diag(s) · X)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  = W_scaled · X_scaled&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;여기서 s = per-channel scaling factor&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;W_scaled&lt;/code&gt; 에서 salient channels 의 가중치는 &lt;code&gt;s^-1&lt;/code&gt; 배 작아짐 → INT4 격자에서 더 정밀하게 표현&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X_scaled&lt;/code&gt; 에서 같은 채널의 활성화는 &lt;code&gt;s&lt;/code&gt; 배 커짐 → 출력 동일&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;알고리즘&quot;&gt;알고리즘&lt;/h4&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;1. 캘리브레이션 데이터로 각 채널의 평균 활성화 크기 |X|_c 계산&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;2. s_c = |X|_c^α 형태로 parametrize (α 는 grid search 변수)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;3. α 를 20개 정도 grid 에서 탐색:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   for α in [0, 0.05, 0.1, ..., 1.0]:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;     계산 layer 출력 오차&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;4. 가장 작은 오차의 α 채택, W_scaled 를 단순 INT4 RTN 으로 양자화&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;비교&quot;&gt;비교&lt;/h4&gt;






























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;GPTQ&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;AWQ&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;접근&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Hessian-weighted 가중치 보정&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Pre-quantization 채널 스케일링&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;계산&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Cholesky 분해 + sequential update&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Grid search (20 forward pass/layer)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;시간&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;1~4 시간&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;10분&lt;del&gt;30분 (**5&lt;/del&gt;10배 빠름**)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;품질&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;LLaMA-7B INT4: PPL 6.09&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;LLaMA-7B INT4: PPL 6.08 (거의 동일)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;GPTQ vs AWQ: GPTQ 는 “weight 별로 더 열심히 보정”, AWQ 는 “문제를 회전시켜서 weight 별 보정이 쉬워지게”. 실용적으로는 AWQ 가 더 인기.&lt;/p&gt;
&lt;h3 id=&quot;5-gguf--ggml-llamacpp&quot;&gt;5. GGUF / GGML (llama.cpp)&lt;/h3&gt;
&lt;p&gt;CPU + Apple Silicon 친화 양자화 포맷. 여러 비트수 동시 지원.&lt;/p&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;포맷&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;bit&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;7B 메모리&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;품질&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Q2_K&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;2.6&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;2.8 GB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;극한 압축 (품질 손실 큼)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Q4_K_M&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;4.1&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;4.1 GB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;권장&lt;/strong&gt;, FP16 대비 96~98%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Q5_K_M&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;5.1&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;4.8 GB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;고품질&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Q8_0&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;8.0&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;7.2 GB&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;FP16 거의 무손실&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;K_M = Mixed precision (중요 레이어는 더 높은 비트). 로컬 LLM 실행의 사실상 표준.&lt;/p&gt;
&lt;h3 id=&quot;6-qlora-nf4&quot;&gt;6. QLoRA (NF4)&lt;/h3&gt;
&lt;p&gt;2023년 5월 발표 (&lt;a href=&quot;https://arxiv.org/abs/2305.14314&quot;&gt;arXiv:2305.14314&lt;/a&gt;). Tim Dettmers 외. &lt;strong&gt;24 GB GPU 1대로 65B 모델 fine-tuning&lt;/strong&gt; 을 가능하게 만든 기법. 단순한 양자화를 넘어 3가지 혁신을 조합.&lt;/p&gt;
&lt;h4 id=&quot;1-nf4-4-bit-normalfloat&quot;&gt;1. NF4 (4-bit NormalFloat)&lt;/h4&gt;
&lt;p&gt;가장 중요한 혁신. 신경망 가중치는 보통 &lt;strong&gt;정규분포 N(0, σ²) 를 따른다&lt;/strong&gt; 는 관찰에서 시작.&lt;/p&gt;
&lt;p&gt;기존 INT4 / FP4 는 균등 간격으로 16개 값을 잡지만, 정규분포 데이터에서는 0 근처에 값이 몰려 있다. 균등 간격은 비효율.&lt;/p&gt;
&lt;p&gt;NF4 는 &lt;strong&gt;각 양자화 구간이 표준정규분포 N(0, 1) 아래 같은 면적&lt;/strong&gt; 을 가지도록 16개 값을 설계.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;표준정규분포 N(0, 1) 를 16등분 (각 구간 확률 1/16):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  q_i = quantile((i + 0.5) / 16)  for i = 0..15&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;결과 NF4 값들 (대략):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  -1.0,  -0.69, -0.52, -0.40, -0.30, -0.21, -0.13, -0.06,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   0.06,  0.16,  0.25,  0.34,  0.44,  0.56,  0.72,  1.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;0 근처에 값이 빽빽하고 양 끝에 듬성. 정규분포 데이터에 최적.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;정보이론 관점&lt;/strong&gt;: NF4 는 “정규분포 데이터를 4-bit 로 표현하는 information-theoretically optimal” 양자화. 균등 INT4 대비 같은 비트로 더 적은 정보 손실.&lt;/p&gt;
&lt;h4 id=&quot;2-double-quantization&quot;&gt;2. Double Quantization&lt;/h4&gt;
&lt;p&gt;블록 양자화 (blocksize 64) 에서는 각 블록마다 scale (FP32, 4 bytes) 이 필요. 큰 모델에선 이 scale 자체가 메모리를 차지.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;65B 모델, blocksize 64:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  parameter 수: 65 × 10^9&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  block 수: ~10^9&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  block 당 FP32 scale: 4 bytes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  scale 총량: 4 GB (! 가중치 압축한 의미가 무색)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Double Quantization: &lt;strong&gt;scale 자체를 다시 양자화&lt;/strong&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;원본:     W (FP16) → blockwise quant → W_NF4 + c_1 (FP32 per 64 weights)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Double:   W (FP16) → quant 1 → W_NF4 + c_1_quantized + c_2 (FP32 per 256 c_1)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;c_1 은 8-bit 로 양자화 (c_2 가 c_1 의 scale)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;평균 &lt;strong&gt;0.37 bits/parameter 절약&lt;/strong&gt; (65B 모델에서 ~3 GB).&lt;/p&gt;
&lt;h4 id=&quot;3-paged-optimizer&quot;&gt;3. Paged Optimizer&lt;/h4&gt;
&lt;p&gt;QLoRA 의 또 다른 혁신. LoRA adapter 의 optimizer state (Adam 의 momentum + variance, FP32) 가 메모리 spike 의 원인.&lt;/p&gt;
&lt;p&gt;긴 시퀀스 처리 중 일시적으로 메모리가 부족해지면 OOM. Paged Optimizer 는 &lt;strong&gt;NVIDIA Unified Memory&lt;/strong&gt; 를 활용해 optimizer state 를 자동으로 GPU ↔ CPU RAM 사이에 페이지 단위로 교환. OS 의 가상 메모리 paging 과 동일 개념.&lt;/p&gt;
&lt;h4 id=&quot;전체-qlora-수식&quot;&gt;전체 QLoRA 수식&lt;/h4&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Y_BF16 = X_BF16 · doubleDequant(c_1, c_2, W_NF4) + X_BF16 · L_1 · L_2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  W_NF4: 4-bit 양자화된 frozen base model 가중치&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  c_1, c_2: double quantized scales&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  L_1, L_2: LoRA adapters (low-rank decomposition, trainable, BF16)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;doubleDequant 가 NF4 → BF16 복원, 그 후 일반 LoRA forward.&lt;/p&gt;
&lt;h4 id=&quot;결과&quot;&gt;결과&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;LLaMA 65B 를 &lt;strong&gt;단일 48 GB A6000 1장&lt;/strong&gt;으로 fine-tuning&lt;/li&gt;
&lt;li&gt;Guanaco 모델 (QLoRA 로 fine-tuned LLaMA 65B) 가 ChatGPT-3.5 와 비교 가능한 품질 달성&lt;/li&gt;
&lt;li&gt;HuggingFace &lt;code&gt;bitsandbytes&lt;/code&gt; 라이브러리로 한 줄 적용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;bitsandbytes-사용-예&quot;&gt;bitsandbytes 사용 예&lt;/h4&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; transformers &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; AutoModelForCausalLM, BitsAndBytesConfig&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; torch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;quant_config &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; BitsAndBytesConfig(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    load_in_4bit&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    bnb_4bit_quant_type&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;nf4&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,          &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# NF4 사용&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    bnb_4bit_use_double_quant&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,     &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# Double Quantization&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    bnb_4bit_compute_dtype&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;torch.bfloat16,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; AutoModelForCausalLM.from_pretrained(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;meta-llama/Llama-2-70b-hf&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    quantization_config&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;quant_config,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 이제 LoRA 추가 후 학습&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;7-fp8-fp4-hardware-native&quot;&gt;7. FP8, FP4 (Hardware native)&lt;/h3&gt;
&lt;p&gt;NVIDIA H100 부터 FP8 (e4m3, e5m2) 하드웨어 지원. B200 부터 FP4 추가.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;FP8&lt;/strong&gt;: 학습 + 추론. INT8 대비 동적 범위 넓음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FP4&lt;/strong&gt;: 4-bit 부동소수, INT4 대비 정확도 우위&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;INT4 같은 정수 양자화는 별도 calibration 이 필요하지만, FP8/FP4 는 하드웨어가 직접 처리.&lt;/p&gt;
&lt;h2 id=&quot;정확도-vs-압축-트레이드오프&quot;&gt;정확도 vs 압축 트레이드오프&lt;/h2&gt;




























































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;포맷&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;압축률&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;품질 (FP16 대비)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;FP16 / bf16&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;1x&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;기준&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;FP8 (H100)&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;2x&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;~99.7%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;INT8&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;4x&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;~99%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;FP4 (B200)&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;4x&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;~99.0%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;AWQ 4-bit&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;4x&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;del&gt;98&lt;/del&gt;99%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;GPTQ 4-bit&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;4x&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;del&gt;97&lt;/del&gt;99%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Q4_K_M GGUF&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;4x&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;del&gt;96&lt;/del&gt;98%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;NF4 (QLoRA)&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;4x&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;del&gt;95&lt;/del&gt;97%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;단순 INT4&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;4x&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;del&gt;85&lt;/del&gt;93%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;INT2&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;16x&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;큰 손실&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;시나리오별-권장&quot;&gt;시나리오별 권장&lt;/h2&gt;

































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;환경&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;권장&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;NVIDIA H100/H200/B200&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;FP8 (vLLM, TensorRT-LLM)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;NVIDIA B100/B200 frontier&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;FP4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;NVIDIA A100/4090&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;AWQ 4-bit&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Apple Silicon (Mac)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;MLX 4-bit 또는 GGUF Q4_K_M&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;CPU 전용&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;GGUF Q4_K_M (llama.cpp)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Fine-tuning, 메모리 제약&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;QLoRA NF4&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;cs-에-미친-영향&quot;&gt;CS 에 미친 영향&lt;/h2&gt;
&lt;p&gt;양자화는 단순한 최적화 기법을 넘어 &lt;strong&gt;모델 배포의 전체 패러다임&lt;/strong&gt;을 바꿨다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;로컬 LLM&lt;/strong&gt;: ChatGPT 급 모델을 노트북에서 실행 (llama.cpp + GGUF Q4)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;edge AI&lt;/strong&gt;: 스마트폰 [[NPU]] 가 INT4 회로로 LLM 추론&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPU 비용&lt;/strong&gt;: 같은 모델을 1/4 메모리로 → 클라우드 비용 4 배 절감&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;연구 방향&lt;/strong&gt;: “더 큰 모델” 만큼 “더 효율적인 양자화” 가 활발한 연구 분야&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ai</category><category>model-compression</category><category>inference</category><category>machine-learning</category><author>koa (김신건)</author></item><item><title>분산 학습</title><link>https://shinkeonkim.com/wiki/ml/distributed-training/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ml/distributed-training/</guid><pubDate>Sun, 14 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;분산 학습 (Distributed Training)&lt;/strong&gt; 은 한 [[GPU]] 또는 [[TPU]] 에 들어가지 않는 큰 모델을 &lt;strong&gt;여러 가속기에 나눠서&lt;/strong&gt; 학습시키는 기법.&lt;/p&gt;
&lt;p&gt;현대 LLM (Llama 405B, GPT-4, Gemini Ultra 등) 은 &lt;strong&gt;수천 ~ 수만 개의 GPU 로 동시에 학습&lt;/strong&gt;된다. 한 GPU 가 메모리, 컴퓨트, 통신 등 어느 한 자원이 부족할 때 다양한 방식으로 분할한다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;핵심-4가지-병렬화-전략&quot;&gt;핵심 4가지 병렬화 전략&lt;/h2&gt;
&lt;p&gt;대규모 모델 학습은 보통 &lt;strong&gt;4가지 (이상의) parallelism 을 조합&lt;/strong&gt;해서 사용한다.&lt;/p&gt;
&lt;h3 id=&quot;1-data-parallelism-dp-가장-단순&quot;&gt;1. Data Parallelism (DP), 가장 단순&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GPU 0: 전체 모델 + 데이터 batch 의 1/N&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GPU 1: 전체 모델 + 데이터 batch 의 1/N&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GPU N: 전체 모델 + 데이터 batch 의 1/N&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;→ 각자 forward + backward&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;→ all-reduce 로 gradient 동기화&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;→ 같은 step 후 모델이 동일해짐&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;장점&lt;/strong&gt;: 구현 가장 단순 (PyTorch DDP 한 줄)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;단점&lt;/strong&gt;: 각 GPU 에 전체 모델이 들어가야 함 (메모리 부족 시 사용 불가)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;통신&lt;/strong&gt;: 매 step backward 후 all-reduce (전체 모델 gradient 동기화)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;2-tensor-parallelism-tp-한-layer-를-쪼개기&quot;&gt;2. Tensor Parallelism (TP), 한 layer 를 쪼개기&lt;/h3&gt;
&lt;p&gt;큰 행렬 곱셈을 가로/세로로 분할.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Original: Y = X @ W  (W: [hidden, ff] = [4096, 16384])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Tensor Parallel (4-way):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  GPU 0: W_0 = W[:, 0:4096]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  GPU 1: W_1 = W[:, 4096:8192]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  GPU 2: W_2 = W[:, 8192:12288]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  GPU 3: W_3 = W[:, 12288:16384]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  각 GPU: Y_i = X @ W_i&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  결합: Y = concat([Y_0, Y_1, Y_2, Y_3])  # all-gather&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;장점&lt;/strong&gt;: 큰 layer 도 분할 가능&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;단점&lt;/strong&gt;: forward 마다 통신 (all-reduce/all-gather) 필요, 노드 내 NVLink 같은 빠른 연결 필수&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;대표&lt;/strong&gt;: Megatron-LM 의 TP 구현&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-pipeline-parallelism-pp-layer-를-분할&quot;&gt;3. Pipeline Parallelism (PP), layer 를 분할&lt;/h3&gt;
&lt;p&gt;모델의 layer 를 GPU 들에 수직 분배.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GPU 0: Layer 1-10&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GPU 1: Layer 11-20&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GPU 2: Layer 21-30&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GPU 3: Layer 31-40&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;→ 입력 → GPU 0 → GPU 1 → GPU 2 → GPU 3 → 출력&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;순차적이라 idle 시간 발생. &lt;strong&gt;micro-batching&lt;/strong&gt; 으로 pipeline 채움 (GPipe, PipeDream).&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;시간 →&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GPU 0: [B1] [B2] [B3] [B4] [bw4][bw3][bw2][bw1]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GPU 1:      [B1] [B2] [B3] [B4] [bw4][bw3][bw2][bw1]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GPU 2:           [B1] [B2] [B3] [B4] [bw4][bw3][bw2][bw1]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GPU 3:                [B1] [B2] [B3] [B4] [bw4][bw3][bw2][bw1]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;장점&lt;/strong&gt;: 통신 비용 작음 (인접 GPU 만), 매우 깊은 모델에 효과적&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;단점&lt;/strong&gt;: bubble (idle 시간) 발생, 정확한 schedule 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;4-zero--fsdp-메모리-sharding&quot;&gt;4. ZeRO / FSDP, 메모리 sharding&lt;/h3&gt;
&lt;p&gt;Microsoft DeepSpeed 의 ZeRO (&lt;a href=&quot;https://arxiv.org/abs/1910.02054&quot;&gt;arXiv:1910.02054&lt;/a&gt;), PyTorch FSDP 가 대표.&lt;/p&gt;
&lt;p&gt;데이터 병렬의 메모리 비효율을 해결. 각 GPU 가 모델 일부만 저장.&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;Stage&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;shard 대상&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;메모리 절약&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;ZeRO-1&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Optimizer state&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;4x&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;ZeRO-2&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;+ Gradient&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;8x&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;ZeRO-3 (FSDP)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;+ Parameter&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;N x&lt;/strong&gt; (GPU 수에 비례)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;ZeRO-3 / FSDP 동작:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;평소: parameter 도 shard 되어 있음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;forward 시: 필요한 layer 의 parameter 를 all-gather 로 모음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;backward 시: gradient 계산 후 reduce-scatter 로 다시 분산&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;장점&lt;/strong&gt;: Data Parallelism + 메모리 효율&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;단점&lt;/strong&gt;: gather/scatter 통신 비용 추가&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;5-context-parallelism-cp-시퀀스-차원-분할&quot;&gt;5. Context Parallelism (CP), 시퀀스 차원 분할&lt;/h2&gt;
&lt;p&gt;긴 컨텍스트 (32K, 100K+ token) 학습 시 시퀀스 자체를 GPU 에 분할.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GPU 0: token 0~8K&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GPU 1: token 8K~16K&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GPU 2: token 16K~24K&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GPU 3: token 24K~32K&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;→ attention 시 ring exchange 로 통신&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Google Gemini 1.5 Pro (1M context), Llama 3 (128K context) 학습에 사용.&lt;/p&gt;
&lt;h2 id=&quot;6-expert-parallelism-ep-moe-모델&quot;&gt;6. Expert Parallelism (EP), MoE 모델&lt;/h2&gt;
&lt;p&gt;Mixture of Experts (MoE) 모델에서 각 expert 를 다른 GPU 에 배치. 라우팅으로 활성 expert 만 통신.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mixtral 8x7B&lt;/li&gt;
&lt;li&gt;DeepSeek V3 (671B parameter, 활성 37B)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;조합-3d--4d--5d-parallelism&quot;&gt;조합: 3D / 4D / 5D Parallelism&lt;/h2&gt;
&lt;p&gt;대규모 학습은 보통 여러 차원을 조합:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Total GPUs = TP × PP × DP × CP × EP&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;예: Llama 3.1 405B 학습 (16,000 H100):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  TP: 8 (노드 내, NVLink)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  PP: 16 (노드 간, InfiniBand)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  DP: 125 (전체 batch 분산)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Total: 8 × 16 × 125 = 16,000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;각 차원의 통신 패턴:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TP&lt;/strong&gt;: forward 마다 all-reduce/all-gather → &lt;strong&gt;고대역폭 필수&lt;/strong&gt; (NVLink)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PP&lt;/strong&gt;: layer 경계에서 1회 → &lt;strong&gt;저대역폭 OK&lt;/strong&gt; (InfiniBand)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DP&lt;/strong&gt;: backward 후 all-reduce → 중간 대역폭&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CP&lt;/strong&gt;: ring exchange → 노드 내 추천&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;EP&lt;/strong&gt;: 라우팅 통신 → all-to-all&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;동기화-패턴-collective-communication&quot;&gt;동기화 패턴 (Collective Communication)&lt;/h2&gt;
&lt;p&gt;분산 학습의 핵심은 &lt;strong&gt;collective operation&lt;/strong&gt; 들.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;all-reduce:  [a,b,c,d] → 각 노드에 sum=a+b+c+d&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;all-gather:  [a,b,c,d] → 각 노드에 [a,b,c,d]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;reduce-scatter: [a,b,c,d] → 각 노드에 일부 sum&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;broadcast:   [a,...,...,...] → [a,a,a,a]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;all-to-all:  matrix transpose 같은 전체 재분배&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 연산들이 분산 학습의 통신 비용. 효율적인 구현이 NVIDIA NCCL, AMD RCCL, Google CC 라이브러리.&lt;/p&gt;
&lt;h2 id=&quot;프레임워크&quot;&gt;프레임워크&lt;/h2&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;프레임워크&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;주력&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;비고&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;PyTorch DDP&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;DP&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;가장 단순, 한 줄로 사용&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;PyTorch FSDP&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;DP + ZeRO-3&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;메모리 효율 DP&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Megatron-LM&lt;/strong&gt; (NVIDIA)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;TP + PP + CP + DP + EP&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;LLM 학습 표준&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;DeepSpeed&lt;/strong&gt; (Microsoft)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;ZeRO 1/2/3 + PP&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;MoE 지원&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Colossal-AI&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;모든 전략 통합&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;학습 + 추론 통합&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;JAX/Flax + pmap/pjit&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;SPMD 스타일 분할&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Google TPU 표준&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;어디서-사용&quot;&gt;어디서 사용?&lt;/h2&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;모델&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;학습에 쓴 전략&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Llama 2/3 (70B+)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;DP + TP + PP + FSDP&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Mixtral 8x7B (MoE)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;DP + EP + TP&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;GPT-4 (추정)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;DP + TP + PP + EP&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Gemini 1.5 Pro (1M context)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;DP + TP + CP&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;DeepSeek V3 (671B MoE)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;DP + EP + TP&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;cs-에-미친-영향&quot;&gt;CS 에 미친 영향&lt;/h2&gt;
&lt;p&gt;분산 학습은 단순한 엔지니어링 기법을 넘어 ML 연구 전체를 바꿨다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;모델 크기 폭증&lt;/strong&gt;: 1B → 7B → 70B → 405B → 1T (3년에 1000배)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;데이터센터 설계 변화&lt;/strong&gt;: NVLink, InfiniBand, 광 통신이 핵심 인프라&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;새로운 연구 분야&lt;/strong&gt;: scaling law, parallelism 자동 탐색 (Alpa, GSPMD)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;분산 시스템 지식 필수&lt;/strong&gt;: ML 엔지니어가 통신, 동기화, 장애 복구를 알아야&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[SPMD]] - 분산 학습의 프로그래밍 모델&lt;/li&gt;
&lt;li&gt;[[양자화]] - 학습된 모델 압축&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ai</category><category>training</category><category>parallelism</category><category>scaling</category><author>koa (김신건)</author></item><item><title>HBM</title><link>https://shinkeonkim.com/wiki/ml/hbm/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ml/hbm/</guid><pubDate>Sat, 13 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;HBM&lt;/strong&gt; (High Bandwidth Memory)는 DRAM die 를 수직으로 적층해 매우 높은 대역폭을 제공하는 메모리 패키지. AI 시대 GPU/TPU 의 메모리 병목 해결을 담당한다.&lt;/p&gt;
&lt;p&gt;기존 GDDR 메모리가 PCB 위에서 칩 옆에 배치되는 것과 달리, HBM 은 GPU/TPU die 와 같은 &lt;strong&gt;interposer&lt;/strong&gt; 위에 수 mm 거리에 배치되어 &lt;strong&gt;수천 개의 병렬 채널&lt;/strong&gt;로 연결된다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;구조&quot;&gt;구조&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                     [HBM Stack]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        +-------------------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        |     DRAM Die (layer 12) |  ← HBM3e 까지 12 단&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        +-------------------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        |     DRAM Die (layer 11) |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        +-------------------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        |          ...            |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        +-------------------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        |     DRAM Die (layer 1)  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        +-------------------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        |     Base Die (Logic)    |  ← I/O + Refresh + ECC&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        +-----+-------+-----+-----+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              |       |     |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              ↓       ↓     ↓  (TSV: 수천 개의 실리콘 관통 전극)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        +-----+-------+-----+-----+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        |    Silicon Interposer   |  ← 마이크론 단위 배선&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        +-----+-------+-----+-----+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              |       |     |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        +-----+-------+-----+-----+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        |       GPU / TPU         |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        +-------------------------+&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;base-die-logic-die&quot;&gt;Base Die (Logic Die)&lt;/h3&gt;
&lt;p&gt;스택의 가장 아래. DRAM die 가 아니라 &lt;strong&gt;로직 회로&lt;/strong&gt; 만 들어있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I/O 컨트롤러&lt;/li&gt;
&lt;li&gt;ECC (Error Correcting Code) 회로&lt;/li&gt;
&lt;li&gt;Refresh 로직 (DRAM 셀이 주기적 갱신 필요)&lt;/li&gt;
&lt;li&gt;Channel 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;through-silicon-via-tsv&quot;&gt;Through-Silicon Via (TSV)&lt;/h3&gt;
&lt;p&gt;핵심 기술. die 를 수직으로 관통하는 전극.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HBM3 기준 한 스택에 &lt;strong&gt;약 1,024 개 TSV&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;직경 수 마이크로미터&lt;/li&gt;
&lt;li&gt;모든 die 를 통과해야 하므로 정렬 정밀도가 핵심&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;silicon-interposer&quot;&gt;Silicon Interposer&lt;/h3&gt;
&lt;p&gt;GPU/TPU die 와 HBM stack 을 연결하는 작은 PCB 같은 실리콘 기판. 일반 PCB 보다 훨씬 미세한 배선 (마이크론 단위).&lt;/p&gt;
&lt;p&gt;HBM 의 비용 큰 이유 중 하나가 interposer + 패키징 (2.5D 패키징, 또는 CoWoS).&lt;/p&gt;
&lt;h2 id=&quot;channel-과-bank-구조&quot;&gt;Channel 과 Bank 구조&lt;/h2&gt;
&lt;p&gt;HBM 한 스택은 내부적으로 여러 channel 로 나뉜다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;1 HBM3 stack&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  ├── 8 channels (병렬 접근 가능)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  │   ├── 16 banks 각각&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  │   └── 각 bank: row + column address&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  └── 1024-bit wide interface&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Channel&lt;/strong&gt;: 독립적으로 read/write 가능. 8 channel = 8 개 메모리 컨트롤러가 동시 동작&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bank&lt;/strong&gt;: 한 channel 안에서 여러 행이 동시 활성화. bank parallelism 으로 throughput 증가&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wide interface&lt;/strong&gt;: 한 cycle 에 1024 bit (128 bytes) 동시 전송&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;GPU 메모리 컨트롤러는 이 8 channels × 16 banks 를 잘 활용해야 최대 대역폭을 낸다. 그래서 GPU 의 메모리 접근 패턴 (coalesced access) 이 중요.&lt;/p&gt;
&lt;h2 id=&quot;동작-원리&quot;&gt;동작 원리&lt;/h2&gt;
&lt;p&gt;DRAM 의 기본 동작은 같다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;1. ACTIVATE: row 를 row buffer 로 가져오기 (RAS, ~15ns)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;2. READ/WRITE: row buffer 의 column 선택 (CAS, ~15ns)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;3. PRECHARGE: 다음 access 를 위해 row 닫기&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;HBM 의 트릭:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- 8 channel × 16 bank = 128개 작업을 동시 진행&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- TSV 가 짧아 latency 가 일반 DDR 과 비슷 (~80ns) 이지만&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- 동시 처리량은 ~20배 (1.2 TB/s vs 50 GB/s)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;즉 HBM 은 &lt;em&gt;latency&lt;/em&gt; 가 아니라 &lt;em&gt;throughput&lt;/em&gt; 으로 이긴다. 한 access 의 응답 시간은 비슷하지만 &lt;strong&gt;동시 처리 가능 수가 압도적&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;세대별-대역폭&quot;&gt;세대별 대역폭&lt;/h2&gt;
&lt;h2 id=&quot;세대별-대역폭-1&quot;&gt;세대별 대역폭&lt;/h2&gt;















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;세대&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;출시&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;스택당 대역폭&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;비고&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;HBM1&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;2015&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;128 GB/s&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;AMD Fiji&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;HBM2&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;2016&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;256 GB/s&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;NVIDIA V100&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;HBM2e&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;2019&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;460 GB/s&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;NVIDIA A100&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;HBM3&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;strong&gt;2022&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;strong&gt;819 GB/s&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;NVIDIA H100, TPU v5p&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;HBM3e&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;strong&gt;2024&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;strong&gt;1,218 GB/s&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;NVIDIA H200, B200 (12-stack)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;HBM4&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;2026 예정&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;~2,048 GB/s&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;NVIDIA Rubin, AMD MI400&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;비교용으로, DDR5 한 채널은 약 51 GB/s. &lt;strong&gt;HBM3e 한 스택이 DDR5 의 24배&lt;/strong&gt; 대역폭.&lt;/p&gt;
&lt;h2 id=&quot;왜-ai-에-필수인가&quot;&gt;왜 AI 에 필수인가&lt;/h2&gt;
&lt;p&gt;LLM 추론을 예로 들면:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GPT-3 175B 모델은 FP16 으로 350 GB&lt;/li&gt;
&lt;li&gt;매 토큰 생성마다 모델 가중치를 전부 메모리에서 가져와야 함&lt;/li&gt;
&lt;li&gt;1초에 100 토큰 생성하려면 35 TB/s 대역폭 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 수치는 HBM 8 스택 (8 × 1.2 TB/s = 9.6 TB/s) 으로도 부족하다. 그래서:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;모델 분할 (multi-GPU)&lt;/li&gt;
&lt;li&gt;양자화 (FP16 → INT8 → INT4)&lt;/li&gt;
&lt;li&gt;KV cache 최적화&lt;/li&gt;
&lt;li&gt;HBM4, HBM5 로의 지속 진화&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;비용-구조&quot;&gt;비용 구조&lt;/h2&gt;
&lt;p&gt;HBM 은 비싸다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;일반 DDR5 16GB: ~$50&lt;/li&gt;
&lt;li&gt;HBM3e 16GB: ~$1,000 (20배)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이유:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;TSV 공정 복잡 (수율 낮음)&lt;/li&gt;
&lt;li&gt;수직 적층 패키징 비용&lt;/li&gt;
&lt;li&gt;SK Hynix 사실상 독점 (HBM3e 의 75%+ 점유)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;NVIDIA H100 의 HBM 비용이 전체 칩 가격 (~$30,000) 의 약 1/3 을 차지한다.&lt;/p&gt;
&lt;h2 id=&quot;cpu-vs-gpu-메모리-격차&quot;&gt;CPU vs GPU 메모리 격차&lt;/h2&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;프로세서&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;메모리 종류&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;대역폭&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Intel Core i9 (DDR5)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;DDR5-5600&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;~89 GB/s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Apple M4 Max (LPDDR5X)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;unified&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;~546 GB/s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;AMD Threadripper (DDR5)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;DDR5-5200&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;~166 GB/s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;NVIDIA H100 (HBM3)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;HBM3 5 stack&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;strong&gt;~3,350 GB/s&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;NVIDIA B200 (HBM3e)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;HBM3e 8 stack&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;strong&gt;~8,000 GB/s&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;GPU/TPU 가 AI 워크로드를 압도하는 핵심 이유 = HBM 의 대역폭.&lt;/p&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[TPU]]&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>hardware</category><category>memory</category><category>gpu</category><category>tpu</category><category>dram</category><author>koa (김신건)</author></item><item><title>SIMT</title><link>https://shinkeonkim.com/wiki/ml/simt/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ml/simt/</guid><pubDate>Sat, 13 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;SIMT&lt;/strong&gt; (Single Instruction, Multiple Threads) 는 NVIDIA 가 정립한 GPU 의 실행 모델이다. 한 명령(instruction) 을 한 그룹의 thread(warp) 가 동시에 실행하되, &lt;strong&gt;각 thread 는 자기 레지스터와 데이터&lt;/strong&gt;를 갖는다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;simd-와의-차이&quot;&gt;SIMD 와의 차이&lt;/h2&gt;
&lt;p&gt;SIMD (Single Instruction Multiple Data) 와 헷갈리기 쉽다.&lt;/p&gt;






























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;SIMD&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;SIMT&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;데이터 그룹&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;벡터 레지스터 (예: AVX-512 = 16 floats)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;thread (수 십개)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;분기 처리&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;어렵음 (masked operation)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;자동 (warp divergence)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;프로그래밍 모델&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;명시적 SIMD intrinsic&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;평범한 thread 코드&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;대표 사례&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;CPU AVX, ARM NEON&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;NVIDIA CUDA, AMD ROCm&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;CUDA 코드는 마치 각 thread 가 독립적으로 도는 것처럼 작성하지만, 하드웨어는 32 thread (= 1 warp)를 lockstep 으로 함께 실행한다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;cpp&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;__global__ &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;float*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; a, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;float*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; b, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;float*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; c, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; n) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; blockIdx.x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; blockDim.x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; threadIdx.x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; n) c[i] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; a[i] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; b[i];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 각 thread 가 c[i] = a[i] + b[i] 를 자기 i 로 수행&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 한 warp 의 32 thread 가 동시에 ADD 명령 실행&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;warp&quot;&gt;Warp&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Warp 크기&lt;/strong&gt;: NVIDIA = 32 threads, AMD wavefront = 32 또는 64&lt;/li&gt;
&lt;li&gt;1 warp 의 모든 thread 는 &lt;strong&gt;같은 PC (program counter)&lt;/strong&gt; 를 공유 → 같은 명령 동시 수행&lt;/li&gt;
&lt;li&gt;각 thread 는 &lt;strong&gt;고유한 thread index&lt;/strong&gt; + 자기 레지스터 보유&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;SM (Streaming Multiprocessor) 한 개:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  - 64 개의 warp 동시 보유 가능&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  - 한 cycle 에 1~4 개의 warp 명령 디스패치&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  - 같은 SM 의 warp 들은 공유 메모리(SRAM) 접근 가능&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;NVIDIA H100 = 132 SM × 64 warp × 32 thread = &lt;strong&gt;약 27만 thread 동시 처리&lt;/strong&gt; 가능 (실제 활성 thread 수는 워크로드에 따라 다름).&lt;/p&gt;
&lt;h2 id=&quot;warp-divergence&quot;&gt;Warp Divergence&lt;/h2&gt;
&lt;p&gt;SIMT 의 가장 큰 함정.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;cpp&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  result &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; compute_A&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;} &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  result &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; compute_B&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;같은 warp 의 일부 thread 만 &lt;code&gt;if&lt;/code&gt; 경로를 타고 나머지가 &lt;code&gt;else&lt;/code&gt; 를 타면, &lt;strong&gt;GPU 는 두 경로를 직렬로 실행&lt;/strong&gt;한다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Cycle 1: warp 의 (x&gt;0) thread 만 활성, compute_A 실행&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;         (x&amp;#x3C;=0) thread 는 idle&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Cycle 2: warp 의 (x&amp;#x3C;=0) thread 만 활성, compute_B 실행&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;         (x&gt;0) thread 는 idle&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;결과적으로 같은 warp 안에서 분기가 갈리면 &lt;strong&gt;활용률이 절반&lt;/strong&gt;으로 떨어진다.&lt;/p&gt;
&lt;h3 id=&quot;divergence-최소화-패턴&quot;&gt;Divergence 최소화 패턴&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;데이터 정렬&lt;/strong&gt;: 비슷한 분기 결과를 가진 thread 를 같은 warp 로 모음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;분기 단순화&lt;/strong&gt;: triangle ops, masked select 등으로 변환&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;branch-free 알고리즘 선호&lt;/strong&gt;: 예) &lt;code&gt;min(a, b)&lt;/code&gt; 보다 &lt;code&gt;a + (b - a) * (a &gt; b)&lt;/code&gt; 같은 식&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;메모리-접근-패턴&quot;&gt;메모리 접근 패턴&lt;/h2&gt;
&lt;p&gt;SIMT 의 또 다른 성능 결정 요인은 &lt;strong&gt;coalesced memory access&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;한 warp 의 32 thread 가 연속된 메모리 주소를 접근 → 1번의 메모리 트랜잭션으로 처리 (좋음)&lt;/li&gt;
&lt;li&gt;흩어진 주소를 접근 → 32번의 트랜잭션 (나쁨, 32x 메모리 대역폭 소모)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;배열 인덱스를 thread ID 로 만드는 게 정석.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;cpp&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Good: thread 0 → a[0], thread 1 → a[1], ... → coalesced&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;data[threadIdx.x]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Bad: thread 0 → a[0], thread 1 → a[32], ... → scattered&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;data[threadIdx.x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;관련-모델-spmd&quot;&gt;관련 모델: SPMD&lt;/h2&gt;
&lt;p&gt;SIMT 와 비슷하지만 더 일반적인 모델로 &lt;strong&gt;SPMD&lt;/strong&gt; (Single Program Multiple Data) 가 있다. MPI 같은 분산 컴퓨팅에서 모든 노드가 같은 프로그램을 다른 데이터로 실행하는 패턴.&lt;/p&gt;
&lt;p&gt;SIMT 는 SPMD 의 GPU 하드웨어 구현 정도로 보면 맞다.&lt;/p&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[HBM]] - SIMT thread 수만큼 메모리 대역폭이 중요한 이유&lt;/li&gt;
&lt;li&gt;[[Systolic Array]] - SIMT 와 다른 행렬 곱셈 전용 구조&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>gpu</category><category>parallel-computing</category><category>architecture</category><category>cuda</category><author>koa (김신건)</author></item><item><title>Systolic Array</title><link>https://shinkeonkim.com/wiki/ml/systolic-array/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ml/systolic-array/</guid><pubDate>Sat, 13 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Systolic Array&lt;/strong&gt; 는 격자 형태로 배치된 다수의 Processing Element (PE) 가, 입력 데이터가 박동(systolic)처럼 격자를 가로질러 흐르는 동안 각 PE 가 곱셈+누적(MAC) 을 수행하는 하드웨어 구조다.&lt;/p&gt;
&lt;p&gt;H.T. Kung 이 1978년 제안한 개념이며, [[TPU]] 의 핵심 컴퓨팅 단위로 부활했다. TPU 에서는 &lt;strong&gt;MXU (Matrix Multiply Unit)&lt;/strong&gt; 으로 불린다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;핵심-아이디어&quot;&gt;핵심 아이디어&lt;/h2&gt;
&lt;p&gt;행렬 곱셈 &lt;code&gt;C = A × B&lt;/code&gt; 를 수행할 때:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;가중치 정주(Weight Stationary)&lt;/strong&gt;: 가중치는 각 PE 에 미리 적재되어 움직이지 않음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;활성화 흐름(Activation Flow)&lt;/strong&gt;: 입력 활성화는 격자를 가로질러 흐름 (좌→우)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;부분합 누적&lt;/strong&gt;: 각 PE 가 받은 입력 × 가중치 결과를 다음 PE 로 전달, 마지막 PE 가 누적합 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 구조의 우아함:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;메모리 접근 최소화&lt;/strong&gt;: 각 가중치는 PE 에 1번 적재 → 수많은 곱셈에 재사용&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;완벽한 데이터 재사용&lt;/strong&gt;: 한 활성화 값이 여러 PE 를 지나며 여러 곱셈에 참여&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;간단한 제어&lt;/strong&gt;: 모든 PE 가 같은 동작 (clock 동기) → 제어 회로 거의 없음&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;cpugpu-와의-차이&quot;&gt;CPU/GPU 와의 차이&lt;/h2&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;CPU&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;GPU&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Systolic Array (TPU)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;제어 회로 비중&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;매우 높음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;중간&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;매우 낮음&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;메모리 접근&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;빈번 (캐시 의존)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;빈번 (HBM)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;최소&lt;/strong&gt; (정주)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;행렬 곱 효율&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;낮음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;높음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;최고&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;다양한 워크로드&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;모두&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;대부분&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;행렬 위주만&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;한계&quot;&gt;한계&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;유연성 부족&lt;/strong&gt;: 행렬 곱셈에 최적화. element-wise 연산, 비선형 함수 등은 별도 vector unit 으로 처리&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;fixed shape&lt;/strong&gt;: MXU 크기 (예: 256x256) 보다 작은 행렬을 곱하면 활용률이 낮아짐. 모델을 큰 행렬로 합치는 패딩/타일링 필요&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;희소(sparse) 비효율&lt;/strong&gt;: 대부분의 element 가 0인 sparse matrix 에서는 비효율. TPU v4+ 에서 SparseCore 별도 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[TPU]]&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>hardware</category><category>tpu</category><category>architecture</category><category>matrix-multiply</category><author>koa (김신건)</author></item></channel></rss>