|
475 | 475 | },
|
476 | 476 | {
|
477 | 477 | "cell_type": "code",
|
478 |
| - "execution_count": 3, |
| 478 | + "execution_count": 2, |
479 | 479 | "id": "da65a942-c764-4c6b-bbed-813d00ec51b7",
|
480 | 480 | "metadata": {
|
481 | 481 | "tags": []
|
|
509 | 509 | "print(f\"ONNX 模型已儲存至 {onnx_file_path}\")"
|
510 | 510 | ]
|
511 | 511 | },
|
| 512 | + { |
| 513 | + "cell_type": "markdown", |
| 514 | + "id": "cae98f28-7c4b-4b2e-906d-2a4731843cb1", |
| 515 | + "metadata": {}, |
| 516 | + "source": [ |
| 517 | + "### 1.4 使用ONNX Runtime進行推論測試\n", |
| 518 | + "我們可以先透過 ONNX Runtime 輸入一筆測試資料檢查推論結果。可以跟稍後 ONNX-MLIR 推論結果進行驗證比較看有沒有數值一至。" |
| 519 | + ] |
| 520 | + }, |
| 521 | + { |
| 522 | + "cell_type": "code", |
| 523 | + "execution_count": 15, |
| 524 | + "id": "dfa57338-f3ec-4c89-9225-67b5b5f5e81a", |
| 525 | + "metadata": {}, |
| 526 | + "outputs": [ |
| 527 | + { |
| 528 | + "name": "stdout", |
| 529 | + "output_type": "stream", |
| 530 | + "text": [ |
| 531 | + "[{0: 2.4887262043193914e-05, 1: 0.008561260998249054, 2: 0.9914138317108154}]\n" |
| 532 | + ] |
| 533 | + } |
| 534 | + ], |
| 535 | + "source": [ |
| 536 | + "import onnxruntime as ort\n", |
| 537 | + "import numpy as np\n", |
| 538 | + "\n", |
| 539 | + "# 加載 ONNX 模型\n", |
| 540 | + "session = ort.InferenceSession('iris_logistic_regression.onnx')\n", |
| 541 | + "\n", |
| 542 | + "# 準備輸入資料\n", |
| 543 | + "input_name = session.get_inputs()[0].name\n", |
| 544 | + "input_data = np.array([[6.3, 3.3, 6. , 2.5]], dtype=np.float32)\n", |
| 545 | + "\n", |
| 546 | + "# 進行推理\n", |
| 547 | + "pred_onnx = session.run(None, {input_name: input_data})[1]\n", |
| 548 | + "\n", |
| 549 | + "# 輸出預測結果\n", |
| 550 | + "print(pred_onnx)" |
| 551 | + ] |
| 552 | + }, |
512 | 553 | {
|
513 | 554 | "cell_type": "markdown",
|
514 | 555 | "id": "c6afb752-fe98-435f-a2c0-efe30ed2ee55",
|
515 | 556 | "metadata": {},
|
516 | 557 | "source": [
|
517 |
| - "### 1.3 使用 Hummingbird 將模型轉換為 ONNX 格式" |
| 558 | + "### 1.3 使用 Hummingbird 將模型轉換為 ONNX 格式\n", |
| 559 | + "onnx-mlir 的設計主要針對深度學習(DL)模型,例如 CNN、RNN 等神經網路,這些模型的特點是以張量(Tensor)為主要數據結構。 Logistic Regression 模型轉換為 ONNX 時,輸出的預測結果默認是 `Sequence<Map>` 類型,用於將分類概率與標籤對應起來。然而,這些類型並不是 onnx-mlir 所支持的張量類型,因此引發錯誤。\n", |
| 560 | + "\n", |
| 561 | + "> [1/6] Mon Nov 18 22:05:19 2024 (0s) Importing ONNX Model to MLIR Module from \"iris_logistic_regression.onnx\"\n", |
| 562 | + "Assertion failed: (elem_type.value_case() == onnx::TypeProto::kTensorType && \"expect tensor inside sequence type\"), function ImportSequenceType, file FrontendDialectTransformer.cpp, line 341.\n", |
| 563 | + "\n", |
| 564 | + "一個有效的解決方案是使用 Hummingbird,這是一個專門將傳統機器學習模型轉換為神經網路框架(如 PyTorch)的工具。 Hummingbird 可以將 Logistic Regression、Random Forest 等 scikit-learn 模型轉換為 PyTorch 模型。 轉換後的模型具有純張量輸入輸出結構,非常適合使用 onnx-mlir 編譯。" |
518 | 565 | ]
|
519 | 566 | },
|
520 | 567 | {
|
|
524 | 571 | "metadata": {},
|
525 | 572 | "outputs": [],
|
526 | 573 | "source": [
|
527 |
| - "# ! pip install onnxruntime==1.19.2 onnx==1.16.1" |
| 574 | + "# ! pip install onnxruntime==1.19.2 onnx==1.16.1 hummingbird-ml" |
528 | 575 | ]
|
529 | 576 | },
|
530 | 577 | {
|
531 | 578 | "cell_type": "code",
|
532 |
| - "execution_count": 4, |
| 579 | + "execution_count": 16, |
533 | 580 | "id": "e75efcac-0b6c-4c66-a248-40349081498b",
|
534 | 581 | "metadata": {},
|
535 | 582 | "outputs": [
|
536 | 583 | {
|
537 | 584 | "name": "stdout",
|
538 | 585 | "output_type": "stream",
|
539 | 586 | "text": [
|
540 |
| - "Model saved with digest: 1609dbcba26491d9bb02bec919f95901ba2140e5\n" |
| 587 | + "Model saved with digest: 351bd4be5772877c89c49c8da7aeafa2c4e6b669\n", |
| 588 | + "Archive: iris_logistic_regression_torch.zip\n", |
| 589 | + " inflating: dist/container.pkl \n", |
| 590 | + " inflating: dist/deploy_model.onnx \n", |
| 591 | + " inflating: dist/model_configuration.txt \n", |
| 592 | + " inflating: dist/model_type.txt \n" |
541 | 593 | ]
|
542 |
| - }, |
543 |
| - { |
544 |
| - "data": { |
545 |
| - "text/plain": [ |
546 |
| - "'1609dbcba26491d9bb02bec919f95901ba2140e5'" |
547 |
| - ] |
548 |
| - }, |
549 |
| - "execution_count": 4, |
550 |
| - "metadata": {}, |
551 |
| - "output_type": "execute_result" |
552 | 594 | }
|
553 | 595 | ],
|
554 | 596 | "source": [
|
|
558 | 600 | "hb_model = convert(onnx_model, 'onnx')\n",
|
559 | 601 | "\n",
|
560 | 602 | "# 保存轉換後的 ONNX 模型\n",
|
561 |
| - "hb_model.save('iris_logistic_regression_torch')" |
| 603 | + "hb_model.save('iris_logistic_regression_torch')\n", |
| 604 | + "\n", |
| 605 | + "# 解壓縮資料夾\n", |
| 606 | + "!unzip -o iris_logistic_regression_torch.zip -d dist" |
| 607 | + ] |
| 608 | + }, |
| 609 | + { |
| 610 | + "cell_type": "code", |
| 611 | + "execution_count": 19, |
| 612 | + "id": "bf5121bc-2e91-40f5-ac50-6d7412a0f0a1", |
| 613 | + "metadata": {}, |
| 614 | + "outputs": [ |
| 615 | + { |
| 616 | + "name": "stdout", |
| 617 | + "output_type": "stream", |
| 618 | + "text": [ |
| 619 | + "[[2.4887262e-05 8.5612610e-03 9.9141383e-01]]\n" |
| 620 | + ] |
| 621 | + } |
| 622 | + ], |
| 623 | + "source": [ |
| 624 | + "import onnxruntime as ort\n", |
| 625 | + "import numpy as np\n", |
| 626 | + "\n", |
| 627 | + "# 加載 ONNX 模型\n", |
| 628 | + "session = ort.InferenceSession('./dist/deploy_model.onnx')\n", |
| 629 | + "\n", |
| 630 | + "# 準備輸入資料\n", |
| 631 | + "input_name = session.get_inputs()[0].name\n", |
| 632 | + "input_data = np.array([[6.3, 3.3, 6. , 2.5]], dtype=np.float32)\n", |
| 633 | + "\n", |
| 634 | + "# 進行推理\n", |
| 635 | + "pred_onnx = session.run(None, {input_name: input_data})[1]\n", |
| 636 | + "\n", |
| 637 | + "# 輸出預測結果\n", |
| 638 | + "print(pred_onnx)" |
562 | 639 | ]
|
563 | 640 | },
|
564 | 641 | {
|
|
578 | 655 | },
|
579 | 656 | {
|
580 | 657 | "cell_type": "code",
|
581 |
| - "execution_count": 7, |
| 658 | + "execution_count": 6, |
582 | 659 | "id": "37a60184-7b15-47c3-95d7-22340cd7155b",
|
583 | 660 | "metadata": {
|
584 | 661 | "tags": []
|
|
588 | 665 | "name": "stdout",
|
589 | 666 | "output_type": "stream",
|
590 | 667 | "text": [
|
591 |
| - "/bin/bash: line 1: ../onnx-mlir/Release/bin/onnx-mlir: cannot execute binary file: Exec format error\n" |
| 668 | + "Archive: iris_logistic_regression_torch.zip\n", |
| 669 | + " inflating: dist/container.pkl \n", |
| 670 | + " inflating: dist/deploy_model.onnx \n", |
| 671 | + " inflating: dist/model_configuration.txt \n", |
| 672 | + " inflating: dist/model_type.txt \n", |
| 673 | + "[1/6] Mon Nov 18 22:15:35 2024 (0s) Importing ONNX Model to MLIR Module from \"deploy_model.onnx\"\n", |
| 674 | + "[2/6] Mon Nov 18 22:15:35 2024 (0s) Compiling and Optimizing MLIR Module\n", |
| 675 | + "[3/6] Mon Nov 18 22:15:35 2024 (0s) Translating MLIR Module to LLVM and Generating LLVM Optimized Bitcode\n", |
| 676 | + "[4/6] Mon Nov 18 22:15:35 2024 (0s) Generating Object from LLVM Bitcode\n", |
| 677 | + "[5/6] Mon Nov 18 22:15:35 2024 (0s) Linking and Generating the Output Shared Library\n", |
| 678 | + "[6/6] Mon Nov 18 22:15:36 2024 (1s) Compilation completed\n" |
592 | 679 | ]
|
593 | 680 | }
|
594 | 681 | ],
|
595 | 682 | "source": [
|
596 |
| - "# !unzip -o iris_logistic_regression_torch.zip -d dist\n", |
597 |
| - "!../onnx-mlir/Release/bin/onnx-mlir --EmitLib iris_logistic_regression.onnx" |
| 683 | + "!../onnx-mlir/Release/bin/onnx-mlir --EmitLib ./dist/deploy_model.onnx" |
598 | 684 | ]
|
599 | 685 | },
|
600 | 686 | {
|
601 | 687 | "cell_type": "markdown",
|
602 |
| - "id": "b8fa986e-af75-4cfd-8faa-302836b7d373", |
| 688 | + "id": "9123da46-ef67-4011-ac1b-8ed8c963ffdb", |
603 | 689 | "metadata": {},
|
604 | 690 | "source": [
|
605 |
| - "### 編寫 C++ 程式以載入並執行模型" |
| 691 | + "成功轉換共享庫後會產生一個 `deploy_model.so` 檔案。我們可以透過系統指令來觀察這個共享庫相依哪些檔案。" |
606 | 692 | ]
|
607 | 693 | },
|
608 | 694 | {
|
609 | 695 | "cell_type": "code",
|
610 |
| - "execution_count": 34, |
611 |
| - "id": "036db295-6125-4b96-8dfe-66dbd4038a85", |
| 696 | + "execution_count": 12, |
| 697 | + "id": "a0f723de-61e7-40ac-9a07-5bae36b56181", |
612 | 698 | "metadata": {},
|
613 | 699 | "outputs": [
|
614 | 700 | {
|
615 | 701 | "name": "stdout",
|
616 | 702 | "output_type": "stream",
|
617 | 703 | "text": [
|
618 |
| - "模型输出:2.48873e-05 0.00856126 0.991414 \n" |
| 704 | + "dist/deploy_model.so:\n", |
| 705 | + "\t./dist/deploy_model.so (compatibility version 0.0.0, current version 0.0.0)\n", |
| 706 | + "\t/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1500.65.0)\n", |
| 707 | + "\t/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1319.100.3)\n" |
619 | 708 | ]
|
620 | 709 | }
|
621 | 710 | ],
|
622 | 711 | "source": [
|
623 |
| - "!g++ --std=c++17 inference.cpp dist/deploy_model.so -o main -I../onnx-mlir/include\n", |
624 |
| - "!./main" |
| 712 | + "# mac 使用 otool \n", |
| 713 | + "# Linux 使用 ldd\n", |
| 714 | + "!otool -L dist/deploy_model.so" |
625 | 715 | ]
|
626 | 716 | },
|
627 | 717 | {
|
628 | 718 | "cell_type": "code",
|
629 |
| - "execution_count": 33, |
| 719 | + "execution_count": 9, |
630 | 720 | "id": "b062bf8d-9681-4fa4-890b-d723fffa0e08",
|
631 | 721 | "metadata": {},
|
632 | 722 | "outputs": [
|
|
646 | 736 | }
|
647 | 737 | ],
|
648 | 738 | "source": [
|
| 739 | + "# 檢查共享庫的結構和依賴\n", |
649 | 740 | "!ld dist/deploy_model.so"
|
650 | 741 | ]
|
651 | 742 | },
|
652 | 743 | {
|
653 | 744 | "cell_type": "markdown",
|
654 |
| - "id": "b8651b7d-7b38-485c-b178-c866abd5461d", |
| 745 | + "id": "b8fa986e-af75-4cfd-8faa-302836b7d373", |
655 | 746 | "metadata": {},
|
656 | 747 | "source": [
|
657 |
| - "## TVM" |
| 748 | + "### 3. 撰寫 C++ 程式進行推論\n", |
| 749 | + "\n", |
| 750 | + "- [參考官方文件C Runtime API](https://onnx.ai/onnx-mlir/doxygen_html/OnnxMlirRuntime/index.html)\n", |
| 751 | + "\n", |
| 752 | + "### 3.1 撰寫 C++ 程式\n", |
| 753 | + "\n", |
| 754 | + "> 請參考 sklearn-example/inference.cpp\n", |
| 755 | + "\n", |
| 756 | + "### 3.2 編譯程式 \n" |
| 757 | + ] |
| 758 | + }, |
| 759 | + { |
| 760 | + "cell_type": "code", |
| 761 | + "execution_count": 7, |
| 762 | + "id": "036db295-6125-4b96-8dfe-66dbd4038a85", |
| 763 | + "metadata": {}, |
| 764 | + "outputs": [ |
| 765 | + { |
| 766 | + "name": "stdout", |
| 767 | + "output_type": "stream", |
| 768 | + "text": [ |
| 769 | + "模型输出:2.48873e-05 0.00856126 0.991414 \n" |
| 770 | + ] |
| 771 | + } |
| 772 | + ], |
| 773 | + "source": [ |
| 774 | + "!g++ --std=c++17 inference.cpp dist/deploy_model.so -o main -I../onnx-mlir/include\n", |
| 775 | + "!./main" |
| 776 | + ] |
| 777 | + }, |
| 778 | + { |
| 779 | + "cell_type": "markdown", |
| 780 | + "id": "b8651b7d-7b38-485c-b178-c866abd5461d", |
| 781 | + "metadata": { |
| 782 | + "jp-MarkdownHeadingCollapsed": true |
| 783 | + }, |
| 784 | + "source": [ |
| 785 | + "# TVM" |
658 | 786 | ]
|
659 | 787 | },
|
660 | 788 | {
|
|
1257 | 1385 | "source": [
|
1258 | 1386 | "lib.export_library(\"c_model.tar\", cc.create_shared, cc=\"g++\")"
|
1259 | 1387 | ]
|
1260 |
| - }, |
1261 |
| - { |
1262 |
| - "cell_type": "markdown", |
1263 |
| - "id": "cae98f28-7c4b-4b2e-906d-2a4731843cb1", |
1264 |
| - "metadata": {}, |
1265 |
| - "source": [ |
1266 |
| - "## 使用ONNX Runtime推論比對結果" |
1267 |
| - ] |
1268 |
| - }, |
1269 |
| - { |
1270 |
| - "cell_type": "code", |
1271 |
| - "execution_count": 12, |
1272 |
| - "id": "dfa57338-f3ec-4c89-9225-67b5b5f5e81a", |
1273 |
| - "metadata": {}, |
1274 |
| - "outputs": [ |
1275 |
| - { |
1276 |
| - "name": "stdout", |
1277 |
| - "output_type": "stream", |
1278 |
| - "text": [ |
1279 |
| - "[[2.4887262e-05 8.5612610e-03 9.9141383e-01]]\n" |
1280 |
| - ] |
1281 |
| - } |
1282 |
| - ], |
1283 |
| - "source": [ |
1284 |
| - "import onnxruntime as ort\n", |
1285 |
| - "\n", |
1286 |
| - "# 加載 ONNX 模型\n", |
1287 |
| - "session = ort.InferenceSession('dist/deploy_model.onnx')\n", |
1288 |
| - "\n", |
1289 |
| - "# 準備輸入資料\n", |
1290 |
| - "input_name = session.get_inputs()[0].name\n", |
1291 |
| - "input_data = np.array([[6.3, 3.3, 6. , 2.5]], dtype=np.float32)\n", |
1292 |
| - "\n", |
1293 |
| - "# 進行推理\n", |
1294 |
| - "pred_onnx = session.run(None, {input_name: input_data})[1]\n", |
1295 |
| - "\n", |
1296 |
| - "# 輸出預測結果\n", |
1297 |
| - "print(pred_onnx)" |
1298 |
| - ] |
1299 |
| - }, |
1300 |
| - { |
1301 |
| - "cell_type": "code", |
1302 |
| - "execution_count": null, |
1303 |
| - "id": "f8091b61-1312-4f18-989b-4165203b191f", |
1304 |
| - "metadata": {}, |
1305 |
| - "outputs": [], |
1306 |
| - "source": [] |
1307 | 1388 | }
|
1308 | 1389 | ],
|
1309 | 1390 | "metadata": {
|
|
1322 | 1403 | "name": "python",
|
1323 | 1404 | "nbconvert_exporter": "python",
|
1324 | 1405 | "pygments_lexer": "ipython3",
|
1325 |
| - "version": "3.9.18" |
| 1406 | + "version": "3.10.15" |
1326 | 1407 | }
|
1327 | 1408 | },
|
1328 | 1409 | "nbformat": 4,
|
|
0 commit comments