모델 로더 API

커뮤니티 그룹 보고서 초안,

이 문서에 대한 자세한 정보
이 버전:
https://webmachinelearning.github.io/model-loader/
이슈 추적:
GitHub
편집자:
Jonathan Bingham (Google Inc.)
설명 문서:
explainer.md

초록

이 문서는 사용자 지정 사전 학습된 머신 러닝 모델을 로드하기 위한 API를 설명한다.

이 문서의 상태

이 명세는 Web Machine Learning Community Group에서 공개했다. 이는 W3C 표준이 아니며 W3C 표준화 과정에 있는 것도 아니다. W3C Community Contributor License Agreement (CLA)에 따라 제한적인 opt-out 및 기타 조건이 적용된다는 점에 유의해야 한다. W3C Community and Business Groups에 대해 자세히 알아보라.

이 인큐베이션은 일시 중지되어 있으며, 최신 업데이트는 논의를 참조하라.

1. 소개

소개와 사용 사례는 explainer.md를 참조하라.

설명을 위해, API와 예제는 TF Lite flatbuffer 형식을 사용한다.

2. API

enum MLModelFormat {
  // Tensorflow-lite flatbuffer.
  "tflite" 
};

enum MLDevicePreference {
  // 백엔드가 가장 적합한 장치를 선택하게 한다.
  "auto",
  // 백엔드는 모델 추론을 수행하기 위해 GPU를 사용한다. 어떤 연산자가
  // GPU에서 지원되지 않으면, CPU로 폴백한다.
  "gpu",
  // 백엔드는 모델 추론을 수행하기 위해 CPU를 사용한다.
  "cpu"
};

enum MLPowerPreference {
  // 백엔드가 가장 적합한 동작을 선택하게 한다.
  "auto",
  // 전력 소비보다 실행 속도를 우선한다.
  "high-performance",
  // 실행 속도 같은 다른 고려사항보다 전력 소비를
  // 우선한다.
  "low-power",
};

dictionary MLContextOptions {
  // 사용할 선호 장치 종류.
  MLDevicePreference devicePreference = "auto";

  // 전력 소비와 관련된 선호도.
  MLPowerPreference powerPreference = "auto";

  // 모델 로더 API를 위한 모델 형식.
  MLModelFormat modelFormat = "tflite";
  
  // 사용할 스레드 수.
  // "0"은 백엔드가 이를 자동으로 결정할 수 있음을 의미한다.
  unsigned long numThreads = 0;
};

[Exposed=Window]
interface ML {
  Promise<MLContext> createContext(optional MLContextOptions options = {});
};

enum MLDataType {
  // "Unknown"은 "unsupported"를 의미하지 않는다. 백엔드는 여기에 명시적으로
  // 나열된 것보다 더 많은 유형을 지원할 수 있다(예: TfLite에는 복소수가 있다).
  // 처음부터 백엔드의 너무 많은 세부사항을 노출하지 않기 위해
  // 이를 "unknown"으로 취급한다.
  "unknown",
  "int64",
  "uint64",
  "float64",
  "int32",
  "uint32",
  "float32",
  "int16",
  "uint16",
  "float16",
  "int8",
  "uint8",
  "bool",
};

dictionary MLTensor {
  required ArrayBufferView data;
  required sequence<unsigned long> dimensions;
};

dictionary MLTensorInfo {
  required DOMString name;
  required MLDataType type;
  required sequence<unsigned long> dimensions;
};

[SecureContext, Exposed=Window]
interface MLModel {
  Promise<record<DOMString, MLTensor>> compute(record<DOMString, MLTensor> inputs);      
  sequence<MLTensorInfo> inputs();
  sequence<MLTensorInfo> outputs();
};

[Exposed=Window]
interface MLModelLoader {
  constructor(MLContext context);
  Promise<MLModel> load(ArrayBuffer modelBuffer);
};

3. 예제

// 먼저 MLContext를 만든다. 이는 WebNN API와 일관된다. 그리고 우리는 
// “numThread”와 "modelFormat"이라는 두 새 필드를 추가할 것이다. 
const context = await navigator.ml.createContext(
                                     { devicePreference: "cpu",
                                       powerPreference: "low-power",
                                       numThread: 0,   // 기본값 0은 
                                                       // "자동으로 결정"을 의미한다. 
                                       modelFormat: "tflite" });
// 그런 다음 ML 컨텍스트를 사용하여 모델 로더를 만든다.
loader = new MLModelLoader(context);
// 첫 번째 버전에서는 ArrayBuffer에서 모델을 로드하는 것만 지원한다. 우리는 
// 이것이 대부분의 사용 사례를 포괄한다고 본다. Web 개발자는 예를 들어 
// fetch API로 모델을 다운로드할 수 있다. 향후 정말 필요하다면 새 "load"
// 함수를 추가할 수 있다.
const modelUrl = 'https://path/to/model/file';
const modelBuffer = await fetch(modelUrl)
                            .then(response => response.arrayBuffer());
// 모델을 로드한다.
model = await loader.load(modelBuffer);
// `model.compute` 함수를 사용하여 일부 입력으로부터 모델의 출력을 
// 얻는다. 이 함수를 사용하는 예시 방식에는 다음이 포함된다. 
// 1. 모델에 입력 텐서가 하나만 있는 경우, 그 이름을 지정하지 않고 
// 텐서를 간단히 입력할 수 있다(사용자가 원하면 이 입력 텐서를 
// 이름으로 지정할 수도 있다).
z = await model.compute({ data: new Float32Array([10]), 
                          dimensions: [1]) });
// 2. 입력 텐서가 여러 개 있는 경우, 사용자는 입력 텐서의 이름을
// 그 이름으로 지정해야 한다.
z = await model.compute({ x: { data: new Float32Array([10]), 
                               dimensions: [1] },
                          y: { data: new Float32Array([20]), 
                               dimensions: [1] } });
// 3. 클라이언트는 출력 텐서도 지정할 수 있다. 이는 WebNN API와 
// 일관되며, 예를 들어 출력 텐서가 GPU 버퍼인 경우 유용할 수 있다. 
// 이 경우 함수는 빈 promise를 반환한다. 지정된 출력 텐서의 차원은 
// 모델의 출력 텐서 차원과 일치해야 한다. 
z_buffer = ml.tensor({data: new Float64Array(1), 
                      dimensions: [1] });
await model.compute({ data: new Float32Array([10]), 
                      dimensions: [1] },
                    z_buffer);
// 출력 텐서에 대해서는,
// 입력 인수와 유사하게, 출력 텐서가 하나만 있는 경우 `compute` 
// 함수는 경우 1과 2에서 텐서를 반환하며, 경우 3에서는 출력 텐서의 
// 이름을 지정할 필요가 없다. 그러나 출력 텐서가 여러 개 있는 경우, 
// 경우 1과 2의 출력은 텐서 이름에서 텐서로의 map이 되며, 
// 경우 3에서도 출력 인수는 텐서 이름에서 텐서로의 map이어야 한다.
// 경우 1과 2에서는 실제 출력 데이터의 위치가 컨텍스트에 따라 
// 달라진다. CPU 컨텍스트이면 출력 텐서의 버퍼는 RAM 버퍼가 되고,
// GPU 컨텍스트이면 출력 텐서의 버퍼는 GPU 
// 버퍼가 된다.

적합성

문서 규약

적합성 요구사항은 설명적 단언과 RFC 2119 용어를 조합하여 표현된다. 이 문서의 규범적 부분에서 쓰이는 핵심 단어 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, 및 “OPTIONAL”은 RFC 2119에 설명된 대로 해석되어야 한다. 그러나 가독성을 위해, 이 명세에서는 이러한 단어가 모두 대문자로 나타나지는 않는다.

명시적으로 비규범적이라고 표시된 절, 예제 및 주석을 제외하고 이 명세의 모든 텍스트는 규범적이다. [RFC2119]

이 명세의 예제는 “for example”이라는 말로 도입되거나 규범적 텍스트와 구분되도록 class="example"을 사용하여 다음과 같이 표시된다:

이는 정보 제공용 예제의 예이다.

정보 제공용 주석은 “Note”라는 단어로 시작하며, 규범적 텍스트와 구분되도록 class="note"를 사용하여 다음과 같이 표시된다:

Note, 이는 정보 제공용 주석이다.

색인

이 명세에서 정의된 용어

참조로 정의된 용어

참고문헌

규범 참고문헌

[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/
[WEBNN]
Ningxin Hu; Chai Chaoweeraprasit. Web Neural Network API. URL: https://webmachinelearning.github.io/webnn/

IDL 색인

enum MLModelFormat {
  // Tensorflow-lite flatbuffer.
  "tflite" 
};

enum MLDevicePreference {
  // 백엔드가 가장 적합한 장치를 선택하게 한다.
  "auto",
  // 백엔드는 모델 추론을 수행하기 위해 GPU를 사용한다. 어떤 연산자가
  // GPU에서 지원되지 않으면, CPU로 폴백한다.
  "gpu",
  // 백엔드는 모델 추론을 수행하기 위해 CPU를 사용한다.
  "cpu"
};

enum MLPowerPreference {
  // 백엔드가 가장 적합한 동작을 선택하게 한다.
  "auto",
  // 전력 소비보다 실행 속도를 우선한다.
  "high-performance",
  // 실행 속도 같은 다른 고려사항보다 전력 소비를
  // 우선한다.
  "low-power",
};

dictionary MLContextOptions {
  // 사용할 선호 장치 종류.
  MLDevicePreference devicePreference = "auto";

  // 전력 소비와 관련된 선호도.
  MLPowerPreference powerPreference = "auto";

  // 모델 로더 API를 위한 모델 형식.
  MLModelFormat modelFormat = "tflite";
  
  // 사용할 스레드 수.
  // "0"은 백엔드가 이를 자동으로 결정할 수 있음을 의미한다.
  unsigned long numThreads = 0;
};

[Exposed=Window]
interface ML {
  Promise<MLContext> createContext(optional MLContextOptions options = {});
};

enum MLDataType {
  // "Unknown"은 "unsupported"를 의미하지 않는다. 백엔드는 여기에 명시적으로
  // 나열된 것보다 더 많은 유형을 지원할 수 있다(예: TfLite에는 복소수가 있다).
  // 처음부터 백엔드의 너무 많은 세부사항을 노출하지 않기 위해
  // 이를 "unknown"으로 취급한다.
  "unknown",
  "int64",
  "uint64",
  "float64",
  "int32",
  "uint32",
  "float32",
  "int16",
  "uint16",
  "float16",
  "int8",
  "uint8",
  "bool",
};

dictionary MLTensor {
  required ArrayBufferView data;
  required sequence<unsigned long> dimensions;
};

dictionary MLTensorInfo {
  required DOMString name;
  required MLDataType type;
  required sequence<unsigned long> dimensions;
};

[SecureContext, Exposed=Window]
interface MLModel {
  Promise<record<DOMString, MLTensor>> compute(record<DOMString, MLTensor> inputs);      
  sequence<MLTensorInfo> inputs();
  sequence<MLTensorInfo> outputs();
};

[Exposed=Window]
interface MLModelLoader {
  constructor(MLContext context);
  Promise<MLModel> load(ArrayBuffer modelBuffer);
};