From f2e4c338bbf23fa55073acf74b4cfe3df9d8bc69 Mon Sep 17 00:00:00 2001 From: Asep Haryana Saputra <90584806+MythEclipse@users.noreply.github.com> Date: Sat, 23 May 2026 10:58:08 +0000 Subject: [PATCH] docs: align Rust ONNX service deployment docs - Update docker-compose.yml MODEL_PATH from best_model.keras to model.onnx - Fix Machine_Learning/README.md TOC and section numbering (remove duplicate section 9, add Validasi Parity ONNX as section 9) - Clarify parity validation as manual/recommended, not mandatory CI - Update CLAUDE.md to document Rust/Axum/ONNX Runtime ML service and ONNX export workflow - Simplify root README.md ML service section with port clarification (8001 local, 8000 container) - Remove stale endpoint examples from root README (documented in apps/ml-service/README.md) - Ensure no FastAPI/Uvicorn references in deployment documentation Co-Authored-By: Claude Opus 4.7 --- CLAUDE.md | 27 ++++++++++++++++++++++----- Machine_Learning/README.md | 8 +++++--- README.md | 18 +----------------- docker-compose.yml | 2 +- 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index a9b1dde..48573c0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,9 +4,9 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Repository overview -This repository currently contains the machine-learning pipeline for ZeaVis Edu: a corn leaf disease classifier trained with EfficientNetV2B0 and exported for production use as TensorFlow SavedModel, TFLite, and TensorFlow.js formats. +This repository contains the ZeaVis Edu application: a corn leaf disease classifier with a machine-learning pipeline (EfficientNetV2B0 training and export), a Rust/Axum/ONNX Runtime inference service, and a fullstack TypeScript application (React frontend, Elysia backend, PostgreSQL). -The active project lives under `Machine_Learning/`. Most commands should be run from that directory unless noted otherwise. +The ML pipeline lives under `Machine_Learning/`. The inference service lives under `apps/ml-service/`. Most ML commands should be run from the `Machine_Learning/` directory unless noted otherwise. ## Common commands @@ -34,6 +34,12 @@ Export a trained Keras model to SavedModel and TFLite after placing the Colab-tr python save_model.py ``` +Convert the SavedModel export to ONNX for the Rust ML service: + +```bash +python convert_onnx.py +``` + Convert the SavedModel export to TensorFlow.js via CLI: ```bash @@ -53,7 +59,7 @@ Open the training notebook locally if needed: jupyter notebook notebook.ipynb ``` -There is no project test suite, lint command, or build system configured in the current repository. +There is no project test suite, lint command, or build system configured in the ML pipeline. ## Fullstack app commands @@ -95,12 +101,20 @@ Run the web app directly: cd apps/web && bun run dev ``` +Run the ML service directly: + +```bash +cd apps/ml-service && cargo run +``` + ## High-level architecture - `Machine_Learning/preprocessing.py` prepares the training dataset locally. It extracts three source ZIP files, merges selected class folders into `dataset/`, maps selected Mandarin labels from Dataset 3 via `desc.json`, removes known problematic image files, then creates `dataset.zip` for upload to Google Drive/Colab. - `Machine_Learning/notebook.ipynb` is the training workflow intended for Google Colab with GPU enabled. It trains an EfficientNetV2B0-based classifier and saves the best model to Google Drive as `best_model.keras`. - `Machine_Learning/save_model.py` is the production export step. It loads `best_model/best_model.keras`, rebuilds a clean EfficientNetV2B0 architecture without training-time augmentation layers, copies weights into that model, exports `model/saved_model/`, and writes `model/model.tflite`. +- `Machine_Learning/convert_onnx.py` converts the SavedModel to ONNX format (`model/model.onnx`) for use by the Rust inference service. - TensorFlow.js export is intentionally done with the `tensorflowjs_converter` CLI rather than from Python to avoid protobuf/runtime conflicts documented in the README. +- `apps/ml-service/` is a Rust/Axum service that loads the ONNX model and serves HTTP endpoints for health checks, metadata, and image classification predictions. It uses ONNX Runtime for cross-platform inference performance. ## Fullstack application architecture @@ -108,9 +122,10 @@ The root TypeScript workspace is a Bun + Moon monorepo: - `apps/web/` contains the React + Vite + TypeScript frontend with React Router, TanStack Query, Zustand, Tailwind, and shadcn/ui-style components. - `apps/api/` contains the Elysia backend with health/status routes and Drizzle/PostgreSQL configuration. +- `apps/ml-service/` contains the Rust/Axum inference service with ONNX Runtime for model predictions. - `packages/shared/` contains shared TypeScript types and utilities consumed by both apps. -The backend reads `DATABASE_URL` for Drizzle/PostgreSQL, but the initial health/status endpoints do not require a live database connection. +The backend reads `DATABASE_URL` for Drizzle/PostgreSQL, but the initial health/status endpoints do not require a live database connection. The ML service reads `MODEL_PATH` (default `../../Machine_Learning/model/model.onnx`) and `MODEL_INPUT_SIZE` (default `224`). ## Model labels and dataset mapping @@ -134,10 +149,12 @@ The following files/directories are generated or externally supplied during the - `Machine_Learning/dataset_1.zip`, `dataset_2.zip`, `dataset_3.zip` — manually downloaded source datasets. - `Machine_Learning/dataset/` and `Machine_Learning/dataset.zip` — generated by `preprocessing.py`. - `Machine_Learning/best_model/best_model.keras` — trained model downloaded from Colab/Google Drive. -- `Machine_Learning/model/saved_model/`, `model/model.tflite`, and `model/tfjs_model/` — production exports. +- `Machine_Learning/model/saved_model/`, `model/model.tflite`, `model/model.onnx`, and `model/tfjs_model/` — production exports. ## Notes for future changes - Keep README command examples and this file in sync when changing the ML pipeline. - Preserve the current class label names unless the training notebook, preprocessing mappings, and downstream app/API expectations are updated together. - `save_model.py` assumes the clean architecture matches the trained model weights exactly; changes to the notebook model architecture usually require corresponding changes in `build_clean_model()`. +- The Rust ML service expects the ONNX model at the path specified by `MODEL_PATH`. Ensure `convert_onnx.py` is run after `save_model.py` to generate the ONNX artifact before deploying the service. + diff --git a/Machine_Learning/README.md b/Machine_Learning/README.md index 3930ebc..79b0ad4 100644 --- a/Machine_Learning/README.md +++ b/Machine_Learning/README.md @@ -14,7 +14,7 @@ Pipeline lengkap untuk klasifikasi penyakit daun jagung menggunakan **EfficientN 6. [Tahap 2 — Upload ke Google Drive & Training di Colab](#6-tahap-2--upload-ke-google-drive--training-di-colab) 7. [Tahap 3 — Download Model dari Colab](#7-tahap-3--download-model-dari-colab) 8. [Tahap 4 — Ekspor Model untuk Produksi](#8-tahap-4--ekspor-model-untuk-produksi) -9. [Tahap 5 — Konversi ke ONNX](#9-tahap-5--konversi-ke-onnx) +9. [Validasi Parity ONNX (Opsional)](#9-validasi-parity-onnx-opsional) 10. [Output Akhir](#10-output-akhir) 11. [Troubleshooting](#11-troubleshooting) @@ -330,7 +330,9 @@ Skrip ini akan: Model ONNX ini digunakan oleh layanan inferensi Rust di `apps/ml-service/` untuk performa dan kompatibilitas lintas platform yang lebih baik. -#### Validasi Parity ONNX +--- + +## 9. Validasi Parity ONNX (Opsional) Untuk memverifikasi bahwa model ONNX menghasilkan prediksi yang sama dengan SavedModel asli, jalankan: @@ -338,7 +340,7 @@ Untuk memverifikasi bahwa model ONNX menghasilkan prediksi yang sama dengan Save python validate_onnx_parity.py /path/to/corn-leaf.jpg ``` -Skrip ini akan membandingkan output prediksi antara SavedModel dan ONNX untuk memastikan keakuratan konversi. +Skrip ini akan membandingkan output prediksi antara SavedModel dan ONNX untuk memastikan keakuratan konversi. **Validasi ini bersifat manual dan direkomendasikan, bukan wajib untuk deployment.** --- diff --git a/README.md b/README.md index 8cdbfd2..51d97a6 100644 --- a/README.md +++ b/README.md @@ -166,23 +166,7 @@ Jika model berada di lokasi lain, gunakan environment variable `MODEL_PATH`: MODEL_PATH=/path/to/model.onnx cargo run ``` -## Endpoint Penting - -### ML Service - -| Method | Endpoint | Fungsi | -|---|---|---| -| GET | `/health` | Mengecek status service dan status model | -| GET | `/metadata` | Melihat metadata service, label, input size, dan path model | -| POST | `/predict` | Mengunggah gambar daun jagung untuk klasifikasi | - -Contoh verifikasi lokal: - -```bash -curl http://localhost:8001/health -curl http://localhost:8001/metadata -curl -X POST http://localhost:8001/predict -F "file=@/path/to/corn-leaf.jpg" -``` +Service mendengarkan di `http://localhost:8001` secara default untuk development lokal (lihat `apps/ml-service/.env.example`). Dalam Docker container, service mendengarkan di port `8000`. ## Docker Deployment diff --git a/docker-compose.yml b/docker-compose.yml index 9aaa4b3..6fd81ef 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -50,7 +50,7 @@ services: env_file: - .env environment: - MODEL_PATH: /app/model/best_model.keras + MODEL_PATH: /app/model/model.onnx MODEL_INPUT_SIZE: "224" labels: traefik.enable: "true"