1. 소개

최종 업데이트: 2022년 4월 11일
이 Codelab에서는 Teachable Machine을 사용하여 이미지 분류 모델을 학습시키고, JavaScript용 강력하고 유연한 머신러닝 라이브러리인 TensorFlow.js를 사용하여 Coral 하드웨어 가속으로 실행하는 방법을 알아봅니다. 웹캠의 이미지를 표시하고 Coral Edge TPU를 사용하여 분류하는 Electron 앱을 빌드합니다. 이 Codelab의 완전히 작동하는 버전은 sig-tfjs GitHub 저장소에서 확인할 수 있습니다.
Coral 기기가 필요한가요?
아니요. Coral 기기 없이 이 Codelab을 시도할 수 있으며, 대신 WebNN 가속기를 사용하여 데스크톱 머신에서 우수한 성능을 얻을 수 있습니다.
빌드할 항목
이 Codelab에서는 이미지를 분류하는 Electron 앱을 빌드합니다. 앱:
- 웹캠의 이미지를 학습한 모델에 정의된 카테고리로 분류합니다.
- 사용 가능한 경우 Coral 가속기를 사용하여 성능을 높입니다.
- 플랫폼에서 지원되는 경우 WebNN을 사용하여 성능을 높입니다.
학습할 내용
- Node.js에서 TFLite 모델을 실행하기 위해 tfjs-tflite-node NPM 패키지를 설치하고 설정하는 방법
- Coral 기기에서 모델을 실행하기 위해 Edge TPU 런타임 라이브러리를 설치하는 방법
- Coral Edge TPU를 사용하여 모델 추론을 가속화하는 방법
- WebNN으로 모델 추론을 가속화하는 방법
이 Codelab에서는 Node.js의 TFLite에 중점을 둡니다. 관련 없는 개념과 코드 블록은 자세히 다루지 않으며 간단하게 복사하여 붙여넣기만 하면 되도록 제공됩니다.
필요한 항목
이 Codelab을 완료하려면 다음이 필요합니다.
- 웹캠이 있는 컴퓨터
- Coral의 경우 데스크톱이 있는 Raspberry Pi OS (64비트)를 실행하는 Raspberry Pi를 사용하는 것이 좋습니다.
- WebNN의 경우 Ubuntu 20.04 또는 Windows 10을 실행하는 Intel x86-64 머신을 사용하는 것이 좋습니다.
- Node.js 버전이 12 이상이어야 합니다.
- JavaScript에 대한 지식
- (권장) 모델 속도를 높이는 Coral USB Accelerator
2. 설정
코드 가져오기
이 프로젝트에 필요한 모든 코드를 Git 저장소에 넣었습니다. 시작하려면 코드를 가져와 선호하는 개발 환경에서 여세요. 이 Codelab에서는 Raspberry Pi OS (64비트) 데스크톱을 실행하는 Raspberry Pi를 사용하는 것이 좋습니다. 이렇게 하면 Coral 액셀러레이터를 쉽게 연결할 수 있습니다.
적극 권장: Git을 사용하여 Raspberry Pi에서 저장소 클론
코드를 가져오려면 새 터미널 창을 열고 저장소를 클론합니다.
git clone https://github.com/tensorflow/sig-tfjs.git
Codelab에서 수정해야 하는 모든 파일은 tfjs-tflite-node-codelab 디렉터리 (sig-tfjs 내부)에 있습니다. 이 디렉터리에는 starter_code, cpu_inference_working, coral_inference_working, webnn_inference_working이라는 하위 디렉터리가 있습니다. 이 Codelab 단계의 체크포인트입니다.
저장소의 다른 파일 중에는 tfjs-tflite-node-codelab이 종속된 NPM 패키지가 있습니다. 이러한 파일을 수정할 필요는 없지만 환경이 올바르게 설정되었는지 확인하려면 일부 테스트를 실행해야 합니다.
Edge TPU 런타임 라이브러리 설치
Coral 기기를 사용하려면 먼저 Edge TPU 런타임 라이브러리를 설치해야 합니다. 플랫폼에 맞는 안내에 따라 설치합니다.
Linux / Raspberry Pi
Linux에서는 Google의 PPA에서 x86-64 및 Armv8 (64비트) 아키텍처용 Debian 패키지 libedgetpu1-std로 라이브러리를 사용할 수 있습니다. 프로세서가 다른 아키텍처를 사용하는 경우 소스에서 컴파일해야 합니다.
이 명령어를 실행하여 Google의 Coral PPA를 추가하고 Edge TPU 런타임 라이브러리를 설치합니다.
# None of this is needed on Coral boards
# This repo is needed for almost all packages below
echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | sudo tee /etc/apt/sources.list.d/coral-edgetpu.list
# This repo is needed for only python3-coral-cloudiot and python3-coral-enviro
echo "deb https://packages.cloud.google.com/apt coral-cloud-stable main" | sudo tee /etc/apt/sources.list.d/coral-cloud.list
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo apt-get update
sudo apt-get install libedgetpu1-std
Windows / 기타 OS
사전 컴파일된 바이너리는 MacOS 및 Windows의 x86-64 버전에서 사용할 수 있으며, 다운로드한 후 보관 파일에서 install.sh 또는 install.bat 스크립트를 실행하여 설치할 수 있습니다.
기기 다시 시작하기
Edge TPU 런타임이 설치되면 기기를 다시 시작하여 설치 프로그램이 추가한 새 Coral Udev 규칙을 활성화합니다.
Coral 기기가 감지되는지 확인
Coral 기기가 감지되고 작동하는지 확인하려면 coral-tflite-delegate 패키지의 통합 테스트를 실행하세요. 이 패키지는 저장소의 루트 디렉터리에 있습니다. 통합 테스트를 실행하려면 Coral 액셀러레이터를 연결하고 패키지의 디렉터리에서 다음 명령어를 실행하세요.
npx yarn
npx yarn build-deps
npx yarn test-integration
다음과 같은 출력이 표시됩니다.
yarn run v1.22.17
$ yarn build && yarn test-integration-dev
$ tsc
$ jasmine --config=jasmine-integration.json
Platform node has already been set. Overwriting the platform with node.
Randomized with seed 78904
Started
============================
Hi there 👋. Looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, which binds to TensorFlow C++, by running npm i @tensorflow/tfjs-node, or npm i @tensorflow/tfjs-node-gpu if you have CUDA. Then call require('@tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of your program. Visit https://github.com/tensorflow/tfjs-node for more details.
============================
WARNING: converting 'int32' to 'uint8'
.
1 spec, 0 failures
Finished in 2.777 seconds
Randomized with seed 78904 (jasmine --random=true --seed=78904)
Done in 6.36s.
로그에 언급된 대로 @tensorflow/tfjs-node,를 설치하지 않아도 됩니다. TFLite에서 모델을 실행할 것이기 때문입니다.
출력에 Encountered unresolved custom op: edgetpu-custom-op가 포함되어 있으면 Coral 기기가 감지되지 않은 것입니다. 에지 TPU 런타임 라이브러리를 설치하고 Coral 기기를 컴퓨터에 연결했는지 확인합니다. Coral 시작 가이드에 따라 Coral 바인딩의 Python 버전을 테스트할 수도 있습니다. Python 버전은 작동하지만 이러한 테스트가 계속 실패하는 경우 버그 신고를 제출하여 알려주세요.
시작 코드 실행하기
이제 스타터 코드를 실행할 준비가 되었습니다. 시작하려면 다음 단계를 따르세요.
tfjs-tflite-node-codelab디렉터리 아래의starter_code디렉터리로 이동합니다.npm install을 실행하여 종속 항목을 설치합니다.npm start을 실행하여 프로젝트를 실행합니다. 컴퓨터의 웹캠에서 동영상 피드를 표시하는 앱이 열립니다.
시작점
이 Codelab을 위해 설계된 기본 Electron 카메라 앱에서 시작해 보겠습니다. Codelab의 개념을 보여주기 위해 코드를 단순화했으며 오류 처리는 거의 없습니다. 프로덕션 앱에서 코드를 재사용하려면 오류를 처리하고 모든 코드를 완전히 테스트해야 합니다.

시작 코드 살펴보기
이 시작 코드에는 많은 파일이 있지만 수정해야 하는 파일은 renderer.js 하나뿐입니다. 동영상 피드와 HTML 요소를 비롯하여 페이지에 표시되는 항목을 제어하며, 여기에 머신러닝 모델을 앱에 추가합니다. 다른 파일 중에는 index.html 파일이 있지만 이 파일은 renderer.js 파일을 로드하기만 합니다. Electron의 진입점인 main.js 파일도 있습니다. 앱이 열릴 때 표시할 내용과 닫힐 때 수행할 작업을 비롯한 앱의 수명 주기를 제어하지만 변경할 필요는 없습니다.
디버거 열기
이 Codelab을 따라 하는 동안 앱을 디버그해야 할 수도 있습니다. 이 앱은 Electron을 기반으로 하므로 Chrome 디버거가 내장되어 있습니다. 대부분의 플랫폼에서 Ctrl + Shift + i를 사용하여 열 수 있습니다. 콘솔 탭을 클릭하여 앱의 로그와 오류 메시지를 확인합니다.
여기에서는 더 살펴볼 것이 많지 않으므로 바로 이미지 분류기 학습으로 넘어가겠습니다.
3. 이미지 분류기 학습
이 섹션에서는 커스텀 이미지 분류 모델의 TFLite 및 Coral 버전을 학습시킵니다.
분류기 학습
이미지 분류기는 입력 이미지를 가져와 라벨을 할당합니다. 이 Codelab에서는 Teachable Machine을 사용하여 브라우저에서 모델을 학습시킵니다. 이 섹션의 학습 속도를 높이려면 Raspberry Pi 대신 데스크톱 또는 노트북 컴퓨터를 사용하면 되지만 결과 파일을 Pi에 복사해야 합니다.
이제 모델을 학습시킬 준비가 되었습니다. 어떤 종류의 모델을 학습시켜야 할지 잘 모르겠다면 프레임에 사람이 있는지 감지하는 사람 감지기를 학습시키는 것이 좋습니다.
- 새 탭에서 Teachable Machine 학습 페이지를 엽니다.
- 이미지 프로젝트를 선택한 다음 표준 이미지 모델을 선택합니다.
- 각 클래스의 이미지 샘플을 추가합니다. 웹캠 입력을 사용하는 것이 가장 쉬운 방법입니다. 클래스 이름을 바꿀 수도 있습니다.
- 각 클래스에 대해 충분한 데이터를 수집한 후 (일반적으로 샘플 50개가 충분함) 모델 학습을 누릅니다.
모델 학습이 완료되면 모델 출력 미리보기가 표시됩니다.

모델에 다른 입력을 제공해 보세요. 잘못 분류된 입력이 있으면 학습 데이터에 추가하고 모델을 재학습합니다.
- 모델의 정확성이 만족스러우면 모델 내보내기를 클릭합니다. 모델의 두 가지 버전을 별도로 다운로드해야 합니다.
- 모델을 TensorFlow Lite 부동 소수점 모델로 내보냅니다. 그러면
converted_tflite.zip이라는 파일이 다운로드됩니다. CPU에서 실행되는 - 모델을 TensorFlow Lite EdgeTPU 모델로 내보냅니다. 그러면 Coral Edge TPU에서 실행되는
converted_edgetpu.zip이라는 파일이 다운로드됩니다.
4. 앱에서 CPU 모델 실행
이제 모델을 학습시켰으므로 앱에 추가할 차례입니다. 이 섹션이 끝나면 앱에서 기기의 CPU를 사용하여 모델을 실행할 수 있습니다.
앱에 모델 파일 추가
분류기를 학습할 때 다운로드한 converted_tflite.zip 모델 파일의 압축을 풉니다. 보관 파일에 파일이 두 개 있습니다. model_uquant.tflite는 모델 그래프와 가중치를 포함한 저장된 TFLite 모델입니다. labels.txt에는 모델이 예측하는 클래스의 사람이 읽을 수 있는 라벨이 포함됩니다. 두 파일을 모두 modeldirectory에 배치합니다.
종속 항목 설치
모델을 로드하고 입력을 전처리하려면 TensorFlow.js의 몇 가지 종속 항목이 필요합니다.
tfjs-tflite-node: Node.js에서 TFLite 모델을 실행하기 위한 TensorFlow.js 패키지입니다.@tensorflow/tfjs: TensorFlow.js의 기본 패키지입니다.
@tensorflow/tfjs는 이미 설치되어 있지만 다음 명령어를 사용하여 tfjs-tflite-node를 설치해야 합니다.
npm install --save tfjs-tflite-node
설치한 후 renderer.js 상단의 앱에 추가합니다.
CODELAB 1부: tfjs-tflite-node 가져오기
const {loadTFLiteModel} = require('tfjs-tflite-node');
모델 로드
이제 모델을 로드할 준비가 되었습니다. tfjs-tflite-node는 이를 수행하는 loadTFLiteModel 함수를 제공합니다. 파일 경로, ArrayBuffer 또는 TFHub URL에서 모델을 로드할 수 있습니다. 모델과 가중치를 로드하려면 main 함수에 다음을 추가합니다.
const modelPath = './model/model_unquant.tflite';
const model = await loadTFLiteModel(modelPath);
const labels = fs.readFileSync('./model/labels.txt', 'utf8')
.split('\n');
모델 실행
모델을 실행하려면 세 단계를 거쳐야 합니다. 먼저 웹캠에서 입력 프레임을 가져와 전처리합니다. 그런 다음 해당 프레임에서 모델을 실행하고 예측을 가져옵니다. 그런 다음 페이지에 예측을 표시합니다.
웹캠 입력 전처리
현재 웹캠은 HTML 요소일 뿐이며, 표시되는 프레임은 JavaScript renderer.js 파일에서 사용할 수 없습니다. 웹캠에서 프레임을 가져오기 위해 TensorFlow.js는 카메라에서 프레임을 캡처하는 사용하기 쉬운 capture() 메서드를 제공하는 tf.data.webcam을 제공합니다.
이를 사용하려면 다음 설정 코드를 main()에 추가하세요.
CODELAB 1부: 여기에서 tf.data.webcam을 설정합니다.
const tensorCam = await tf.data.webcam(webcam);
그런 다음 프레임마다 이미지를 캡처하려면 run()에 다음을 추가합니다.
CODELAB 1부: 여기에서 웹캠 프레임을 캡처합니다.
const image = await tensorCam.capture();
또한 모델과 호환되도록 각 프레임을 전처리해야 합니다. 이 Codelab에서 사용하는 모델의 입력 모양은 [1, 224, 224, 3]이므로 224x224 픽셀 RGB 이미지가 필요합니다. tensorCam.capture()의 모양은 [224, 224, 3]이므로 tf.expandDims를 사용하여 텐서 앞에 추가 차원을 추가해야 합니다. 또한 CPU 모델은 -1과 1 사이의 Float32 입력을 예상하지만 웹캠은 0~255의 값을 캡처합니다. 입력 텐서를 127로 나누어 범위를 [0, 255] 에서 [0, ~2] 로 변경한 다음 1을 빼서 원하는 범위 [-1, ~1]을 얻을 수 있습니다. run() 함수의 tf.tidy()에 다음 줄을 추가합니다.
CODELAB 1부: 여기에서 웹캠 프레임을 전처리합니다.
const expanded = tf.expandDims(image, 0);
const divided = tf.div(expanded, tf.scalar(127));
const normalized = tf.sub(divided, tf.scalar(1));
텐서를 사용한 후에는 삭제하는 것이 중요합니다. tf.tidy()는 콜백에 포함된 코드에 대해 이 작업을 자동으로 실행하지만 비동기 함수는 지원하지 않습니다. dispose() 메서드를 호출하여 이전에 만든 이미지 텐서를 수동으로 삭제해야 합니다.
CODELAB 1부: 여기에 웹캠 프레임을 삭제합니다.
image.dispose();
모델 실행 및 결과 표시
전처리된 입력에서 모델을 실행하려면 정규화된 텐서에서 model.predict()를 호출합니다. 그러면 각 라벨의 예측 확률이 포함된 1차원 텐서가 반환됩니다. 이 확률에 100을 곱하여 각 라벨의 확률을 구하고 시작 코드에 포함된 showPrediction 함수를 사용하여 화면에 모델의 예측을 표시합니다.
이 코드에서는 stats.js를 사용하여 model.predict 주변에 stats.begin 및 stats.end 호출을 배치하여 예측에 걸리는 시간을 측정합니다.
CODELAB 1부: 모델을 실행하고 결과를 여기에 표시합니다.
stats.begin();
const prediction = model.predict(normalized);
stats.end();
const percentage = tf.mul(prediction, tf.scalar(100));
showPrediction(percentage.dataSync(), labels);
yarn start로 앱을 다시 실행하면 모델의 분류가 표시됩니다.

성능
현재 설정된 대로 모델은 CPU에서 실행됩니다. 데스크톱 컴퓨터와 대부분의 노트북에서는 괜찮지만 Raspberry Pi나 다른 저전력 기기에서 실행하는 경우에는 바람직하지 않을 수 있습니다. Raspberry Pi 4에서는 약 10FPS가 표시될 수 있으며 이는 일부 애플리케이션에 충분히 빠르지 않을 수 있습니다. 더 빠른 머신을 사용하지 않고 성능을 개선하려면 Coral Edge TPU 형태의 애플리케이션별 실리콘을 사용하면 됩니다.
5. 앱에서 Coral 모델 실행
Coral 기기가 없는 경우 이 섹션을 건너뛰어도 됩니다.
이 Codelab 단계는 이전 섹션에서 작성한 코드를 기반으로 하지만, 처음부터 시작하려면 cpu_inference_working 체크포인트를 대신 사용해도 됩니다.
Coral 모델을 실행하는 단계는 CPU 모델을 실행하는 단계와 거의 동일합니다. 주요 차이점은 모델 형식입니다. Coral은 uint8 텐서만 지원하므로 모델이 양자화됩니다. 이는 모델에 전달되는 입력 텐서와 모델에서 반환되는 출력 텐서에 영향을 미칩니다. 또 다른 차이점은 Coral TPU에서 실행하려면 Edge TPU 컴파일러를 사용하여 모델을 컴파일해야 한다는 점입니다. TeachableMachine에서는 이 단계를 이미 완료했지만 Coral 문서를 방문하여 다른 모델에 대해 이 단계를 수행하는 방법을 알아볼 수 있습니다.
앱에 Coral 모델 파일 추가
분류기를 학습할 때 다운로드한 converted_edgetpu.zip 모델 파일의 압축을 풉니다. 보관 파일에는 두 개의 파일이 포함되어 있습니다. model_edgetpu.tflite는 모델 그래프와 가중치를 포함한 저장된 TFLite 모델입니다. labels.txt에는 모델이 예측하는 클래스의 사람이 읽을 수 있는 라벨이 포함됩니다. 모델 파일을 coral_model 디렉터리에 배치합니다.
종속 항목 설치
Coral 모델을 실행하려면 Edge TPU 런타임 라이브러리가 필요합니다. 계속하기 전에 설정 안내에 따라 설치했는지 확인하세요.
Coral 기기는 TFLite 대리자로 액세스됩니다. JavaScript에서 액세스하려면 coral-tflite-delegate 패키지를 설치하세요.
npm install --save coral-tflite-delegate
그런 다음 renderer.js 파일의 상단에 다음 줄을 추가하여 위임을 가져옵니다.
const {CoralDelegate} = require('coral-tflite-delegate');
모델 로드
이제 Coral 모델을 로드할 준비가 되었습니다. CPU 모델과 동일한 방식으로 이 작업을 수행합니다. 단, 이제 Coral 대리자를 로드하기 위해 loadTFLiteModel 함수에 옵션을 전달합니다.
const coralModelPath = './coral_model/model_edgetpu.tflite';
const options = {delegates: [new CoralDelegate()]};
const coralModel = await loadTFLiteModel(coralModelPath, options);
라벨은 CPU 모델과 동일하므로 로드할 필요가 없습니다.
CPU와 Coral 간 전환 버튼 추가
이전 섹션에서 추가한 CPU 모델과 함께 Coral 모델을 추가합니다. 두 모델을 동시에 실행하면 성능 차이를 확인하기 어려우므로 전환 버튼을 사용하여 Coral과 CPU 실행 간에 전환합니다.
다음 코드를 사용하여 버튼을 추가합니다.
let useCoralDelegate = false;
const toggleCoralButton = document.createElement('button');
function toggleCoral() {
useCoralDelegate = !useCoralDelegate;
toggleCoralButton.innerText = useCoralDelegate
? 'Using Coral. Press to switch to CPU.'
: 'Using CPU. Press to switch to Coral.';
}
toggleCoralButton.addEventListener('click', toggleCoral);
toggleCoral();
document.body.appendChild(toggleCoralButton);
run() 함수에서 이 조건을 연결해 보겠습니다. useCoralDelegate가 false이면 CPU 버전을 실행해야 합니다. 그렇지 않으면 Coral 버전을 실행합니다 (하지만 현재는 아무 작업도 하지 않음). CPU 모델 실행 코드를 if 문으로 래핑합니다. Coral 모델에서 expanded 텐서를 사용하므로 if 문에서 생략됩니다.
Codelab 2부: 여기에서 위임을 사용할지 확인합니다.
// NOTE: Don't just copy-paste this code into the app.
// You'll need to edit the code from the CPU section.
const expanded = tf.expandDims(image, 0);
if (useCoralDelegate) {
// CODELAB part 2: Run Coral prediction here.
} else {
const divided = tf.div(expanded, tf.scalar(127));
const normalized = tf.sub(divided, tf.scalar(1));
stats.begin();
const prediction = model.predict(normalized);
stats.end();
const percentage = tf.mul(prediction, tf.scalar(100));
showPrediction(percentage.dataSync(), labels);
}
모델 실행
Coral 버전의 모델은 0~255의 uint8 텐서를 예상하므로 입력이 정규화될 필요가 없습니다. 하지만 출력은 0~255 범위의 uint8 텐서이기도 합니다. 표시되기 전에 0~100의 부동 소수점으로 변환해야 합니다.
CODELAB 2부: 여기에서 Coral 예측을 실행합니다. (위 코드 스니펫의 일부)
stats.begin();
const prediction = coralModel.predict(expanded);
stats.end();
const percentage = tf.div(tf.mul(prediction, tf.scalar(100)), tf.scalar(255));
showPrediction(percentage.dataSync(), labels);
yarn start로 앱을 다시 실행하면 Coral 액셀러레이터의 분류가 표시됩니다.

버튼을 눌러 Coral 추론과 CPU 추론 간에 전환할 수 있습니다. Coral 모델의 신뢰도 순위가 CPU 모델보다 정확하지 않으며 일반적으로 짝수 소수점으로 끝나는 것을 확인할 수 있습니다. 정밀도 손실은 Coral에서 양자화된 모델을 실행할 때 발생하는 트레이드오프입니다. 실제로는 문제가 되지 않는 경우가 많지만 염두에 두어야 합니다.
성능 관련 참고사항
표시되는 프레임 속도에는 전처리 및 후처리가 포함되므로 Coral 하드웨어의 기능을 나타내지 않습니다. model.predict 호출만 측정하는 지연 시간 (밀리초)이 표시될 때까지 FPS 측정기를 클릭하면 성능을 더 잘 파악할 수 있습니다. 하지만 텐서를 TFLite 네이티브 C 바인딩으로 이동한 다음 Coral 기기로 이동하는 데 걸리는 시간도 포함되므로 완벽한 측정은 아닙니다. C++로 작성된 더 정확한 성능 벤치마크는 EdgeTPU 벤치마크 페이지를 참고하세요.
또한 동영상은 Raspberry Pi가 아닌 노트북에서 녹화되었으므로 FPS가 다를 수 있습니다.
Coral 전처리 속도 향상
경우에 따라 TFJS 백엔드를 전환하여 전처리 속도를 높일 수 있습니다. 기본 백엔드는 WebGL로, 병렬화 가능한 대규모 작업에 적합하지만 이 앱은 전처리 단계에서 이러한 작업을 많이 실행하지 않습니다 (사용하는 유일한 작업은 병렬이 아닌 expandDims임). 파일 상단의 가져오기 뒤에 이 줄을 추가하여 텐서를 GPU로 이동하거나 GPU에서 이동하는 추가 지연 시간을 방지하고 CPU 백엔드로 전환할 수 있습니다.
tf.setBackend(‘cpu');
이는 병렬화된 TFLite CPU 모델의 전처리에도 영향을 미치므로 이 변경사항으로 인해 모델이 훨씬 느리게 실행됩니다.
6. WebNN으로 CPU 모델 가속화
Coral 액셀러레이터가 없거나 모델을 가속화하는 다른 방법을 사용해 보려면 WebNN TFLite 대리자를 사용하면 됩니다. 이 위임자는 Intel 프로세서에 내장된 머신러닝 하드웨어를 사용하여 OpenVINO 툴킷으로 모델 추론을 가속화합니다. 따라서 이 Codelab의 설정 섹션에서 다루지 않은 추가 요구사항이 있으며 OpenVINO 툴킷을 설치해야 합니다. 계속하기 전에 지원되는 타겟 시스템 플랫폼에 대해 설정을 확인하세요. 하지만 WebNN 위임은 아직 macOS를 지원하지 않습니다.
OpenVINO 툴킷 설치
OpenVINO 툴킷은 Intel 프로세서에 내장된 머신러닝 하드웨어를 사용하여 모델을 가속화합니다. Intel에서 사전 컴파일된 버전을 다운로드하거나 소스에서 빌드할 수 있습니다. OpenVINO를 설치하는 방법은 여러 가지가 있지만 이 Codelab에서는 Windows 또는 Linux용 설치 스크립트를 사용하는 것이 좋습니다. 다른 버전은 호환되지 않을 수 있으므로 2021.4.2 LTS 런타임 버전을 설치해야 합니다. 설치 프로그램을 실행한 후 Linux 또는 Windows 설치 안내에 설명된 대로 셸의 환경 변수를 구성하거나 ( 영구 솔루션) webnn-tflite-delegate 디렉터리에 있는 setupvars.sh (Linux) 또는 setupvars.bat (Windows) 명령어를 실행합니다.
WebNN 대리자가 작동하는지 확인
WebNN 위임자가 올바르게 작동하는지 확인하려면 저장소의 루트 디렉터리에 있는 webnn-tflite-delegate 패키지의 통합 테스트를 실행합니다. 통합 테스트를 실행하려면 패키지의 디렉터리에서 다음 명령어를 실행합니다.
# In webnn-tflite-delegate/
npx yarn
npx yarn test-integration
다음과 같은 출력이 표시됩니다.
WebNN delegate: WebNN device set to 0.
INFO: Created TensorFlow Lite WebNN delegate for device Default and power Default.
============================
Hi there 👋. Looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, which binds to TensorFlow C++, by running npm i @tensorflow/tfjs-node, or npm i @tensorflow/tfjs-node-gpu if you have CUDA. Then call require('@tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of your program. Visit https://github.com/tensorflow/tfjs-node for more details.
============================
label: wine bottle
score: 0.934505045413971
.
1 spec, 0 failures
Finished in 0.446 seconds
Randomized with seed 58441 (jasmine --random=true --seed=58441)
Done in 8.07s.
다음과 같은 출력이 표시되면 구성 오류가 있는 것입니다.
Platform node has already been set. Overwriting the platform with node.
Randomized with seed 05938
Started
error Command failed with exit code 3221225477.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
이 출력은 OpenVINO의 환경 변수가 설정되지 않았음을 의미할 가능성이 높습니다. 지금은 setupvars.sh (Linux) 또는 setupvars.bat (Windows) 명령어를 실행하여 설정할 수 있지만 Linux 또는 Windows ( 영구 솔루션) 안내에 따라 영구적으로 설정하는 것이 좋습니다. Windows를 사용하는 경우 다음
setupvars.bat
명령어는 Git bash를 지원하지 않으므로 Windows 명령 프롬프트에서 이 Codelab의 명령어와 기타 명령어를 실행해야 합니다.
WebNN 대리자 설치
OpenVINO가 설치되었으므로 이제 WebNN으로 CPU 모델을 가속화할 수 있습니다. 이 Codelab 섹션은 '앱에서 CPU 모델 실행' 섹션에서 작성한 코드를 기반으로 합니다. 이 단계에서 작성한 코드를 사용할 수 있지만 Coral 섹션을 이미 완료한 경우 cpu_inference_working 체크포인트를 대신 사용하여 처음부터 시작하세요.
WebNN 위임자의 Node.js 부분은 npmjs에 배포됩니다. 설치하려면 다음 명령어를 실행합니다.
npm install --save webnn-tflite-delegate
그런 다음 renderer.js 파일의 상단에 다음 줄을 추가하여 위임을 가져옵니다.
const {WebNNDelegate, WebNNDevice} = require('webnn-tflite-delegate');
WebNN 대리자는 CPU 또는 GPU에서 실행을 지원합니다. WebNNDevice를 사용하면 사용할 항목을 선택할 수 있습니다.
모델 로드
이제 WebNN 대리자가 사용 설정된 모델을 로드할 준비가 되었습니다. Coral의 경우 다른 모델 파일을 로드해야 했지만 WebNN은 TFLite와 동일한 모델 형식을 지원합니다. 모델에 전달된 대리자 목록에 WebNNDelegate를 추가하여 사용 설정합니다.
let webnnModel = await loadTFLiteModel(modelPath, {
delegates: [new WebNNDelegate({webnnDevice: WebNNDevice.DEFAULT})],
});
동일한 모델이므로 라벨을 다시 로드할 필요가 없습니다.
TfLite CPU와 WebNN 간 전환 버튼 추가
이제 모델의 WebNN 버전이 준비되었으므로 WebNN과 TfLite CPU 추론 간에 전환하는 버튼을 추가합니다. 두 가지를 동시에 실행하면 성능 차이를 확인하기 어렵습니다.
다음 코드를 사용하여 버튼을 추가합니다 (아직 모델이 전환되지는 않음).
let useWebNNDelegate = false;
const divElem = document.createElement('div');
const toggleWebNNButton = document.createElement('button');
function toggleWebNN() {
useWebNNDelegate = !useWebNNDelegate;
toggleWebNNButton.innerHTML = useWebNNDelegate
? 'Using WebNN. Press to switch to TFLite CPU.'
: 'Using TFLite CPU. Press to switch to WebNN.';
divElem.hidden = useWebNNDelegate ? false : true;
}
toggleWebNNButton.addEventListener('click', toggleWebNN);
toggleWebNN();
document.body.appendChild(toggleWebNNButton);
document.body.appendChild(divElem);
이 코드에서는 다음 섹션에서 WebNN 설정을 구성하는 데 사용하는 div 요소도 추가합니다.
WebNN 기기 간 전환을 위한 드롭다운 추가
WebNN은 CPU와 GPU에서 실행을 지원하므로 드롭다운을 추가하여 전환합니다. 버튼을 만드는 코드 뒤에 다음 코드를 추가합니다.
// Create elements for WebNN device selection
divElem.innerHTML = '<br/>WebNN Device: ';
const selectElem = document.createElement('select');
divElem.appendChild(selectElem);
const webnnDevices = ['Default', 'GPU', 'CPU'];
// append the options
for (let i = 0; i < webnnDevices.length; i++) {
var optionElem = document.createElement('option');
optionElem.value = i;
optionElem.text = webnnDevices[i];
selectElem.appendChild(optionElem);
}
이제 앱을 실행하면 기본, GPU, CPU가 나열된 드롭다운이 표시됩니다. 드롭다운이 아직 연결되지 않았으므로 지금은 선택해도 아무런 작업이 실행되지 않습니다. 
드롭다운으로 기기 변경하기
사용되는 WebNN 기기가 변경되도록 드롭다운을 연결하려면 드롭다운 선택기 요소의 change 이벤트에 리스너를 추가합니다. 선택한 값이 변경되면 대리자 옵션에서 해당 WebNN 기기를 선택하여 WebNN 모델을 다시 만듭니다.
드롭다운을 추가한 코드 뒤에 다음 코드를 추가합니다.
selectElem.addEventListener('change', async () => {
let webnnDevice;
switch(selectElem.value) {
case '1':
webnnDevice = WebNNDevice.GPU;
break;
case '2':
webnnDevice = WebNNDevice.CPU;
break;
default:
webnnDevice = WebNNDevice.DEFAULT;
break;
}
webnnModel = await loadTFLiteModel(modelPath, {
delegates: [new WebNNDelegate({webnnDevice})],
});
});
이 변경사항으로 인해 드롭다운이 변경될 때마다 올바른 설정으로 새 모델이 생성됩니다. 이제 WebNN 모델을 연결하고 추론에 사용할 차례입니다.
WebNN 모델 실행
WebNN 모델을 사용할 준비가 되었지만 WebNN과 TfLite CPU 간에 전환하는 버튼은 아직 모델을 전환하지 않습니다. 모델을 전환하려면 먼저 Codelab의 첫 번째 섹션에서 TfLite CPU 모델을 로드할 때 사용한 model 변수의 이름을 바꿔야 합니다.
다음 줄을 변경하세요...
const model = await loadTFLiteModel(modelPath);
이 줄과 일치하도록
const cpuModel = await loadTFLiteModel(modelPath);
model 변수의 이름을 cpuModel로 바꾼 후 이를 run 함수에 추가하여 버튼의 상태에 따라 올바른 모델을 선택합니다.
Codelab 2부: 여기에서 위임을 사용할지 확인합니다.
let model;
if (useWebNNDelegate) {
model = webnnModel;
} else {
model = cpuModel;
}
이제 앱을 실행하면 버튼이 TfLite CPU와 WebNN 간에 전환됩니다. 
통합 Intel GPU가 있는 경우 WebNN CPU와 GPU 추론 간에 전환할 수도 있습니다.
성능 관련 참고사항
표시되는 프레임 속도에는 전처리 및 후처리가 포함되므로 WebNN의 기능을 나타내지 않습니다. model.predict 호출만 측정하는 지연 시간 (밀리초)이 표시될 때까지 FPS 측정기를 클릭하면 성능을 더 잘 파악할 수 있습니다. 하지만 텐서를 TFLite 네이티브 C 바인딩으로 이동하는 데 걸리는 시간도 포함되므로 완벽한 측정은 아닙니다.
7. 축하합니다
축하합니다. Electron에서 tfjs-tflite-node를 사용하여 첫 번째 Coral / WebNN 프로젝트를 완료했습니다.
다양한 이미지에서 사용해 보고 테스트해 보세요. TeachableMachine에서 완전히 다른 항목을 분류하도록 새 모델을 학습시킬 수도 있습니다.
요약
이 Codelab에서 배운 내용은 다음과 같습니다.
- Node.js에서 TFLite 모델을 실행하기 위해 tfjs-tflite-node npm 패키지를 설치하고 설정하는 방법
- Coral 기기에서 모델을 실행하기 위해 Edge TPU 런타임 라이브러리를 설치하는 방법
- Coral Edge TPU를 사용하여 모델 추론을 가속화하는 방법
- WebNN으로 모델 추론을 가속화하는 방법
다음 단계
이제 시작할 수 있는 작업 기반이 마련되었습니다. 머신러닝 모델 러너를 작업 중인 실제 사용 사례로 확장할 만한 창의적인 아이디어를 갖고 계신가요? 빠르고 저렴한 추론으로 업계에 혁명을 일으킬 수도 있고, 빵이 적당히 구워지면 토스트를 멈추도록 토스터를 수정할 수도 있습니다. 가능성은 무한합니다.
더 나아가 사용한 모델을 TeachableMachine이 학습시킨 방법을 자세히 알아보려면 전이 학습에 관한 Codelab을 확인하세요. 음성 인식, 자세 추정과 같이 Coral과 호환되는 다른 모델을 찾고 있다면 coral.ai/models를 참고하세요. TensorFlow Hub에서 이러한 모델의 CPU 버전과 기타 여러 모델을 확인할 수도 있습니다.
결과물 공유
오늘 만든 항목을 다른 창의적인 사용 사례로 쉽게 확장할 수 있으니 틀에 박히지 않은 생각을 하고 계속해서 실험해 보세요.
TensorFlow 블로그 또는 향후 이벤트에서 여러분의 프로젝트가 추천되는 기회를 얻으려면 소셜 미디어에서 #MadeWithTFJS 해시태그를 사용해 태그해 주세요. 여러분이 만든 작품을 보고 싶습니다.