1. 소개
소개와 사용 사례는 explainer.md를 참조하라.
설명을 위해, API와 예제는 TF Lite flatbuffer 형식을 사용한다.
2. API
enum { // Tensorflow-lite flatbuffer.MLModelFormat };"tflite" enum { // 백엔드가 가장 적합한 장치를 선택하게 한다.MLDevicePreference , // 백엔드는 모델 추론을 수행하기 위해 GPU를 사용한다. 어떤 연산자가 // GPU에서 지원되지 않으면, CPU로 폴백한다."auto" , // 백엔드는 모델 추론을 수행하기 위해 CPU를 사용한다."gpu" };"cpu" enum { // 백엔드가 가장 적합한 동작을 선택하게 한다.MLPowerPreference , // 전력 소비보다 실행 속도를 우선한다."auto" , // 실행 속도 같은 다른 고려사항보다 전력 소비를 // 우선한다."high-performance" , };"low-power" dictionary { // 사용할 선호 장치 종류.MLContextOptions MLDevicePreference = "auto"; // 전력 소비와 관련된 선호도.devicePreference MLPowerPreference = "auto"; // 모델 로더 API를 위한 모델 형식.powerPreference MLModelFormat = "tflite"; // 사용할 스레드 수. // "0"은 백엔드가 이를 자동으로 결정할 수 있음을 의미한다.modelFormat unsigned long = 0; }; [numThreads Exposed =Window ]interface {ML Promise <MLContext >(createContext optional MLContextOptions = {}); };options enum { // "Unknown"은 "unsupported"를 의미하지 않는다. 백엔드는 여기에 명시적으로 // 나열된 것보다 더 많은 유형을 지원할 수 있다(예: TfLite에는 복소수가 있다). // 처음부터 백엔드의 너무 많은 세부사항을 노출하지 않기 위해 // 이를 "unknown"으로 취급한다.MLDataType ,"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 // 버퍼가 된다.