Com WSL2 e docker
Tradução
Tradução
Detecção de objetos YOLOv5 usando TDL SDK da CVITEK.
O fluxo para fazer isso é aproximadamente o seguinte:
- Crie um inferência usando TDL SDK
- Converter o pré-modelo yolov5s.pt para o modelo ONNX
- Crie MLIR do modelo ONNX e cvimodel do MLIR
- Copie o inferência e o cvimodel para Milk-V Duo 256
- Experimente inferência usando imagens no Milk-V Duo
Em primeiro lugar, o que é o TDL da CVITEK?
O que é cvimodel?
Modelos de aprendizado de máquina criados para as TPUs acima.
Crie um raciocínio usando TDL SDK
> wget https://sophon-file.sophon.cn/sophon-prod-s3/drive/23/03/07/16/host-tools.tar.gz
> tar xvf host-tools.tar.gz
> export PATH=$PATH:$(pwd)/host-tools/gcc/riscv64-linux-musl-x86_64/bin
Depois de baixar o SDK para Duo256M com as variáveis de ambiente acima instaladas, execute o build shell.
Ao executar o shell, um conjunto completo de amostras é compilado.
> git clone https://github.com/milkv-duo/cvitek-tdl-sdk-sg200x.git
> cd cvitek-tdl-sdk-sg200x
> cd sample
> ./compile_sample.sh
sample_yolo5
gerado no diretório cvi_yolo .Crie um modelo de aprendizado de máquina para TPU
Desta vez seguiremos os passos do site oficial, começaremosyolov5s.pt
com um modelo PyTorch e finalmente geraremos um cvimodel
que possa ser usado com Milk-V Duo256M.
Construindo ambiente YOLOv5 e gerando modelo ONNX
ONNX (Open Neural Network Exchange) é um formato de representação intermediário para modelos usados para converter vários frameworks de treinamento e inferência de aprendizado profundo. Ele suporta múltiplos frameworks de aprendizado profundo, incluindo TensorFlow, PyTorch, Caffe, etc. Converter modelos para o formato ONNX torna mais fácil implantar e inferir em diferentes frameworks de aprendizado profundo sem a necessidade de treinar novamente os modelos.
Em aplicações práticas, os modelos podem ser treinados usando PyTorch ou TensorFlow, exportados para o formato ONNX e então convertidos para o formato de modelo suportado pelo dispositivo de destino. O ONNX define um conjunto de formatos e ambientes padrão independentes de plataforma para aprimorar a interoperabilidade de vários modelos de IA, tornando-o relativamente aberto.
O arquivo ONNX não apenas armazena os pesos do modelo de rede neural, mas também armazena as informações estruturais do modelo e as informações de entrada e saída de cada camada na rede. Ele pode ser visualizado usando Netron, o que facilita ajustes subsequentes do modelo no trabalho de desenvolvimento. Dependendo do modelo, você pode obter o código-fonte.
Após criar e ativar o ambiente venv, instale os módulos dependentes.
> git clone https://github.com/ultralytics/yolov5.git> cd yolov5
> python3 -m venv venv
> source venv/bin/activate
> pip3 install -r requirements.txt
> pip3 install onnx
baixar yolov5s.pt
e yolov5_export.py
e exportar modelos ONNX.
> wget https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5s.pt
> wget https://raw.githubusercontent.com/milkv-duo/cvitek-tdl-sdk-sg200x/main/sample/yolo_export/yolov5_export.py
> python3 yolov5_export.py --weights ./yolov5s.pt --img-size 640 640
> ls *.onnx
yolov5s.onnx
Crie MLIR a partir do modelo ONNX e cvimodel a partir do MLIR
Mantendo a pasta yolov5 como diretório atual, prossiga para obter o kit de ferramentas de conversão MLIR e construa seu ambiente de compilação em um contêiner Docker.
> docker run --rm --privileged --name tpudev -v ${PWD}:/workspace -it sophgo/tpuc_dev:latest
root@xxxx:/workspace# git clone https://github.com/milkv-duo/tpu-mlir.git
root@xxxx:/workspace# source ./tpu-mlir/envsetup.sh
A partir de agora iremos gerar arquivos, então crie uma pasta de trabalho e trabalhe nela.
root@xxxx:/workspace# mkdir work && cd work
Converter modelo ONNX em modelo MLIR
root@xxxx:/workspace# model_transform.py \--model_name yolov5s \
--model_def ../yolov5s.onnx \
--input_shapes [[1,3,640,640]] \
--mean 0.0,0.0,0.0 \
--scale 0.0039216,0.0039216,0.0039216 \
--keep_aspect_ratio \
--pixel_format rgb \
--test_input ../tpu-mlir/regression/image/dog.jpg \
--test_result yolov5s_top_outputs.npz \
--mlir yolov5s.mlir
Calibrar especificando um conjunto de dados? Demora um pouco.
root@xxxx:/workspace# run_calibration.py \yolov5s.mlir \
--dataset ../tpu-mlir/regression/dataset/COCO2017 \
--input_num 100 \
-o yolov5s_cali_table
Gere cvimodel. Se for para o SG2002, será.--chip cv181x
root@xxxx:/workspace# model_deploy.py \--mlir yolov5s.mlir \
--quant_input --quant_output \
--quantize INT8 \
--calibration_table yolov5s_cali_table \
--chip cv181x \
--test_input yolov5s_in_f32.npz \
--test_reference yolov5s_top_outputs.npz \
--tolerance 0.85,0.45 \
--model yolov5_cv181x_int8_sym.cvimodel
root@xxxx:/workspace# ls *.cvimodel
yolov5_cv181x_int8_sym.cvimodel
Experimente inferência com Milk-V Duo256M
Copie todos os arquivos necessários para Milk-V Duo256M. 000000000113.jpg |
dog.jpg
do site oficial.
Baixe tpu-sdk
Vá para o diretório /workspace
no terminal Docker
cd /workspace
Baixe tpu sdk, Se você estiver utilizando Duo, execute
git clone https://github.com/milkv-duo/tpu-sdk-cv180x.git
mv ./tpu-sdk-cv180x ./tpu-sdk
Caso contrário, se você estiver utilizando Duo 256M/Duo S , execute
git clone https://github.com/milkv-duo/tpu-sdk-sg200x.git
mv ./tpu-sdk-sg200x ./tpu-sdk
Copie arquivos tpu-sdk e modelos para o Duo
No terminal da placa Duo, crie um novo diretório /mnt/tpu/
# mkdir -p /mnt/tpu && cd /mnt/tpu
No terminal do Docker (ver como executar acima), copie arquivos tpu-sdk
e model para o Duo
# scp -r /workspace/tpu-sdk root@192.168.42.1:/mnt/tpu/
# scp yolov5_cv181x_int8_sym.cvimodel root@192.168.42.1:/mnt/tpu/tpu-sdk/
Set as variáveis de ambiente
No terminal da placa Duo, set as variáveis de ambiente
# cd /mnt/tpu/tpu-sdk
# source ./envs_tpu_sdk.sh
> ls
000000000113.jpg dog.jpg sample_yolov5 yolov5_cv181x_int8_sym.cvimodel
> scp * root@192.168.42.1:~/
> ssh root@192.168.42.1
Primeiro, vamos inferir dog.jpg
> ./sample_yolov5 yolov5_cv181x_int8_sym.cvimodel dog.jpgversion: 1.4.0
yolov5s Build at 2024-05-06 16:30:56 For platform cv181x
Max SharedMem size:5734400
model opened:yolov5_cv181x_int8_sym.cvimodel
detect res: 137.379303 217.066299 310.982025 541.966858 0.915610 16
detect res: 473.738098 71.988899 683.512390 176.103775 0.722637 2
detect res: 166.451904 118.458267 563.148132 423.640594 0.580343 1
detect res:
O valor a seguir está no formato Bounding Boxies, como PyTorch: X1, Y1, X2, Y2, Score, Classes .
O índice Classes utiliza o conjunto de dados COCO2017 , então acompanhe o texto abaixo. No entanto, a saída do índice pela ferramenta é de origem zero, portanto combine o valor +1 com o texto abaixo.
Por exemplo, o resultado acima seria o seguinte.
16 => dog(17)2 => car(3)
1 => bicycle(2)
Usando as informações do BoundingBox acima, tentei desenhar um retângulo usando o programa Python descrito posteriormente e o resultado é mostrado abaixo. Eu reconheço isso corretamente.
Da mesma forma, da próxima vez, tente inferir 000000000113.jpg .
> ./sample_yolov5 yolov5_cv181x_int8_sym.cvimodel 000000000113.jpg
version: 1.4.0
yolov5s Build at 2024-05-06 16:30:56 For platform cv181x
Max SharedMem size:5734400
model opened:yolov5_cv181x_int8_sym.cvimodel
detect res: 149.599243 52.756699 344.154053 434.715759 0.877362 0
detect res: 340.399902 96.056824 415.000000 423.052612 0.866147 0
detect res: 7.182785 34.055344 163.182800 521.089905 0.741203 0
detect res: 159.104950 433.623596 395.260651 550.903992 0.739044 55
detect res: 81.713333 456.810913 125.030563 518.194275 0.683194 41
detect res: 253.461395 364.123352 304.291901 454.123352 0.611235 43
detect res: 282.405457 93.188477 309.046570 121.621582 0.558343 41
detect res: 281.694244 61.441063 309.968231 91.748878 0.553116 41
Descobri que estava funcionando corretamente.
Se você preparar seu próprio modelo personalizado em vez do modelo yolov5s.pt , deverá ser capaz de detectar um objeto específico com Milk-V Duo256M.
Programa Python que desenha um retângulo usando o BoundingBox do resultado da detecção
sample_yolo5 gera apenas informações de BoundingBox, então abaixo está um programa Python que usa essas informações para desenhar um retângulo. As informações do resultado são codificadas, portanto, altere-as de acordo.
> python draw_boundingbox.py
# draw_boudingbox.py
import cv2
import numpy as np
# dog.jpg
input1 = {
"file":"dog.jpg",
"bounding_boxes" : [
[137.379303, 217.066299, 310.982025, 541.966858, 0.915610, 16],
[473.738098, 71.988899, 683.512390, 176.103775, 0.722637, 2],
[166.451904, 118.458267, 563.148132, 423.640594, 0.580343, 1],
]
}
# 000000000113.jpg
input2 = {
"file":"000000000113.jpg",
"bounding_boxes" : [
[149.599243, 52.756699, 344.154053, 434.715759, 0.877362, 0],
[340.399902, 96.056824, 415.000000, 423.052612, 0.866147, 0],
[7.182785, 34.055344, 163.182800, 521.089905, 0.741203, 0],
[159.104950, 433.623596, 395.260651, 550.903992, 0.739044, 55],
[81.713333, 456.810913, 125.030563, 518.194275, 0.683194, 41],
[253.461395, 364.123352, 304.291901, 454.123352, 0.611235, 43],
[282.405457, 93.188477, 309.046570, 121.621582, 0.558343, 41],
[281.694244, 61.441063, 309.968231, 91.748878, 0.553116, 41],
]
}
# どのデータを描画するか?
input_data = input2
# COCO2017 Labels
# https://github.com/amikelive/coco-labels/blob/master/coco-labels-2014_2017.txt
coco2017_labels = [
"person",
"bicycle",
"car",
"motorcycle",
"airplane",
"bus",
"train",
"truck",
"boat",
"traffic light",
"fire hydrant",
"stop sign",
"parking meter",
"bench",
"bird",
"cat",
"dog",
"horse",
"sheep",
"cow",
"elephant",
"bear",
"zebra",
"giraffe",
"backpack",
"umbrella",
"handbag",
"tie",
"suitcase",
"frisbee",
"skis",
"snowboard",
"sports ball",
"kite",
"baseball bat",
"baseball glove",
"skateboard",
"surfboard",
"tennis racket",
"bottle",
"wine glass",
"cup",
"fork",
"knife",
"spoon",
"bowl",
"banana",
"apple",
"sandwich",
"orange",
"broccoli",
"carrot",
"hot dog",
"pizza",
"donut",
"cake",
"chair",
"couch",
"potted plant",
"bed",
"dining table",
"toilet",
"tv",
"laptop",
"mouse",
"remote",
"keyboard",
"cell phone",
"microwave",
"oven",
"toaster",
"sink",
"refrigerator",
"book",
"clock",
"vase",
"scissors",
"teddy bear",
"hair drier",
"toothbrush"
]
def draw_bounding_boxes(image, bounding_boxes, labels, color=(0, 255, 255), thickness=2):
for bbox in bounding_boxes:
x1, y1, x2, y2, score, classes = bbox
cv2.rectangle(image, (int(x1), int(y1+10)), (int(x2), int(y2)), color, thickness)
txt = "%.2f %s"%(float(score), labels[int(classes)])
cv2.putText(image, txt, (int(x1), int(y1)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0,0,255), 2)
return image
# 画像の読み込み
image = cv2.imread(input_data["file"])
# Bounding Boxesの描画
image_with_boxes = draw_bounding_boxes(image.copy(), input_data["bounding_boxes"], coco2017_labels)
# 描画された画像の表示
cv2.imshow("Image with Bounding Boxes", image_with_boxes)
cv2.waitKey(0)
cv2.destroyAllWindows
Alguns testes
cat.jpg
Ref:
TPUMLIR 开源工具链项目 | 通用 AI 编译器工具链项目,高效将模型编译生成 TPU 执行代码
Object Detection Based on YOLOv5 | Milk-V
A SMARTCORE FORNECE CHIPS E MÓDULOS PARA IOT, COMUNICAÇÃO WIRELESS, BIOMETRIA, CONECTIVIDADE, RASTREAMENTO E AUTOMAÇÃO. NOSSO PORTFÓLIO INCLUI MODEM 2G/3G/4G/NB-IOT, SATELITAL, MÓDULOS WIFI, BLUETOOTH, GPS, SIGFOX, LORA, LEITOR DE CARTÃO, LEITOR QR CCODE, MECANISMO DE IMPRESSÃO, MINI-BOARD PC, ANTENA, PIGTAIL, BATERIA, REPETIDOR GPS E SENSORES.
Nenhum comentário:
Postar um comentário