Featured image of post 'C++์—์„œ Microsoft.Windows.AI๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•'

'C++์—์„œ Microsoft.Windows.AI๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•'

๐ŸŽฏ C++์—์„œ Microsoft.Windows.AI๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•ใ€์ƒ˜ํ”Œ ์ฝ”๋“œ ํฌํ•จใ€‘

Windows 10 ์ดํ›„, Windows์—๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ONNX ํ˜•์‹์˜ AI ๋ชจ๋ธ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋Ÿฐํƒ€์ž„ ** ์ด ํƒ‘์žฌ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ๋ฐ”๋กœ ** Windows ML (Windows.AI.MachineLearning) ์ž…๋‹ˆ๋‹ค.

์ด ๊ธ€์—์„œ๋Š” C++(Win32 ์•ฑ ๊ธฐ๋ฐ˜) ์—์„œ Microsoft.Windows.AI.MachineLearning์„ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ** ์ƒ˜ํ”Œ ์ฝ”๋“œ์™€ ํ•จ๊ป˜ ๊ตฌ์ฒด์ ์œผ๋กœ ์„ค๋ช…** ํ•ฉ๋‹ˆ๋‹ค.


โœ… ์ค€๋น„ํŽธ

โ—พ ํ•„์š” ํ™˜๊ฒฝ

  • Windows 10 (1809+) ๋˜๋Š” Windows 11
  • Visual Studio 2019 ์ดํ›„ (Community ๋ฒ„์ „ ๊ฐ€๋Šฅ)
  • C++/WinRT ์ง€์› (Microsoft.Windows.CppWinRT)
  • Windows SDK 10.0.17763.0 ์ด์ƒ

โœ… ํ”„๋กœ์ ํŠธ ๊ตฌ์„ฑ

Visual Studio์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์„ฑ์˜ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

  • ์œ ํ˜•: C++ Windows ๋ฐ์Šคํฌํ†ฑ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(๋นˆ ํ”„๋กœ์ ํŠธ)

  • ํ•˜์œ„ ์‹œ์Šคํ…œ: Windows (WinMain)

  • NuGet์—์„œ ๋‹ค์Œ ํŒจํ‚ค์ง€๋ฅผ ์ถ”๊ฐ€

    1
    
    Microsoft.Windows.CppWinRT
    

โœ… ์ƒ˜ํ”Œ ์ฝ”๋“œ

๋‹ค์Œ์€ WinMain์„ ์‚ฌ์šฉํ•˜์—ฌ Win32 API์™€ Windows.AI.MachineLearning์„ ์กฐํ•ฉํ•œ ์ตœ์†Œ ๊ตฌ์„ฑ์˜ ์ƒ˜ํ”Œ์ž…๋‹ˆ๋‹ค.

โ€ป ์‚ฌ์šฉํ•  ONNX ๋ชจ๋ธ์€ model.onnx๋กœ ํ•˜๊ณ , ์‹คํ–‰ ํŒŒ์ผ๊ณผ ๊ฐ™์€ ํด๋”์— ๋ฐฐ์น˜ํ•ด ์ฃผ์„ธ์š”.

main.cpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <windows.h>
#include <winrt/Windows.AI.MachineLearning.h>
#include <winrt/Windows.Storage.h>

#pragma comment(lib, "windowsapp") // WinRT ๋งํฌ์šฉ

using namespace winrt;
using namespace Windows::AI::MachineLearning;
using namespace Windows::Storage;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
{
    // WinRT ์ดˆ๊ธฐํ™” (MTA๋“  STA๋“  ์ƒ๊ด€์—†์Œ)
    winrt::init_apartment();

    try {
        // ๋ชจ๋ธ ํŒŒ์ผ์„ ์ฝ์–ด์˜ค๊ธฐ
        auto modelFile = StorageFile::GetFileFromPathAsync(L"model.onnx").get();
        LearningModel model = LearningModel::LoadFromStorageFileAsync(modelFile).get();

        // ์„ธ์…˜ ์ƒ์„ฑ
        LearningModelSession session(model);
        LearningModelBinding binding(session);

        // ๋ชจ๋ธ์˜ ์ž…์ถœ๋ ฅ (์—ฌ๊ธฐ์„œ๋Š” ์ž„์‹œ๋กœ ๋นˆ ์ž…๋ ฅ)
        // ์‹ค์ œ๋กœ๋Š” TensorFloat ๋“ฑ์œผ๋กœ ๋ฐ”์ธ๋”ฉ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

        // ์ถ”๋ก  ์‹คํ–‰
        auto result = session.EvaluateAsync(binding, L"").get();

        MessageBox(nullptr, L"์ถ”๋ก ์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค", L"Windows ML (C++)", MB_OK);
    }
    catch (winrt::hresult_error const& ex) {
        MessageBox(nullptr, ex.message().c_str(), L"์—๋Ÿฌ", MB_ICONERROR);
    }

    return 0;
}

โœ… ๋ณด์ถฉ: ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅ Tensor ์ง€์ • ๋ฐฉ๋ฒ•

๋ชจ๋ธ์— ๋”ฐ๋ผ ์ถ”๋ก  ์ „์— Tensor์˜ ์ƒ์„ฑ ๋ฐ ๋ฐ”์ธ๋”ฉ ์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ:

1
2
3
4
5
6
7
8
// 1์ฐจ์› float ๋ฐฐ์—ด์„ Tensor๋กœ ๋ณ€ํ™˜
std::vector<float> inputData = {0.5f, 0.3f, 0.2f};
std::vector<int64_t> shape = {1, 3}; // ํ˜•ํƒœ: [1, 3]

auto tensor = TensorFloat::CreateFromArray(shape, inputData);

// ์ž…๋ ฅ ๋ฐ”์ธ๋”ฉ (๋ชจ๋ธ์˜ ์ž…๋ ฅ ์ด๋ฆ„์— ๋งž์ถค)
binding.Bind(L"input_0", tensor);

์ถœ๋ ฅ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ result.Outputs().Lookup(L"output_0")์œผ๋กœ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


โœ… ๋””๋ฒ„๊น… ์‹œ ์ฃผ์˜์‚ฌํ•ญ

  • ๋ชจ๋ธ ํŒŒ์ผ์ด ์‹คํ–‰ ํด๋”์— ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด FileNotFoundException์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
  • ์ž…์ถœ๋ ฅ ์ด๋ฆ„์ด ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด invalid_argument ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
  • ๋ชจ๋ธ์˜ ์ •ํ™•ํ•œ IO ์‚ฌ์–‘์€ Netron ๋“ฑ์˜ ๋„๊ตฌ๋กœ ํ™•์ธ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

โœ… ์š”์•ฝ

ํ•ญ๋ชฉ๋‚ด์šฉ
์‚ฌ์šฉ APIWindows.AI.MachineLearning (WinRT)
์–ธ์–ดC++ (Win32 ๊ธฐ๋ฐ˜)
๊ถŒ์žฅ ๋ฐฉ์‹C++/WinRT ํ—ค๋” ๊ฒฝ์œ 
์žฅ์ ONNX ๋ชจ๋ธ์ด ๋„ค์ดํ‹ฐ๋ธŒ๋กœ ๋™์ž‘, GPU ์ง€์›๋„ ๊ฐ€๋Šฅ
์ฃผ์˜๋ชจ๋ธ์˜ ์ž…๋ ฅ ์ด๋ฆ„๊ณผ Tensor ํ˜•ํƒœ์— ์ฃผ์˜

โœ… ๋Œ€์•ˆ: WinRT๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์ง€ ์•Š์€ ๋ถ„๋“ค์„ ์œ„ํ•ด

  • Microsoft์˜ ONNX Runtime์„ ์‚ฌ์šฉํ•˜๋ฉด WinRT ์—†์ด C++์—์„œ ์™„์ „ํžˆ ONNX ๋ชจ๋ธ์„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํฌ๋กœ์Šค ํ”Œ๋žซํผ ์ง€์›์œผ๋กœ Windows/Linux์—์„œ๋„ ๊ณตํ†ต ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ ๋งˆ๋ฌด๋ฆฌ

Windows ML (Microsoft.Windows.AI)์€ C++์—์„œ๋„ ํ™•์‹คํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•œ AI ์ถ”๋ก  ์—”์ง„์ž…๋‹ˆ๋‹ค. Windows ๋„ค์ดํ‹ฐ๋ธŒ์—์„œ์˜ ์ถ”๋ก ์ด ํ•„์š”ํ•˜์‹  ๋ถ„๋“ค์€ ๊ผญ ์‹œ๋„ํ•ด ๋ณด์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.

ONNX ๋ชจ๋ธ ์ƒ์„ฑ์ด๋‚˜ Tensor ๋ฐ”์ธ๋”ฉ์˜ ๊ตฌ์ฒด์ ์ธ ์˜ˆ์‹œ๊ฐ€ ํ•„์š”ํ•˜์‹  ๋ถ„๋“ค์„ ์œ„ํ•ด ํ›„์† ๊ธฐ์‚ฌ์—์„œ ์„ค๋ช…ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค!

comments powered by Disqus
Hugo๋กœ ๋งŒ๋“ฆ
Jimmy์˜ Stack ํ…Œ๋งˆ ์‚ฌ์šฉ ์ค‘