언어

Windows ML을 사용하여 고유한 언어 모델로 텍스트 생성

Important

Windows ML 런타임 및 텍스트 생성 API는 현재 실험적이며 프로덕션 환경에서 사용하도록 지원되지 않습니다. 이러한 API를 사용해보는 앱은 Microsoft Store에 게시해서는 안 됩니다.

Important

Windows ML 런타임 및 텍스트 생성 API는 현재 C++ 및 Python에서 사용할 수 있으며; C#은 현재 지원되지 않습니다. Windows ML GitHub 리포지토리에 문제를 게시하여 C#에서 이러한 API를 사용하는 데 관심이 있는지 알려주세요.

Windows ML 텍스트 생성 API는 사용자 고유의 언어 모델을 통해 텍스트 생성을 실행하는 것을 간소화합니다. ONNX Runtime GenAI가 ONNX Runtime을 기반으로 해당 루프를 간소화하는 방식과 유사하게, Windows ML Runtime API를 기반으로 토큰화, 자기회귀 디코딩, 스트리밍 출력 및 취소를 처리합니다. Windows는 이 API용 모델을 제공하지 않습니다. 사용자가 ONNX 또는 GGUF 파일과 토크나이저로 이루어진 모델을 선택하고 패키지하여 앱과 함께 배포합니다.

Tip

특정 모델이 필요하지 않고 Microsoft가 관리하는 모델을 사용하여 디바이스 내 텍스트 생성을 원한다면, 대신 즉시 사용할 수 있는 로컬 LLM 중 하나를 사용하세요.

여전히 기본 런타임 개체(모델, 실행 대상 및 파이프라인)를 만들고 세션에 전달합니다. API는 하드웨어 배치를 숨기지 않습니다. 직접 토큰 루프를 작성할 필요만 없앱니다.

지원되는 모델

텍스트 생성 API는 다음을 허용합니다.

  • ONNX (.onnx) 또는 ORT 형식 (.ort) 모델은 ONNX 런타임을 통해 실행됩니다. 모델은 토큰 ID 입력, 로짓 출력 및 키/값 캐시와 시퀀스 위치를 보유하는 하나의 고정 용량 상태 텐서 쌍을 노출해야 합니다. 별도의 토크나이저 소스(예: tokenizer.json와 같은 항목)를 제공합니다.
  • GGUF (.gguf) 모델은 llama.cpp 백 엔드를 통해 실행됩니다. 토크나이저는 모델에 포함되어 있으므로 별도의 토크나이저 소스가 필요하지 않습니다.

샘플은 키/값 캐시 및 시퀀스 위치를 하나의 상태 쌍으로 압축하는 작업별 그래프를 사용하여 내보낸 Qwen2.5-0.5B-Instruct 모델 패밀리에 대해 이 계약의 유효성을 검사합니다. 동일한 토큰 입력, 로짓 출력 및 상태 계약을 노출하는 다른 디코더 전용 언어 모델도 작동해야 합니다.

텍스트 생성

텍스트 생성 세션은 토큰라이저와 상태 저장 파이프라인(키/값 캐시를 소유하는 모델)을 래핑합니다. 모델 및 토크나이저를 로드하고, 모델의 토큰 입력, 로짓 출력 및 상태 계약을 설명하고, 세션을 빌드합니다.

// Create the runtime and an execution target (CPU here; GPU/NPU also available).
ComPtr<IWinMLRuntime> runtime;
THROW_IF_FAILED(WinMLCreateRuntime(IID_PPV_ARGS(runtime.GetAddressOf())));
ComPtr<IWinMLExecutionTarget> target;
THROW_IF_FAILED(runtime->CreateCpuExecutionTarget(target.GetAddressOf()));

// Load your ONNX model and its tokenizer.
ComPtr<IWinMLModel> model;
THROW_IF_FAILED(runtime->LoadModelFromFile(
    L"C:\\models\\qwen2.5-0.5b-instruct\\task_model.onnx",
    nullptr,
    model.GetAddressOf()));
ComPtr<IWinMLTokenizer> tokenizer;
THROW_IF_FAILED(WinMLCreateTokenizerFromFile(
    L"C:\\models\\qwen2.5-0.5b-instruct\\tokenizer.json",
    tokenizer.GetAddressOf()));

// Describe the model's token input, logits output, and KV-cache state pair.
winml::tasks::text_generation::onnx::StateTensorPair stateTensorPairs[] = {{1, 1}};
winml::tasks::text_generation::Options options;
options.values = winml::tasks::MakeTextGenerationOptions(/* maxNewTokens */ 64);

winml::tasks::text_generation::onnx::BuildTextGenerationArguments arguments;
arguments.runtime = runtime.Get();
arguments.model = model.Get();
arguments.target = target.Get();
arguments.tokenizer = tokenizer.Get();
arguments.tokenInputName = L"input_ids";
arguments.outputName = L"logits";
arguments.debugName = L"my-text-generation";
arguments.stateTensorPairs = stateTensorPairs;
arguments.sequenceCapacityHint = 128;
arguments.outputKind = WINML_TEXT_GENERATION_OUTPUT_KIND_LOGITS;
arguments.eosPolicy = WINML_TEXT_GENERATION_EOS_POLICY_TOKENIZER_DEFAULT;
arguments.options = &options;

winml::tasks::text_generation::TextGeneration textGeneration;
THROW_IF_FAILED(winml::tasks::text_generation::onnx::BuildTextGeneration(
    arguments, textGeneration));

GenerateText 프롬프트를 사용하여 스트리밍 작업을 시작한 다음, 완료를 보고할 때까지 반환된 스트림에서 조각을 가져옵니다.

ComPtr<IWinMLCancellationSource> cancellation;
THROW_IF_FAILED(textGeneration.tasks->CreateCancellationSource(
    cancellation.GetAddressOf()));

ComPtr<IWinMLTextGenerationPullStream> stream;
THROW_IF_FAILED(textGeneration.session->GenerateText(
    L"The sky is often",
    textGeneration.options.Get(),
    cancellation.Get(),
    stream.GetAddressOf()));

// Pull generated text one fragment at a time until the stream completes.
WINML_TEXT_GENERATION_READ_STATUS status{};
UINT32 tokenId = 0;
LPCWSTR fragment = nullptr;
while (SUCCEEDED(stream->ReadNext(&status, &tokenId, &fragment)) &&
    status == WINML_TEXT_GENERATION_READ_STATUS_UPDATE)
{
    std::wprintf(L"%ls", fragment);
}

// The terminal result is the authoritative text, token counts, and finish reason.
ComPtr<IWinMLTextGenerationResult> result;
THROW_IF_FAILED(stream->GetResult(result.GetAddressOf()));

완료된 결과 보고 내용은 다음과 같습니다:

  • 생성된 전체 텍스트 및 토큰 ID
  • 프롬프트 및 생성된 토큰 수
  • 완료 이유 - 시퀀스 종료 토큰, 중지 토큰, 요청된 토큰 제한, 시퀀스 용량, 취소 또는 오류

C++ 및 Python

네이티브 API는 winml/tasks/text_generation/TextGeneration.hpp 및 WinMLTasks.h 아래의 형식화된 C++ 도우미를 통해 노출됩니다. Python 애플리케이션은 windowsml.tasks 프로젝션을 windowsml.runtime와 함께 사용합니다.

Windows ML 샘플에는 C++ 및 Python 텍스트 생성 샘플이 포함됩니다. 이 샘플에서는 추상화가 시작되는 위치와 기반 워크플로를 사용자 지정하는 방법을 확인할 수 있도록 텍스트 생성 구성 옆에 전체 런타임 설정을 보여 줍니다.

또한, 다음을 참조하세요.