<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Windows on kenji.blog</title><link>http://kenji.blog/ko/categories/windows/</link><description>Recent content in Windows on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>ko</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 18:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/ko/categories/windows/index.xml" rel="self" type="application/rss+xml"/><item><title>Microsoft.Windows.AI의 최신 API 활용 사례 및 샘플 코드</title><link>http://kenji.blog/ko/p/microsoft-windows-ai-api-guide/</link><pubDate>Fri, 11 Sep 2026 18:00:00 +0900</pubDate><guid>http://kenji.blog/ko/p/microsoft-windows-ai-api-guide/</guid><description>&lt;img src="http://kenji.blog/p/microsoft-windows-ai-api-guide/img/eyecatch.jpg" alt="Featured image of post Microsoft.Windows.AI의 최신 API 활용 사례 및 샘플 코드" />&lt;h1 id="microsoftwindowsai의-최신-api-활용-사례-및-샘플-코드-windows-copilot-runtime의-심연을-탐구하다">Microsoft.Windows.AI의 최신 API 활용 사례 및 샘플 코드: Windows Copilot Runtime의 심연을 탐구하다
&lt;/h1>&lt;h2 id="1-시작하며-ai가-네이티브로-내장되는-windows의-새로운-시대">1. 시작하며: AI가 네이티브로 내장되는 Windows의 새로운 시대
&lt;/h2>&lt;p>최근 AI 기술의 진화는 눈부시며, 클라우드 상에서의 대규모 언어 모델(LLM) 활용에서 엣지 디바이스(로컬 PC)에서의 AI 추론으로 급속히 패러다임 전환이 일어나고 있습니다. 그 핵심을 담당하는 것이 Microsoft가 Windows 11용으로 제공하는 &amp;ldquo;Windows Copilot Runtime&amp;quot;과 이를 제어하기 위한 &amp;ldquo;Microsoft.Windows.AI&amp;rdquo; API입니다.&lt;/p>
&lt;p>클라우드 API(OpenAI나 Azure OpenAI 등)를 이용한 애플리케이션 개발은 쉽지만, 지연 시간(레이턴시), 프라이버시, 그리고 지속적인 비용이라는 과제가 따라다닙니다. 반면, 로컬에서 AI 모델을 구동함으로써 기밀 데이터를 디바이스 밖으로 내보내지 않고 오프라인에서도 작동하는 초저지연 애플리케이션을 구현할 수 있습니다.&lt;/p>
&lt;p>본 기사에서는 앞으로의 Windows 애플리케이션 개발에서 필수가 될 로컬 AI 기능의 구현 방법에 대해 C# 및 C++의 실용적인 샘플 코드를 곁들여 아키텍처부터 성능 튜닝까지 아주 상세하게 철저히 해설합니다. 단순히 API를 호출하는 것에 그치지 않고, 그 이면에 있는 하드웨어(NPU 및 GPU)의 활용, DirectML과의 연동 등 고도의 기술적 세부 사항까지 깊이 파고듭니다.&lt;/p>
&lt;h2 id="2-windows-copilot-runtime과-아키텍처의-전체상">2. Windows Copilot Runtime과 아키텍처의 전체상
&lt;/h2>&lt;p>Windows Copilot Runtime은 개발자가 Windows 상에서 AI 모델을 쉽게 통합하고 최고의 성능을 끌어낼 수 있도록 설계된 일련의 AI 스택입니다. 이 런타임은 OS 레벨에서 하드웨어 가속을 추상화하여 개발자에게 통일된 인터페이스를 제공합니다.&lt;/p>
&lt;div class="mermaid">graph TD
App["Windows 애플리케이션 (C# / C++)"] --> API["Microsoft.Windows.AI APIs"]
App --> ORT["ONNX Runtime"]
API --> WCR["Windows Copilot Runtime (OS 레이어)"]
WCR --> SLM["로컬 모델 (Phi-Silica 등)"]
ORT --> DML["DirectML Execution Provider"]
SLM --> DML
DML --> DXCore["DXCore / DirectX 12"]
DXCore --> NPU["NPU (Neural Processing Unit)"]
DXCore --> GPU["GPU (Graphics Processing Unit)"]
DXCore --> CPU["CPU"]&lt;/div>
&lt;p>위의 아키텍처 다이어그램이 보여주듯이, 애플리케이션은 고수준의 &lt;code>Microsoft.Windows.AI&lt;/code> API를 이용함으로써 OS에 내장된 소규모 언어 모델(SLM: Phi-Silica 등)에 직접 접근할 수 있습니다. 또한, 커스텀 모델을 사용할 경우에는 ONNX Runtime과 DirectML을 통해 하드웨어 가속을 명시적으로 이용하는 것도 가능합니다. OS 레이어가 CPU, GPU, NPU로의 워크로드 분산을 최적화하므로, 개발자는 하드웨어의 차이를 깊이 의식하지 않고도 고성능 AI 앱을 구축할 수 있습니다.&lt;/p>
&lt;h2 id="3-하드웨어-가속과-npu의-수리적-평가">3. 하드웨어 가속과 NPU의 수리적 평가
&lt;/h2>&lt;p>최신 Copilot+ PC에는 AI 처리에 특화된 프로세서인 NPU(Neural Processing Unit)가 탑재되어 있습니다. NPU의 성능은 일반적으로 TOPS(Tera Operations Per Second)로 평가됩니다.&lt;/p>
&lt;p>AI 모델의 추론에 있어서, 특히 행렬 곱셈(GEMM: General Matrix Multiply)의 계산 능력이 처리량(Throughput)을 결정짓습니다. 하드웨어의 이론상 최대 성능 $P_{\text{peak}}$ 은 다음 수식으로 개략적으로 계산됩니다.&lt;/p>
$$
P_{\text{peak}} = f \times N_{\text{cores}} \times N_{\text{MACs/core}} \times 2
$$
&lt;p>여기서,&lt;/p>
&lt;ul>
&lt;li>$f$ 는 NPU의 클럭 주파수(Hz)&lt;/li>
&lt;li>$N_{\text{cores}}$ 는 NPU 내의 코어 수&lt;/li>
&lt;li>$N_{\text{MACs/core}}$ 는 1코어당 MAC(Multiply-Accumulate) 유닛 수&lt;/li>
&lt;li>마지막의 $2$ 는, 1회의 MAC 연산이 곱셈과 덧셈의 2개 오퍼레이션(FLOPs/OPs)으로 계산되기 때문입니다.&lt;/li>
&lt;/ul>
&lt;p>예를 들어, 주파수 1.5GHz, 4코어, 각 코어가 4096MACs를 가진 NPU의 경우,
&lt;/p>
$$
P_{\text{peak}} = 1.5 \times 10^9 \times 4 \times 4096 \times 2 \approx 49.15 \text{ TOPS}
$$
&lt;p>
가 됩니다. Windows 11의 Copilot+ PC 요건인 40 TOPS를 만족하는 성능임이 수학적으로 증명됩니다.&lt;/p>
&lt;p>또한, AI 모델, 특히 LLM의 추론(디코드 페이즈)은 **메모리 바운드(Memory-Bound)**가 되기 쉽습니다. 시스템 메모리의 이론적 대역폭 $BW$ 는 다음과 같이 계산됩니다.&lt;/p>
$$
BW = f_{\text{mem}} \times W_{\text{bus}} \times \frac{2}{8}
$$
&lt;p>LPDDR5x-8533 메모리($f_{\text{mem}} = 8533 \text{ MT/s}$), 128비트 버스($W_{\text{bus}} = 128$)의 경우, 대역폭은 약 $136 \text{ GB/s}$ 가 됩니다. AI 애플리케이션의 최적화에서는 이 대역폭을 어떻게 절약할지가 중요하며, 후술할 모델의 양자화(Quantization)가 필수적입니다.&lt;/p>
&lt;h2 id="4-개발-환경-설정">4. 개발 환경 설정
&lt;/h2>&lt;p>최신 Windows AI API를 이용하려면, 다음의 환경과 툴체인을 갖추어야 합니다.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>OS&lt;/strong>: Windows 11 버전 24H2 이상 (Copilot+ PC 요건을 만족하는 NPU 탑재 디바이스를 강력히 권장)&lt;/li>
&lt;li>&lt;strong>SDK&lt;/strong>: Windows App SDK (v1.5 이후의 AI 확장 대응 버전)&lt;/li>
&lt;li>&lt;strong>개발 환경&lt;/strong>: Visual Studio 2022 (v17.10 이상), C++를 사용한 네이티브 개발 워크로드 및 .NET 데스크톱 개발 워크로드&lt;/li>
&lt;li>&lt;strong>패키지&lt;/strong>: NuGet을 통해 &lt;code>Microsoft.Windows.AI&lt;/code> 및 &lt;code>Microsoft.ML.OnnxRuntime.DirectML&lt;/code> 설치&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-xml" data-lang="xml">&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;lt;!-- .csproj 설정 예시 --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nt">&amp;lt;ItemGroup&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;lt;PackageReference&lt;/span> &lt;span class="na">Include=&lt;/span>&lt;span class="s">&amp;#34;Microsoft.Windows.AI&amp;#34;&lt;/span> &lt;span class="na">Version=&lt;/span>&lt;span class="s">&amp;#34;1.0.0-preview1&amp;#34;&lt;/span> &lt;span class="nt">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;lt;PackageReference&lt;/span> &lt;span class="na">Include=&lt;/span>&lt;span class="s">&amp;#34;Microsoft.WindowsAppSDK&amp;#34;&lt;/span> &lt;span class="na">Version=&lt;/span>&lt;span class="s">&amp;#34;1.5.240311000&amp;#34;&lt;/span> &lt;span class="nt">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;lt;PackageReference&lt;/span> &lt;span class="na">Include=&lt;/span>&lt;span class="s">&amp;#34;Microsoft.ML.OnnxRuntime.DirectML&amp;#34;&lt;/span> &lt;span class="na">Version=&lt;/span>&lt;span class="s">&amp;#34;1.17.1&amp;#34;&lt;/span> &lt;span class="nt">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nt">&amp;lt;/ItemGroup&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="5-deep-dive-1-c을-이용한-로컬-언어-모델phi-silica-활용">5. 【Deep Dive 1】 C#을 이용한 로컬 언어 모델(Phi-Silica) 활용
&lt;/h2>&lt;p>Windows Copilot Runtime에는 Microsoft가 개발한 고효율 소규모 언어 모델인 &amp;ldquo;Phi-Silica&amp;quot;가 OS 표준 컴포넌트로 내장되어 있습니다. 이를 통해 GB 단위의 모델을 네트워크에서 다운로드할 필요 없이, 오프라인 환경에서 고도의 자연어 처리(문서 요약, 코드 생성, 챗봇)가 가능해집니다.&lt;/p>
&lt;p>다음은 &lt;code>Microsoft.Windows.AI.Generative&lt;/code> 네임스페이스를 사용하여 C#으로 채팅 AI를 구축하는 고급 샘플 코드입니다. 스트리밍 응답을 지원하며, UI 스레드를 차단하지 않고 실시간으로 텍스트를 생성합니다.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;span class="lnt">64
&lt;/span>&lt;span class="lnt">65
&lt;/span>&lt;span class="lnt">66
&lt;/span>&lt;span class="lnt">67
&lt;/span>&lt;span class="lnt">68
&lt;/span>&lt;span class="lnt">69
&lt;/span>&lt;span class="lnt">70
&lt;/span>&lt;span class="lnt">71
&lt;/span>&lt;span class="lnt">72
&lt;/span>&lt;span class="lnt">73
&lt;/span>&lt;span class="lnt">74
&lt;/span>&lt;span class="lnt">75
&lt;/span>&lt;span class="lnt">76
&lt;/span>&lt;span class="lnt">77
&lt;/span>&lt;span class="lnt">78
&lt;/span>&lt;span class="lnt">79
&lt;/span>&lt;span class="lnt">80
&lt;/span>&lt;span class="lnt">81
&lt;/span>&lt;span class="lnt">82
&lt;/span>&lt;span class="lnt">83
&lt;/span>&lt;span class="lnt">84
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="nn">System&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="nn">System.Text&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="nn">System.Threading&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="nn">System.Threading.Tasks&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="nn">Microsoft.Windows.AI.Generative&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">namespace&lt;/span> &lt;span class="nn">WindowsAI.Sample&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">public&lt;/span> &lt;span class="k">class&lt;/span> &lt;span class="nc">LocalLanguageModelService&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">private&lt;/span> &lt;span class="n">LanguageModel&lt;/span> &lt;span class="n">_languageModel&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">private&lt;/span> &lt;span class="kt">bool&lt;/span> &lt;span class="n">_isInitialized&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="kc">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cs">/// &amp;lt;summary&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cs">/// 언어 모델의 초기화를 수행합니다. NPU 사용 가능 여부를 확인하고 최적의 디바이스에 모델을 로드합니다.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cs">/// &amp;lt;/summary&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">public&lt;/span> &lt;span class="kd">async&lt;/span> &lt;span class="n">Task&lt;/span> &lt;span class="n">InitializeAsync&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">_isInitialized&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WriteLine&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;로컬 AI 모델(Phi-Silica)의 시스템 요구 사항 및 가용성을 확인하고 있습니다...&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 모델이 시스템에서 사용 가능한지 확인 (미지원일 경우 다운로드가 촉구될 수 있음)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">var&lt;/span> &lt;span class="n">availability&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="k">await&lt;/span> &lt;span class="n">LanguageModel&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">CheckAvailabilityAsync&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">availability&lt;/span> &lt;span class="p">!=&lt;/span> &lt;span class="n">LanguageModelAvailability&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Available&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">throw&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="n">InvalidOperationException&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">$&amp;#34;로컬 AI 모델을 현재 사용할 수 없습니다. 상태: {availability}&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 모델 인스턴스 생성 (이 타이밍에 메모리 공간으로의 매핑과 NPU 초기화가 수행됨)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">_languageModel&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="k">await&lt;/span> &lt;span class="n">LanguageModel&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">CreateAsync&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">_isInitialized&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WriteLine&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;언어 모델의 초기화가 완료되었습니다. DirectML을 통한 하드웨어 가속이 활성화되었습니다.&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cs">/// &amp;lt;summary&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cs">/// 사용자의 프롬프트를 받아 스트리밍으로 응답을 생성합니다.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cs">/// &amp;lt;/summary&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">public&lt;/span> &lt;span class="kd">async&lt;/span> &lt;span class="n">Task&lt;/span> &lt;span class="n">GenerateResponseStreamAsync&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">string&lt;/span> &lt;span class="n">prompt&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">CancellationToken&lt;/span> &lt;span class="n">cancellationToken&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(!&lt;/span>&lt;span class="n">_isInitialized&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">await&lt;/span> &lt;span class="n">InitializeAsync&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WriteLine&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">$&amp;#34;\n[사용자 입력]: {prompt}\n[AI 어시스턴트]: &amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 생성 시 하이퍼파라미터 설정&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">var&lt;/span> &lt;span class="n">options&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="n">LanguageModelOptions&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Temperature&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="m">0.7f&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">TopP&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="m">0.9f&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">MaxTokens&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="m">2048&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">RepetitionPenalty&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="m">1.1f&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 대화 컨텍스트 구축&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">var&lt;/span> &lt;span class="n">context&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="n">LanguageModelContext&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">context&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">AddSystemMessage&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;당신은 Windows의 로컬 NPU 상에서 직접 동작하는 고도의 AI 어시스턴트입니다. 단계별로 논리적으로 생각하고 간결하게 답변해 주세요.&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">context&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">AddUserMessage&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">prompt&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">try&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 스트리밍 추론 API 호출&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">var&lt;/span> &lt;span class="n">responseStream&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="n">_languageModel&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">GenerateResponseStreamAsync&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">context&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">options&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// IAsyncEnumerable로 반환되는 청크를 비동기로 반복 처리&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">await&lt;/span> &lt;span class="k">foreach&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">var&lt;/span> &lt;span class="n">chunk&lt;/span> &lt;span class="k">in&lt;/span> &lt;span class="n">responseStream&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WithCancellation&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">cancellationToken&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 생성된 토큰(청크)을 실시간으로 콘솔에 출력&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// UI 애플리케이션의 경우, 여기서 DispatcherQueue를 사용하여 TextBox 등에 반영합니다&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">chunk&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Text&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WriteLine&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">catch&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">OperationCanceledException&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WriteLine&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;\n[사용자 또는 시스템에 의해 생성이 취소되었습니다]&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">catch&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">Exception&lt;/span> &lt;span class="n">ex&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WriteLine&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">$&amp;#34;\n[치명적인 오류가 발생했습니다: {ex.Message}]&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="51-c-구현에서의-아키텍처-해설">5.1 C# 구현에서의 아키텍처 해설
&lt;/h3>&lt;p>이 코드의 핵심은 &lt;code>LanguageModel.CheckAvailabilityAsync()&lt;/code> 에 의한 실행 전 검증과 &lt;code>GenerateResponseStreamAsync&lt;/code> 에 의한 비동기 스트리밍입니다. OS 백그라운드에서 동작하는 Copilot Runtime은 이 API 호출을 받으면 내부적으로 ONNX Runtime을 기동하고, 시스템의 구성에 따라 최적의 Execution Provider(대부분의 최신 PC에서는 DirectML + NPU)를 선택합니다.&lt;/p>
&lt;p>개발자는 모델의 텐서 형태, 토크나이저 구현, KV 캐시의 메모리 관리 등을 전혀 의식하지 않고, 단 몇 줄의 C# 코드로 최첨단 AI 추론 파이프라인을 애플리케이션에 통합할 수 있습니다.&lt;/p>
&lt;h2 id="6-deep-dive-2-c와-directml을-이용한-커스텀-모델의-고속-추론">6. 【Deep Dive 2】 C++와 DirectML을 이용한 커스텀 모델의 고속 추론
&lt;/h2>&lt;p>OS 표준 언어 모델만으로는 커버할 수 없는 특정 도메인(독자적인 이미지 세그멘테이션, 음성 인식, 커스텀 객체 탐지 모델 등)을 다룰 경우, 개발자는 &lt;code>Microsoft.Windows.AI&lt;/code> 의 하위 레이어에 위치하는 ONNX Runtime과 DirectML을 직접 제어해야 합니다.&lt;/p>
&lt;p>C++를 사용함으로써 메모리 할당을 극한까지 최적화하고 NPU/GPU의 최대 성능을 끌어낼 수 있습니다. 다음은 ONNX 형식의 커스텀 모델(예: YOLOv8)을 DirectML을 사용하여 C++로 실행하기 위한, 고급 초기화 및 추론 파이프라인의 핵심 구현입니다.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;span class="lnt">64
&lt;/span>&lt;span class="lnt">65
&lt;/span>&lt;span class="lnt">66
&lt;/span>&lt;span class="lnt">67
&lt;/span>&lt;span class="lnt">68
&lt;/span>&lt;span class="lnt">69
&lt;/span>&lt;span class="lnt">70
&lt;/span>&lt;span class="lnt">71
&lt;/span>&lt;span class="lnt">72
&lt;/span>&lt;span class="lnt">73
&lt;/span>&lt;span class="lnt">74
&lt;/span>&lt;span class="lnt">75
&lt;/span>&lt;span class="lnt">76
&lt;/span>&lt;span class="lnt">77
&lt;/span>&lt;span class="lnt">78
&lt;/span>&lt;span class="lnt">79
&lt;/span>&lt;span class="lnt">80
&lt;/span>&lt;span class="lnt">81
&lt;/span>&lt;span class="lnt">82
&lt;/span>&lt;span class="lnt">83
&lt;/span>&lt;span class="lnt">84
&lt;/span>&lt;span class="lnt">85
&lt;/span>&lt;span class="lnt">86
&lt;/span>&lt;span class="lnt">87
&lt;/span>&lt;span class="lnt">88
&lt;/span>&lt;span class="lnt">89
&lt;/span>&lt;span class="lnt">90
&lt;/span>&lt;span class="lnt">91
&lt;/span>&lt;span class="lnt">92
&lt;/span>&lt;span class="lnt">93
&lt;/span>&lt;span class="lnt">94
&lt;/span>&lt;span class="lnt">95
&lt;/span>&lt;span class="lnt">96
&lt;/span>&lt;span class="lnt">97
&lt;/span>&lt;span class="lnt">98
&lt;/span>&lt;span class="lnt">99
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;string&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;stdexcept&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;onnxruntime_cxx_api.h&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;dml_provider_factory.h&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">CustomVisionAIProcessor&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">private&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Ort&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">Env&lt;/span> &lt;span class="n">env&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Ort&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">Session&lt;/span> &lt;span class="n">session&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="k">nullptr&lt;/span>&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Ort&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">AllocatorWithDefaultOptions&lt;/span> &lt;span class="n">allocator&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">CustomVisionAIProcessor&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">wstring&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">modelPath&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">:&lt;/span> &lt;span class="n">env&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ORT_LOGGING_LEVEL_WARNING&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s">&amp;#34;VisionAIProcessor&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Ort&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">SessionOptions&lt;/span> &lt;span class="n">sessionOptions&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 스레드 수 최적화
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">sessionOptions&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">SetIntraOpNumThreads&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 그래프 최적화 레벨을 최대로 설정
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">sessionOptions&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">SetGraphOptimizationLevel&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">GraphOptimizationLevel&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">ORT_ENABLE_ALL&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 1. DirectML Execution Provider (DML EP) 추가
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// device_id = 0 은 시스템의 기본 권장 어댑터(NPU 또는 고성능 GPU)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="n">OrtApi&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">ortApi&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Ort&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">GetApi&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">OrtDmlApi&lt;/span>&lt;span class="o">*&lt;/span> &lt;span class="n">dmlApi&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">nullptr&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">OrtStatus&lt;/span>&lt;span class="o">*&lt;/span> &lt;span class="n">status&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">ortApi&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">GetExecutionProviderApi&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;DML&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">ORT_API_VERSION&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">reinterpret_cast&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="o">**&amp;gt;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">dmlApi&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">status&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="k">nullptr&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="n">dmlApi&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="k">nullptr&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Ort&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">ThrowOnError&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">dmlApi&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">SessionOptionsAppendExecutionProvider_DML&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sessionOptions&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Info] DirectML Execution Provider를 정상적으로 연결했습니다.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Warning] DirectML API 가져오기에 실패했습니다. CPU 폴백 모드로 실행합니다.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">status&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="k">nullptr&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="n">ortApi&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">ReleaseStatus&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">status&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 2. 모델 로드 및 세션 생성
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">try&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">session&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Ort&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">Session&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">env&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">modelPath&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">c_str&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">sessionOptions&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Info] ONNX 모델 로드에 성공하고 연산 그래프가 컴파일되었습니다.&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">catch&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">Ort&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">Exception&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">e&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Error] 모델 로드 실패: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">e&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">what&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">throw&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="nf">RunInference&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">float&lt;/span>&lt;span class="o">&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">imageTensor&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int64_t&lt;/span>&lt;span class="o">&amp;gt;&amp;amp;&lt;/span> &lt;span class="n">inputShape&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 3. 입력 텐서 버퍼 생성
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">Ort&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">MemoryInfo&lt;/span> &lt;span class="n">memoryInfo&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Ort&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">MemoryInfo&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">CreateCpu&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">OrtArenaAllocator&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">OrtMemTypeDefault&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Ort&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">Value&lt;/span> &lt;span class="n">inputTensor&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Ort&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">Value&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">CreateTensor&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">float&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">memoryInfo&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">const_cast&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">float&lt;/span>&lt;span class="o">*&amp;gt;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">imageTensor&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">()),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">imageTensor&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">inputShape&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">inputShape&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 4. 입출력 노드 이름 동적 획득
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">auto&lt;/span> &lt;span class="n">inputNamePtr&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">session&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">GetInputNameAllocated&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">allocator&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="n">outputNamePtr&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">session&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">GetOutputNameAllocated&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">allocator&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">const&lt;/span> &lt;span class="kt">char&lt;/span>&lt;span class="o">*&lt;/span> &lt;span class="n">inputNames&lt;/span>&lt;span class="p">[]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">inputNamePtr&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">const&lt;/span> &lt;span class="kt">char&lt;/span>&lt;span class="o">*&lt;/span> &lt;span class="n">outputNames&lt;/span>&lt;span class="p">[]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">outputNamePtr&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 5. 추론 실행 (DirectML을 통해 NPU/GPU로 오프로드됨)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Info] 추론 엔진 실행을 시작합니다...&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="n">startTime&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">chrono&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">high_resolution_clock&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">now&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="n">outputTensors&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">session&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Run&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Ort&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">RunOptions&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="k">nullptr&lt;/span>&lt;span class="p">},&lt;/span> &lt;span class="n">inputNames&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">inputTensor&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">outputNames&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="n">endTime&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">chrono&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">high_resolution_clock&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">now&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="n">duration&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">chrono&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">duration_cast&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">chrono&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">milliseconds&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">endTime&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">startTime&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 6. 결과 텐서 획득 및 분석
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">float&lt;/span>&lt;span class="o">*&lt;/span> &lt;span class="n">outputData&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">outputTensors&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">front&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="n">GetTensorMutableData&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">float&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">size_t&lt;/span> &lt;span class="n">outputSize&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">outputTensors&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">front&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="n">GetTensorTypeAndShapeInfo&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="n">GetElementCount&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Result] 추론 완료: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">duration&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">count&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; ms&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;[Result] 출력 텐서의 요소 수: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">outputSize&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ※ 이 후, 출력 텐서에 대해 NMS(Non-Maximum Suppression)나 바운딩 박스 그리기 처리를 구현합니다
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">try&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 실행할 ONNX 모델의 경로
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">CustomVisionAIProcessor&lt;/span> &lt;span class="n">processor&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">L&lt;/span>&lt;span class="s">&amp;#34;models/yolov8n_quantized.onnx&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 추론용 더미 이미지 데이터 (배치 크기 1 x 3 채널 x 640 x 640)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int64_t&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">inputShape&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">640&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">640&lt;/span>&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">float&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">dummyImage&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="mi">3&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="mi">640&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="mi">640&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">0.5f&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">processor&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">RunInference&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">dummyImage&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">inputShape&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">catch&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">exception&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">e&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;프로그램이 비정상 종료되었습니다: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">e&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">what&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="61-c에서의-메모리-관리와-제로-카피-추론의-중요성">6.1 C++에서의 메모리 관리와 제로 카피 추론의 중요성
&lt;/h3>&lt;p>C++에서 DirectML을 사용하는 최대의 장점은 DirectX 12(DX12)와의 긴밀한 통합이 가능하다는 점입니다. 위의 코드는 교육적 관점에서 표준적인 CPU 메모리로부터의 데이터 복사를 포함하고 있지만, 실제 게임 엔진이나 영상 처리 애플리케이션에서는 DX12를 사용하여 이미지(텍스처)를 이미 GPU나 NPU의 메모리 공간에 유지하고 있는 경우가 많습니다.&lt;/p>
&lt;p>이 경우, &lt;code>OrtDmlApi&lt;/code> 의 고급 바인딩 기능을 이용하여 DX12의 리소스를 직접 ONNX Runtime의 텐서로 매핑하는 &amp;ldquo;&lt;strong>제로 카피 추론(Zero-Copy Inference)&lt;/strong>&amp;ldquo;을 구현할 수 있습니다. 이를 통해 PCIe 버스 간의 데이터 전송 오버헤드(앞서 언급한 대역폭 $BW$ 의 소비)가 완전히 사라져, 실시간 동영상 처리에서의 프레임 속도가 극적으로 향상됩니다.&lt;/p>
&lt;h2 id="7-성능-최적화와-모범-사례">7. 성능 최적화와 모범 사례
&lt;/h2>&lt;p>Windows AI API나 DirectML을 활용하여 최상급의 AI 애플리케이션을 개발할 때의 필수적인 최적화 전략을 아래에 정리합니다.&lt;/p>
&lt;h3 id="71-모델-양자화quantization와-olive-toolkit">7.1 모델 양자화(Quantization)와 Olive Toolkit
&lt;/h3>&lt;p>NPU의 진정한 힘을 발휘시키려면, AI 모델의 가중치와 활성화 값을 FP32(단정밀도 부동소수점)에서 INT8 또는 INT4로 **양자화(Quantization)**하는 것이 절대적인 조건입니다. NPU의 아키텍처는 정수 연산에 특화되어 있어, FP32와 비교해 INT8에서는 이론상 4배의 처리량과 대폭적인 전력 절감을 실현합니다.&lt;/p>
&lt;p>Microsoft가 제공하는 &lt;code>Olive (ONNX Live)&lt;/code> 툴체인을 사용하면 PyTorch 등의 모델을 Windows 환경에 맞게 자동 최적화할 수 있습니다. Olive는 Transformer 모델에 대한 특수한 어텐션 최적화나 하드웨어별 그래프 컴파일을 강력하게 지원합니다.&lt;/p>
&lt;h3 id="72-배치-처리-vs-대화형-스트리밍의-트레이드오프">7.2 배치 처리 vs 대화형 스트리밍의 트레이드오프
&lt;/h3>&lt;p>API 호출에 있어 여러 추론 요청을 묶어서 배치(Batch) 처리함으로써 NPU의 사용 효율(Compute Utilization)을 높일 수 있습니다. 그러나 챗봇과 같은 대화형 UI의 경우, 처리량보다도 첫 번째 토큰이 표시될 때까지의 시간(TTFT: Time To First Token)이 사용자 경험(UX)을 결정짓습니다.
따라서 대화형 UI에서는 배치 크기를 1로 설정하고, 스트리밍 생성을 우선하는 설계가 모범 사례가 됩니다.&lt;/p>
&lt;h3 id="73-백그라운드-작업과-os의-연동">7.3 백그라운드 작업과 OS의 연동
&lt;/h3>&lt;p>AI 추론은 로컬 전력과 시스템 리소스를 대량으로 소비합니다. Windows의 &lt;code>App Lifecycle API&lt;/code> 와 연동하여, 애플리케이션이 백그라운드로 전환될 때는 우선순위가 낮은 추론 작업을 일시 중단(Suspend)하거나 리소스 소비를 줄이는 구현이 요구됩니다.&lt;/p>
&lt;div class="mermaid">sequenceDiagram
participant User as "사용자"
participant App as "Windows 앱 (C#)"
participant API as "Microsoft.Windows.AI"
participant OS as "Windows Copilot Runtime"
participant ORT as "ONNX Runtime (DML)"
participant NPU as "NPU 하드웨어"
User->>App: "프롬프트 입력"
App->>API: "GenerateResponseStreamAsync()"
API->>OS: "추론 작업 디스패치"
OS->>ORT: "그래프 실행 요청"
ORT->>NPU: "DirectML을 통한 명령 목록 실행"
NPU-->>ORT: "계산 완료 (1 토큰 생성)"
ORT-->>OS: "텐서 결과"
OS-->>API: "디코딩된 텍스트"
API-->>App: "IAsyncEnumerable&lt;string> 청크"
App-->>User: "UI로의 실시간 문자 렌더링"
Note over ORT,NPU: "완료될 때까지 이 루프를 고속으로 반복"&lt;/div>
&lt;p>이 시퀀스 다이어그램은 UI 스레드를 전혀 차단하지 않고, 최하층의 NPU 하드웨어에서 애플리케이션의 프레젠테이션 계층까지 데이터가 흐르듯이 스트리밍되는 비동기 처리의 아름다움을 보여줍니다.&lt;/p>
&lt;h2 id="8-향후-전망과-windows-ai의-진화">8. 향후 전망과 Windows AI의 진화
&lt;/h2>&lt;p>&lt;code>Microsoft.Windows.AI&lt;/code> API와 Copilot Runtime은 현재 진행형으로 급속한 진화를 거듭하고 있습니다. 향후 개발자 대상 업데이트에서는 다음과 같은 패러다임 전환이 기대됩니다.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>멀티모달 API의 OS 네이티브 통합&lt;/strong>: 텍스트뿐만 아니라 음성, 이미지, 나아가 라이브 비디오 피드를 매끄럽게 동시 처리하여 크로스모달 AI 추론을 OS 수준에서 기본 제공.&lt;/li>
&lt;li>&lt;strong>RAG(Retrieval-Augmented Generation) 시스템 수준 지원&lt;/strong>: 로컬 PC 내의 개인 문서들이나 Windows Search의 인덱스와 AI 모델을 OS의 안전한 샌드박스 내에서 연동시켜, 사용자의 프라이버시를 완벽히 보호한 상태에서의 초고도 개인 AI 어시스턴트 구축.&lt;/li>
&lt;li>&lt;strong>NPU의 동적 리소스 스케일링&lt;/strong>: 여러 AI 애플리케이션(예를 들어, 백그라운드에서의 노이즈 캔슬링과 포그라운드에서의 코드 생성)이 동시에 가동될 때, Windows 커널 스케줄러가 NPU의 실행 컨텍스트를 동적으로 전환하여 QoS(Quality of Service)를 보장하는 메커니즘.&lt;/li>
&lt;/ul>
&lt;h2 id="9-결론-로컬-ai가-바꾸는-애플리케이션의-미래">9. 결론: 로컬 AI가 바꾸는 애플리케이션의 미래
&lt;/h2>&lt;p>Windows 11의 Copilot Runtime과 &lt;code>Microsoft.Windows.AI&lt;/code> API는 모든 Windows 개발자에게 &amp;lsquo;로컬 AI&amp;rsquo;라는 극히 강력한 무기를 가져다주었습니다. 이제 클라우드 API에 전적으로 의존할 필요가 없습니다. 지연 시간을 없애고 프라이버시를 굳건히 지키면서도, 오프라인에서 완벽하게 작동하는 차세대 AI 경험을 사용자에게 제공하는 것이 가능해졌습니다.&lt;/p>
&lt;p>본 기사에서 해설한 C#을 이용한 시스템 표준 언어 모델의 통합, 수리적인 성능 평가, 그리고 C++와 DirectML을 이용한 극한의 하드웨어 최적화 지식을 활용하여, 여러분의 손으로 차세대 &amp;ldquo;AI 네이티브&amp;rdquo; Windows 애플리케이션을 창조해 보세요. AI가 가져올 무한한 가능성은 여러분이 작성하는 코드의 바로 앞에 펼쳐져 있습니다.&lt;/p>
&lt;hr>
&lt;p>&lt;em>※ 주의사항: 이 기사는 2026년 9월 현재의 프리뷰 버전 API 및 최신 사양을 바탕으로 작성되었습니다. Windows 업데이트에 따라 API 사양이나 하드웨어 요구 사항이 변경될 수 있으므로, 구현 시에는 반드시 Microsoft Learn의 공식 문서를 함께 참조해 주시기 바랍니다.&lt;/em>&lt;/p></description></item><item><title>【2026년 최신】 로컬 LLM을 Windows 환경에서 구동하는 완전 가이드</title><link>http://kenji.blog/ko/p/local-llm-windows-2026/</link><pubDate>Fri, 11 Sep 2026 10:00:00 +0900</pubDate><guid>http://kenji.blog/ko/p/local-llm-windows-2026/</guid><description>&lt;img src="http://kenji.blog/p/local-llm-windows-2026/img/eyecatch.jpg" alt="Featured image of post 【2026년 최신】 로컬 LLM을 Windows 환경에서 구동하는 완전 가이드" />&lt;h1 id="1-소개-왜-지금-windows에서-로컬-llm인가">1. 소개: 왜 지금 Windows에서 로컬 LLM인가?
&lt;/h1>&lt;p>2026년 현재, 생성형 AI와 대규모 언어 모델(LLM)의 진화는 클라우드 상의 거대한 API 서비스에서 개인 PC나 온프레미스 환경에서 동작하는 &amp;lsquo;로컬 LLM&amp;rsquo;으로 큰 패러다임 전환을 보여주고 있습니다. OpenAI의 GPT-5나 Anthropic의 Claude 3.5와 같은 클라우드 AI는 매우 강력하지만, 기업이나 개인이 모든 데이터를 클라우드로 전송할 수 있는 것은 아닙니다. 개인정보 보호, 보안, 대기 시간(레이턴시), 그리고 장기적이고 지속 가능한 비용 관점에서 로컬 LLM에 대한 수요는 그 어느 때보다 폭발적으로 증가하고 있습니다.&lt;/p>
&lt;p>특히 Windows 환경에서 로컬 LLM 생태계의 발전은 눈부십니다. 몇 년 전까지만 해도 &amp;ldquo;AI 개발 및 실행은 Linux&amp;quot;라는 것이 상식이었지만, 2026년 현재 Windows는 매우 강력하고 편리한 AI 플랫폼으로 변모했습니다.&lt;/p>
&lt;p>본 기사에서는 2026년 최신 기술 동향을 바탕으로 Windows 환경에서 로컬 LLM을 구축, 운영 및 최적화하기 위한 완전한 가이드를 제공합니다. 초보자를 위한 Ollama를 사용한 간단한 구축부터, 고급 사용자를 위한 llama.cpp를 활용한 극한의 최적화, 나아가 VRAM 계산의 수학적 접근 및 아키텍처에 대한 깊은 이해, 그리고 로컬에서의 파인튜닝(미세조정)까지 압도적인 분량으로 철저하게 해설합니다.&lt;/p>
&lt;h2 id="11-2026년-로컬-llm을-둘러싼-기술-트렌드">1.1 2026년 로컬 LLM을 둘러싼 기술 트렌드
&lt;/h2>&lt;p>현재의 로컬 LLM 생태계를 형성하는 주요 트렌드는 다음과 같습니다.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>GGUF 포맷의 완전한 보급&lt;/strong>: 메타데이터와 텐서를 단일 파일로 통합한 GGUF(GPT-Generated Unified Format)가 완전히 사실상 표준(De facto standard)이 되었습니다. 이를 통해 Hugging Face에서 파일 하나를 다운로드하는 것만으로 어떤 환경에서든 실행할 수 있게 되었습니다.&lt;/li>
&lt;li>&lt;strong>MoE(Mixture of Experts) 아키텍처의 대중화&lt;/strong>: 소규모이면서도 고성능인 MoE 모델이 다수 출시되었으며, 추론 시 일부 전문가(Expert)만 활성화함으로써 일반 소비자용 PC의 계산 부하를 억제하면서 거대 모델에 필적하는 성능을 내고 있습니다.&lt;/li>
&lt;li>&lt;strong>추론 엔진의 고도화된 추상화 및 최적화&lt;/strong>: Ollama, LM Studio, AnythingLLM 등의 도구가 세련되어져서 사용자가 CUDA 드라이버 설치 등 복잡한 의존성을 신경 쓸 필요가 없어졌습니다. 또한 FlashAttention 3의 Windows 네이티브 지원으로 추론 속도가 극적으로 향상되었습니다.&lt;/li>
&lt;li>&lt;strong>NPU 활용과 Windows Copilot+ PC의 대두&lt;/strong>: GPU가 없는 노트북에서도 탑재된 NPU(Neural Processing Unit)를 활용하여 소규모 LLM(SLM: Small Language Models)을 저전력으로 구동하는 기술이 실용화 단계에 접어들었습니다.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="2-하드웨어-요구-사항-및-os-준비">2. 하드웨어 요구 사항 및 OS 준비
&lt;/h1>&lt;p>로컬 LLM을 실용적인 속도(초당 15~30 토큰 이상)로 구동하기 위해서는 하드웨어 선택이 가장 중요합니다.&lt;/p>
&lt;h2 id="21-권장-하드웨어-구성">2.1 권장 하드웨어 구성
&lt;/h2>&lt;p>AI PC의 진화에 따라 요구 스펙도 변화하고 있습니다.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>OS&lt;/strong>: Windows 11 Pro (24H2 이후). WSL2의 완전한 기능과 고급 메모리 관리, 나아가 DirectML의 최신 API를 활용하기 위해 필수적입니다.&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: Intel Core Ultra 200 시리즈 이상 또는 AMD Ryzen 9000 시리즈 이상. CPU 추론을 병행할 경우, 광대역 메모리 통신이 필수적입니다.&lt;/li>
&lt;li>&lt;strong>RAM&lt;/strong>: 최소 32GB, 권장 64GB 이상. 메인 메모리의 대역폭(MB/s)이 CPU 추론 시나 오프로드(Offload) 시 결정적인 병목 지점이 됩니다. DDR5-6000 이상의 고속 메모리가 이상적입니다.&lt;/li>
&lt;li>&lt;strong>GPU&lt;/strong>: NVIDIA RTX 4000/5000 시리즈. 로컬 LLM에서 가장 중요한 것은 연산 성능이 아니라 &amp;lsquo;VRAM 용량&amp;rsquo;입니다.
&lt;ul>
&lt;li>&lt;strong>엔트리&lt;/strong>: RTX 4060 Ti (16GB 버전) - 가성비 최강. 8B~14B 클래스의 모델에 최적입니다.&lt;/li>
&lt;li>&lt;strong>미들레인지&lt;/strong>: RTX 4070 Ti SUPER (16GB) / RTX 4080 SUPER (16GB)&lt;/li>
&lt;li>&lt;strong>하이엔드&lt;/strong>: RTX 4090 (24GB) / RTX 5090 (32GB) - 30B~70B 클래스의 양자화 모델을 구동하기 위해 필요합니다.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>스토리지&lt;/strong>: PCIe Gen4 또는 Gen5 NVMe SSD. 수십 GB에 달하는 모델 로드 시간을 극적으로 단축시킵니다.&lt;/li>
&lt;/ul>
&lt;h2 id="22-wsl2-windows-subsystem-for-linux-2-설정">2.2 WSL2 (Windows Subsystem for Linux 2) 설정
&lt;/h2>&lt;p>많은 GUI 도구는 Windows 네이티브로 동작하지만, Python을 사용한 개발, 최신 도구 컴파일, 후술할 LoRA 파인튜닝에는 WSL2가 매우 편리합니다. Windows 11의 최신 환경에서는 호스트 쪽에 NVIDIA 드라이버를 설치하는 것만으로 WSL2에서 투명하게 GPU(CUDA)를 사용할 수 있습니다.&lt;/p>
&lt;p>관리자 권한으로 PowerShell을 열고 다음을 실행합니다.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># WSL2와 최신 Ubuntu 설치&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">wsl&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-install&lt;/span> &lt;span class="n">-d&lt;/span> &lt;span class="n">Ubuntu&lt;/span>&lt;span class="p">-&lt;/span>&lt;span class="mf">24.04&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 커널 업데이트&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">wsl&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-update&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>설치 후 WSL2 터미널 내에서 &lt;code>nvidia-smi&lt;/code>를 실행하여 GPU가 정상적으로 인식되면 성공입니다.&lt;/p>
&lt;hr>
&lt;h1 id="3-로컬-llm-아키텍처-및-추론-메커니즘">3. 로컬 LLM 아키텍처 및 추론 메커니즘
&lt;/h1>&lt;p>로컬 환경에서 모델이 어떻게 텍스트를 생성하는지, 그 내부 구조를 이해하는 것은 문제 해결(트러블슈팅)이나 최적화에 매우 유용합니다.&lt;/p>
&lt;p>다음 Mermaid 다이어그램은 전형적인 로컬 LLM의 추론 파이프라인을 보여줍니다.&lt;/p>
&lt;div class="mermaid">graph TD
User["사용자 입력 (프롬프트)"] --> Tokenizer["토크나이저 (Tokenizer)"]
Tokenizer --> Embedding["임베딩 계층 (Embedding)"]
subgraph "Transformer Block (x Layers)"
Embedding --> Attn["자기 주의 (Self-Attention)"]
Attn --> KVCache["KV 캐시 (Key/Value 유지)"]
Attn --> FFN["피드 포워드 네트워크 (FFN)"]
end
FFN --> Logits["로짓 계산 (Logits)"]
Logits --> Sampler["샘플러 (Temperature, Top-K, Top-P)"]
Sampler --> OutputToken["출력 토큰"]
OutputToken --> |"자기 회귀 생성 (Autoregressive)"| Tokenizer
OutputToken --> Decoder["디토크나이저 (Detokenizer)"]
Decoder --> FinalOutput["최종 출력 텍스트"]&lt;/div>
&lt;h2 id="31-2가지-단계-prefill과-decode">3.1 2가지 단계: Prefill과 Decode
&lt;/h2>&lt;p>LLM의 텍스트 생성은 계산 특성이 다른 두 가지 단계로 나뉩니다.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Prefill (프롬프트 처리) 단계&lt;/strong>: 입력된 프롬프트 전체를 한 번에 처리하고 이해하는 단계입니다. 병렬 계산이 가능하므로 GPU의 계산 능력(FLOPS)이 속도에 직결됩니다. 프롬프트가 길 경우 이 단계에 몇 초가 걸릴 수 있습니다.&lt;/li>
&lt;li>&lt;strong>Decode (토큰 생성) 단계&lt;/strong>: 1 토큰씩 예측하고 다음 입력으로 넘기는(자기 회귀, Autoregressive) 단계입니다. 이 단계에서는 병렬 계산이 제한되므로 GPU의 VRAM 대역폭(Memory Bandwidth)이 결정적인 병목 지점이 됩니다.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="4-vram-소비량-계산-및-모델-크기의-수학적-이해">4. VRAM 소비량 계산 및 모델 크기의 수학적 이해
&lt;/h1>&lt;p>&amp;ldquo;내 PC에서 어떤 모델이 돌아갈까?&amp;ldquo;를 정확히 판단하려면 VRAM 계산 공식을 이해해야 합니다. VRAM 부족으로 인해 시스템 메모리(RAM)로의 폴백(Fallback)이 발생하면 추론 속도는 10배~100배 느려집니다.&lt;/p>
&lt;h2 id="41-파라미터-크기-기반-기본-vram">4.1 파라미터 크기 기반 기본 VRAM
&lt;/h2>&lt;p>모델의 가중치(웨이트)를 VRAM에 로드하기 위한 메모리 양입니다.
모델 크기 $P$ (파라미터 수, 단위: 10억 = 1B)와 1 파라미터당 바이트 수 $B$를 사용하여 계산합니다.&lt;/p>
$$
V_{base} = P \times B \quad \text{(GB)}
$$
&lt;p>예를 들어, 8B(80억) 파라미터 모델을 FP16(반정밀도 부동소수점, 16비트=2바이트)으로 로드할 경우:&lt;/p>
$$
V_{base} = 8 \times 2 = 16 \text{ GB}
$$
&lt;p>즉, 16GB VRAM을 가진 GPU라도 모델을 로드하는 것만으로 거의 한계에 도달하게 됩니다.&lt;/p>
&lt;h2 id="42-양자화quantization의-마법">4.2 양자화(Quantization)의 마법
&lt;/h2>&lt;p>여기서 &amp;lsquo;양자화&amp;rsquo;가 등장합니다. 파라미터의 정밀도를 낮춰 모델 크기를 극적으로 축소합니다. 가장 일반적인 4bit 양자화(예: Q4_K_M)의 경우, 1 파라미터당 평균 약 0.55바이트가 됩니다.&lt;/p>
$$
V_{base\_4bit} = 8 \times 0.55 = 4.4 \text{ GB}
$$
&lt;p>이를 통해 16GB의 VRAM이 있다면 충분한 여유를 가지고 8B 모델을 구동할 수 있습니다.&lt;/p>
&lt;h2 id="43-kv-캐시-계산-gqa-지원-버전">4.3 KV 캐시 계산 (GQA 지원 버전)
&lt;/h2>&lt;p>추론 시에는 과거의 문맥을 유지하기 위한 &amp;lsquo;KV 캐시&amp;rsquo;가 VRAM을 소비합니다. Llama 3 등 최신 모델에서는 메모리 절약을 위해 GQA(Grouped Query Attention)가 채택되었습니다.&lt;/p>
&lt;p>KV 캐시 소비량 $V_{kv}$ (기가바이트)는 다음 수식으로 표현됩니다.&lt;/p>
$$
V_{kv} = 2 \times b \times s \times l \times \left( \frac{h_{kv}}{h_q} \right) \times h_q \times d \times B_{kv} \div 10^9
$$
&lt;p>정리하면, 키와 값의 헤드 수 $h_{kv}$를 사용하여 단순하게 계산할 수 있습니다.&lt;/p>
$$
V_{kv} = 2 \times b \times s \times l \times h_{kv} \times d \times B_{kv} \div 10^9
$$
&lt;p>여기서:&lt;/p>
&lt;ul>
&lt;li>$b$: 배치 크기 (개인의 로컬 사용이라면 보통 1)&lt;/li>
&lt;li>$s$: 시퀀스 길이 (컨텍스트 길이, 예: 8192)&lt;/li>
&lt;li>$l$: 레이어 수 (예: 32)&lt;/li>
&lt;li>$h_{kv}$: KV 헤드 수 (예: 8)&lt;/li>
&lt;li>$d$: 헤드당 차원 수 (예: 128)&lt;/li>
&lt;li>$B_{kv}$: KV 캐시의 바이트 수 (FP16이면 2)&lt;/li>
&lt;/ul>
&lt;p>계산 예 (Llama 3 8B, 컨텍스트 8192, FP16 캐시):
$V_{kv} = 2 \times 1 \times 8192 \times 32 \times 8 \times 128 \times 2 \div 10^9 \approx 1.07 \text{ GB}$&lt;/p>
&lt;p>컨텍스트 길이 $s$를 길게 할수록 필요한 VRAM은 선형적으로 증가한다는 점에 주의하십시오.&lt;/p>
&lt;hr>
&lt;h1 id="5-실전-1-ollama를-이용한-가장-빠르고-짧은-설정">5. 실전 1: Ollama를 이용한 가장 빠르고 짧은 설정
&lt;/h1>&lt;p>이론을 이해했으니, 실제로 Windows 환경에서 LLM을 구동해 봅시다.
2026년 현재 가장 사용자 친화적인 도구가 &amp;lsquo;Ollama&amp;rsquo;입니다. Docker와 유사한 직관적인 CLI를 제공합니다.&lt;/p>
&lt;h2 id="51-설치-및-실행">5.1 설치 및 실행
&lt;/h2>&lt;ol>
&lt;li>&lt;a class="link" href="https://ollama.com/" target="_blank" rel="noopener"
>Ollama 공식 웹사이트&lt;/a>에서 Windows 버전 설치 프로그램을 다운로드하여 실행합니다.&lt;/li>
&lt;li>PowerShell을 열고 다음 명령어를 입력합니다. 여기서는 일본어/한국어 등을 지원하는 &lt;code>llama3:8b&lt;/code>를 사용합니다.&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">ollama&lt;/span> &lt;span class="n">run&lt;/span> &lt;span class="n">llama3&lt;/span>&lt;span class="err">:&lt;/span>&lt;span class="n">8b&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>최초 실행 시 모델 다운로드가 진행됩니다. 완료되면 터미널에서 바로 대화가 가능합니다.&lt;/p>
&lt;h2 id="52-modelfile을-통한-사용자-정의-ai-생성">5.2 Modelfile을 통한 사용자 정의 AI 생성
&lt;/h2>&lt;p>특정 페르소나를 가진 AI를 쉽게 생성할 수 있습니다. 임의의 위치에 &lt;code>Modelfile&lt;/code>을 생성합니다.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">FROM llama3:8b
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">SYSTEM &amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">당신은 매우 뛰어난 시니어 소프트웨어 엔지니어입니다.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">사용자의 질문에 대해 반드시 코드 예시를 곁들여 논리적이고 간결하게 답변해 주세요.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PARAMETER temperature 0.3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PARAMETER num_ctx 8192
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>다음 명령어로 자체 모델을 빌드하고 실행합니다.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">ollama&lt;/span> &lt;span class="n">create&lt;/span> &lt;span class="n">SeniorDev&lt;/span> &lt;span class="o">-f&lt;/span> &lt;span class="p">./&lt;/span>&lt;span class="n">Modelfile&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ollama&lt;/span> &lt;span class="n">run&lt;/span> &lt;span class="n">SeniorDev&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="53-외부-앱-ai-에디터에서-활용">5.3 외부 앱 (AI 에디터)에서 활용
&lt;/h2>&lt;p>Ollama는 &lt;code>http://localhost:11434&lt;/code>에 OpenAI 호환 API 엔드포인트를 공개합니다.
Cursor나 Continue.dev와 같은 VS Code 확장 프로그램의 백엔드 설정에서 URL을 위와 같이 지정하고, 모델 이름에 &lt;code>SeniorDev&lt;/code> 등을 지정하기만 하면 무료로 강력한 로컬 코딩 어시스턴트가 실현됩니다.&lt;/p>
&lt;hr>
&lt;h1 id="6-실전-2-llamacpp에-의한-극한의-성능-튜닝">6. 실전 2: llama.cpp에 의한 극한의 성능 튜닝
&lt;/h1>&lt;p>세밀한 메모리 관리나 최신 포맷(EXL2나 IQ 양자화 등)을 가장 먼저 시도해보고 싶다면, 핵심 엔진인 &lt;code>llama.cpp&lt;/code>를 직접 조작합니다.&lt;/p>
&lt;h2 id="61-llamacpp-빌드-절차">6.1 llama.cpp 빌드 절차
&lt;/h2>&lt;p>Windows 환경에서는 CUDA Toolkit과 CMake를 사용하여 소스에서 빌드하는 것이 가장 좋습니다.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">git&lt;/span> &lt;span class="n">clone&lt;/span> &lt;span class="n">https&lt;/span>&lt;span class="err">:&lt;/span>&lt;span class="p">//&lt;/span>&lt;span class="n">github&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">com&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">ggerganov&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">llama&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cpp
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd &lt;/span>&lt;span class="n">llama&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cpp
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">&lt;/span>&lt;span class="n">mkdir&lt;/span> &lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd &lt;/span>&lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># CUDA 지원으로 구성하고 컴파일&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cmake&lt;/span> &lt;span class="p">..&lt;/span> &lt;span class="n">-DLLAMA_CUBLAS&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="n">ON&lt;/span> &lt;span class="n">-DBUILD_SHARED_LIBS&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="n">OFF&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cmake&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-build&lt;/span> &lt;span class="p">.&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-config&lt;/span> &lt;span class="n">Release&lt;/span> &lt;span class="n">-j&lt;/span> &lt;span class="mf">16&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="62-서버-모드에서의-고급-실행">6.2 서버 모드에서의 고급 실행
&lt;/h2>&lt;p>빌드된 &lt;code>llama-server.exe&lt;/code>를 사용하여 모델을 호스팅합니다.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="p">.\&lt;/span>&lt;span class="n">bin&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Release&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="nb">llama-server&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">exe&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-model&lt;/span> &lt;span class="s2">&amp;#34;C:\models\Llama-3-8B-Instruct.Q4_K_M.gguf&amp;#34;&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-ctx-size&lt;/span> &lt;span class="mf">8192&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-n-gpu-layers&lt;/span> &lt;span class="mf">99&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-threads&lt;/span> &lt;span class="mf">8&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-flash-attn&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-port&lt;/span> &lt;span class="mf">8080&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;ul>
&lt;li>&lt;code>--n-gpu-layers 99&lt;/code>: 가능한 모든 레이어를 GPU VRAM으로 오프로드합니다.&lt;/li>
&lt;li>&lt;code>--flash-attn&lt;/code>: FlashAttention 3을 활성화하여 추론 속도를 향상시키고 KV 캐시의 VRAM 소비를 줄입니다.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h1 id="7-gui-프론트엔드-lm-studio-및-로컬-rag-구축">7. GUI 프론트엔드: LM Studio 및 로컬 RAG 구축
&lt;/h1>&lt;p>명령줄(CLI)에 거부감이 있거나 RAG(검색 증강 생성)를 직관적으로 수행하고 싶은 경우 GUI를 이용합니다.&lt;/p>
&lt;h2 id="71-lm-studio">7.1 LM Studio
&lt;/h2>&lt;p>LM Studio는 모델 검색, 다운로드, 시스템 요구 사항 사전 확인, 그리고 채팅 UI까지 하나로 통합한 훌륭한 애플리케이션입니다. 앱 내의 &amp;ldquo;Local Server&amp;rdquo; 버튼을 누르기만 하면 OpenAI 호환 API가 시작됩니다.&lt;/p>
&lt;h2 id="72-anythingllm을-이용한-rag-아키텍처">7.2 AnythingLLM을 이용한 RAG 아키텍처
&lt;/h2>&lt;p>사내 문서나 개인 메모를 읽게 하는 RAG 환경의 아키텍처 다이어그램입니다.&lt;/p>
&lt;div class="mermaid">graph LR
Document["문서 (PDF, MD)"] --> Chunking["청크 분할 (Chunking)"]
Chunking --> EmbedModel["임베딩 모델"]
EmbedModel --> VectorDB["벡터 데이터베이스"]
UserQuery["사용자 질문"] --> EmbedQuery["질문 임베딩"]
EmbedQuery --> VectorDB
VectorDB --> |"유사도 검색"| RetrievedDocs["관련 문서 추출"]
UserQuery --> PromptBuilder["프롬프트 생성"]
RetrievedDocs --> PromptBuilder
PromptBuilder --> LocalLLM["로컬 LLM"]
LocalLLM --> Answer["최종 답변"]&lt;/div>
&lt;p>AnythingLLM 데스크톱 버전(Windows)을 사용하면 설정 화면에서 Ollama(LLM 및 Embedding)를 지정하고, 로컬 VectorDB(LanceDB)를 사용하도록 설정하는 것만으로 몇 분 만에 이 아키텍처가 완성됩니다. 데이터를 외부에 전혀 전송하지 않는 프라이빗 AI의 탄생입니다.&lt;/p>
&lt;hr>
&lt;h1 id="8-windows-wsl2-상에서의-파인튜닝-lora">8. Windows WSL2 상에서의 파인튜닝 (LoRA)
&lt;/h1>&lt;p>로컬에서 구동할 뿐만 아니라 내 데이터로 모델을 똑똑하게 만들고 싶다면, LoRA(Low-Rank Adaptation)를 이용한 파인튜닝이 가능합니다. 2026년 현재 &amp;lsquo;Unsloth&amp;rsquo;라는 라이브러리를 사용하면 Windows의 WSL2 환경에서 16GB VRAM으로도 8B 모델의 학습을 몇 시간 만에 완료할 수 있습니다.&lt;/p>
&lt;p>WSL2의 Ubuntu 내에서 다음을 실행하여 환경을 구축합니다.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">conda create --name unsloth_env &lt;span class="nv">python&lt;/span>&lt;span class="o">=&lt;/span>3.11
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">conda activate unsloth_env
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install &lt;span class="s2">&amp;#34;unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install --no-deps trl peft accelerate bitsandbytes
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Unsloth는 CUDA 커널을 극한까지 최적화하여, 표준 Hugging Face 라이브러리와 비교해 학습 속도가 약 2배, VRAM 소비량이 약 절반이 됩니다. Jupyter Notebook을 실행하고 데이터 세트(JSONL 형식)를 읽어 들이는 것만으로, VRAM 12GB~16GB의 RTX 4060 Ti 등에서도 몇 에포크(epoch)의 학습이 가능합니다.&lt;/p>
&lt;hr>
&lt;h1 id="9-성능-및-문제-해결-트러블슈팅">9. 성능 및 문제 해결 (트러블슈팅)
&lt;/h1>&lt;p>자주 직면하는 문제와 그 해결책입니다.&lt;/p>
&lt;h3 id="1-추론-속도가-극단적으로-느림-12-tokenss">1. 추론 속도가 극단적으로 느림 (1~2 tokens/s)
&lt;/h3>&lt;p>&lt;strong>원인&lt;/strong>: 모델이 VRAM에 다 들어가지 못하고 시스템 메모리(RAM)로 오프로드되었습니다.
&lt;strong>대책&lt;/strong>: 작업 관리자에서 &amp;ldquo;전용 GPU 메모리&amp;quot;를 확인해 주세요. 한계에 도달한 경우 컨텍스트 크기(&lt;code>-c&lt;/code>)를 줄이거나 더 낮은 비트 수의 양자화 모델(Q4_K_M 등)을 사용하십시오.&lt;/p>
&lt;h3 id="2-cuda-out-of-memory-에러">2. &amp;ldquo;CUDA out of memory&amp;rdquo; 에러
&lt;/h3>&lt;p>&lt;strong>원인&lt;/strong>: VRAM이 완전히 고갈되었습니다. 특히 대화가 길어져 KV 캐시가 비대해졌을 때 발생합니다.
&lt;strong>대책&lt;/strong>: Ollama의 경우 &lt;code>num_ctx&lt;/code>, llama.cpp의 경우 &lt;code>-c&lt;/code> 값을 의도적으로 작게 제한합니다.&lt;/p>
&lt;h3 id="3-언어일본어한국어-등-생성이-이상함">3. 언어(일본어/한국어 등) 생성이 이상함
&lt;/h3>&lt;p>&lt;strong>원인&lt;/strong>: 프롬프트 템플릿의 불일치 또는 지원하지 않는 모델입니다.
&lt;strong>대책&lt;/strong>: 모델 이름에 &lt;code>Instruct&lt;/code>가 포함된 것을 사용하고, ChatML이나 Llama3 포맷 등 모델 작성자가 지정한 올바른 템플릿이 도구 측에서 선택되어 있는지 확인하십시오.&lt;/p>
&lt;hr>
&lt;h1 id="10-요약-및-향후-전망">10. 요약 및 향후 전망
&lt;/h1>&lt;p>2026년, Windows 환경에서의 로컬 LLM 구축은 더 이상 일부 엔지니어들만의 특권이 아닙니다. GGUF 포맷의 사실상 표준화, Ollama나 LM Studio와 같이 세련된 생태계의 등장, 그리고 FlashAttention을 비롯한 하드웨어 최적화 덕분에 누구나 쉽게 엔터프라이즈급 AI 환경을 구축할 수 있게 되었습니다.&lt;/p>
&lt;p>이 기사에서 설명한 다음 요점들을 꼭 활용해 보시기 바랍니다.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>VRAM의 수학적 계산&lt;/strong>을 활용하여 내 PC 스펙에 최적화된 모델 크기와 양자화 수준을 논리적으로 선택한다.&lt;/li>
&lt;li>&lt;strong>Ollama&lt;/strong>를 사용하여 가장 빠르게 환경을 구축하고, AI 에디터와 연동하여 생산성을 극적으로 향상시킨다.&lt;/li>
&lt;li>&lt;strong>llama.cpp&lt;/strong>의 고급 파라미터 제어로 하드웨어의 한계 성능을 끌어낸다.&lt;/li>
&lt;li>&lt;strong>AnythingLLM&lt;/strong>으로 기밀 데이터를 다루는 안전한 로컬 RAG 시스템을 구축한다.&lt;/li>
&lt;li>**Unsloth (WSL2)**를 활용하여 나만의 전문 지식을 가진 커스텀 AI를 육성한다.&lt;/li>
&lt;/ol>
&lt;p>AI의 &amp;lsquo;대중화&amp;rsquo;는 더 이상 버즈워드가 아니라 여러분의 Windows 데스크톱에서 작동하는 현실의 시스템입니다. 클라우드 API 사용 비용이나 정보 유출 위험에서 벗어나, 자유롭고 강력한 프라이빗 AI의 세계로 지금 당장 발을 들여놓아 보시기 바랍니다.&lt;/p></description></item></channel></rss>