Bài 38.5: Bài tập thực hành deploy AI application

Chào mừng các bạn quay trở lại với hành trình chinh phục Lập trình Web kết hợp AI! Sau khi đã cùng nhau tìm hiểu về các mô hình AI cơ bản, cách xây dựng và huấn luyện chúng, bài viết hôm nay sẽ tập trung vào một khâu cực kỳ quan trọng: biến những mô hình "offline" đó thành những ứng dụng AI có thể truy cập và sử dụng được bởi người dùng cuối thông qua môi trường Web. Đây chính là bước deploy AI application.

Tại sao việc deploy lại quan trọng đến vậy? Đơn giản là vì một mô hình AI dù có xuất sắc đến đâu, nếu nó chỉ nằm yên trên máy tính của bạn thì sẽ không thể mang lại giá trị cho người dùng. Deploy chính là cây cầu nối giữa thế giới mô hình và thế giới thực, giúp người dùng tương tác với trí tuệ nhân tạo mà bạn đã tạo ra.

Trong khuôn khổ bài viết này, chúng ta sẽ không đi quá sâu vào từng bước chi tiết của một nền tảng cụ thể (vì mỗi nền tảng có cách làm khác nhau), mà sẽ tập trung vào việc hiểu các chiến lược triển khai chính và xem xét các yếu tố cần cân nhắc khi đưa ứng dụng AI của bạn lên "mây" hoặc ra mắt công chúng.

Tại sao cần Deploy AI Application trong bối cảnh Web?

Series của chúng ta tập trung vào Lập trình Web. Khi tích hợp AI vào ứng dụng web, có hai kịch bản chính:

  1. AI hỗ trợ tính năng web: Ví dụ: gợi ý sản phẩm, phân loại bình luận, nhận diện hình ảnh tải lên, dịch văn bản... AI chạy "đằng sau" để cải thiện trải nghiệm hoặc chức năng của website.
  2. Website là giao diện cho ứng dụng AI chính: Ví dụ: website cho phép người dùng tải ảnh lên để AI nhận diện, website cung cấp công cụ tạo nội dung bằng AI, website chatbot AI... Website đóng vai trò là giao diện người dùng (UI) cho mô hình AI.

Dù là kịch bản nào, việc đưa mô hình AI hoạt động và phản hồi yêu cầu từ trình duyệt của người dùng là điều bắt buộc. Đó là lúc chúng ta cần đến deployment.

Các Chiến Lược Triển Khai AI Phổ Biến

Có nhiều cách để deploy một ứng dụng AI, mỗi cách có ưu và nhược điểm riêng. Lựa chọn chiến lược phụ thuộc vào nhiều yếu tố như kích thước mô hình, yêu cầu về độ trễ (latency), chi phí, mức độ phức tạp của mô hình, và tài nguyên sẵn có.

Dưới đây là một số chiến lược phổ biến:

1. Triển Khai trên Frontend (Browser-based AI)

Chiến lược này cho phép mô hình AI chạy trực tiếp trong trình duyệt của người dùng, sử dụng các thư viện JavaScript chuyên dụng như TensorFlow.js hoặc ONNX.js.

  • Ưu điểm:
    • Độ trễ thấp: Gần như không có độ trễ mạng vì tính toán diễn ra cục bộ.
    • Bảo mật dữ liệu: Dữ liệu của người dùng không cần gửi lên server.
    • Tiết kiệm chi phí server: Giảm tải đáng kể cho backend.
    • Hoạt động offline: Một số trường hợp có thể chạy mà không cần kết nối mạng (sau khi tải mô hình).
  • Nhược điểm:
    • Giới hạn về kích thước và độ phức tạp của mô hình: Trình duyệt có tài nguyên hạn chế hơn server.
    • Hiệu năng phụ thuộc vào thiết bị của người dùng: Máy yếu có thể chạy chậm hoặc không chạy được.
    • Hỗ trợ mô hình: Chỉ hỗ trợ các định dạng mô hình nhất định (thường là mô hình được convert sang định dạng web-friendly).

Code minh hoạ (TensorFlow.js):

Đây là ví dụ JavaScript đơn giản về cách tải và chạy một mô hình classification ảnh trong trình duyệt:

// Import thư viện TensorFlow.js (đã được thêm qua CDN hoặc npm)
// import * as tf from '@tensorflow/tfjs';

/**
 * Tải mô hình và thực hiện dự đoán trên một element ảnh.
 * @param {HTMLImageElement} imgElement - Thẻ <img> chứa ảnh cần xử lý.
 */
async function predictImageWithTFJS(imgElement) {
  // 1. Tải mô hình từ URL hoặc đường dẫn
  // Đảm bảo đường dẫn này trỏ đến file model.json của mô hình đã được convert
  try {
    console.log('Đang tải mô hình...');
    const model = await tf.loadLayersModel('path/to/your/tfjs/model.json');
    console.log('Mô hình đã tải xong.');

    // 2. Tiền xử lý ảnh để phù hợp với input của mô hình
    // Ví dụ: chuyển ảnh thành tensor, chuẩn hóa giá trị pixel, resize...
    const tensor = tf.browser.fromPixels(imgElement) // Chuyển ảnh thành tensor
      .toFloat() // Chuyển sang kiểu float
      .resizeBilinear([224, 224]) // Resize về kích thước input của mô hình (ví dụ 224x224)
      .expandDims(0); // Thêm chiều batch (batch size là 1)

    // 3. Thực hiện dự đoán
    console.log('Đang thực hiện dự đoán...');
    const predictions = model.predict(tensor);

    // 4. Lấy kết quả dự đoán và xử lý
    // Tùy thuộc vào bài toán (classification, regression...), cách xử lý predictions sẽ khác nhau
    const values = await predictions.data();
    console.log('Kết quả dự đoán raw:', values);

    // Ví dụ: Tìm index có xác suất cao nhất (cho bài toán classification)
    const topPrediction = Array.from(values).indexOf(Math.max(...values));
    console.log('Lớp được dự đoán:', topPrediction);

    // Giải phóng bộ nhớ của tensor
    tensor.dispose();
    predictions.dispose();
    console.log('Giải phóng bộ nhớ tensor.');

  } catch (error) {
    console.error('Lỗi khi tải hoặc chạy mô hình TF.js:', error);
  }
}

// Cách sử dụng: Gọi hàm này khi ảnh đã load và mô hình sẵn sàng
// const myImage = document.getElementById('inputImage');
// predictImageWithTFJS(myImage);

Giải thích code:

  • tf.loadLayersModel('path/to/your/tfjs/model.json'): Tải file cấu trúc mô hình và trọng số từ đường dẫn. Mô hình gốc (ví dụ từ Keras, PyTorch) cần được convert sang định dạng TensorFlow.js trước đó.
  • tf.browser.fromPixels(imgElement): Chuyển dữ liệu pixel từ một element ảnh HTML thành tensor.
  • .toFloat(), .resizeBilinear([...]), .expandDims(0): Các bước tiền xử lý phổ biến để đưa dữ liệu ảnh về đúng định dạng và kích thước mà mô hình mong đợi.
  • model.predict(tensor): Chạy tensor qua mô hình để lấy kết quả dự đoán (predictions).
  • predictions.data(): Lấy dữ liệu kết quả từ tensor predictions dưới dạng mảng kiểu TypedArray.
  • tensor.dispose(), predictions.dispose(): Rất quan trọng trong TensorFlow.js để giải phóng bộ nhớ GPU sau khi không dùng đến tensor nữa, tránh làm trình duyệt bị treo hoặc chậm.
2. Triển Khai trên Backend (Server-based AI)

Đây là chiến lược phổ biến nhất, nơi mô hình AI chạy trên server và được truy cập thông qua API (thường là REST API). Frontend sẽ gửi dữ liệu đến server và nhận kết quả từ server.

  • Ưu điểm:
    • Không giới hạn về kích thước và độ phức tạp của mô hình: Server có tài nguyên mạnh hơn (CPU, GPU, RAM).
    • Ngôn ngữ lập trình đa dạng: Có thể sử dụng Python (với TensorFlow, PyTorch, Scikit-learn), Java, C++,... để chạy mô hình.
    • Bảo vệ mô hình: Mô hình không bị lộ ra cho người dùng cuối.
    • Quản lý tập trung: Dễ dàng cập nhật mô hình, theo dõi hiệu năng, quản lý tài nguyên.
  • Nhược điểm:
    • Độ trễ mạng: Dữ liệu và kết quả phải truyền qua mạng.
    • Chi phí server: Cần có server để chạy mô hình, có thể tốn kém nếu yêu cầu tài nguyên lớn hoặc lượng truy cập cao.
    • Cần kiến thức về backend/server: Cần xây dựng và quản lý hạ tầng server.

Code minh hoạ (Backend Python + Frontend JS):

  • Backend (Flask - Python):

    ```python # Example using Flask framework from flask import Flask, request, jsonify # import numpy as np # import pickle # Hoặc thư viện load mô hình tương ứng (tf, torch, sk-learn)

    app = Flask(__name__)

    # Load mô hình AI khi ứng dụng khởi động # Tránh load lại mỗi khi có request để tối ưu hiệu năng # try: # with open('path/to/your/model.pkl', 'rb') as f: # model = pickle.load(f) # print("Mô hình AI đã được load thành công.") # except Exception as e: # print(f"Lỗi khi load mô hình: {e}") # model = None # Đặt model = None hoặc thoát ứng dụng nếu lỗi load

    @app.route('/predict', methods=['POST']) def predict():

    # Kiểm tra xem mô hình đã load chưa
    # if model is None:
    #     return jsonify({'error': 'Mô hình chưa sẵn sàng'}), 503 # Service Unavailable
    
    try:
        # Lấy dữ liệu đầu vào từ request POST (dạng JSON)
        data = request.get_json(force=True)
        # print(f"Nhận dữ liệu từ frontend: {data}")
    
        # Giả định data chứa các đặc trưng cần dự đoán, ví dụ: {'features': [v1, v2, v3]}
        # features = np.array(data['features']).reshape(1, -1) # Chuyển sang numpy array và reshape
    
        # Thực hiện dự đoán bằng mô hình
        # prediction_result = model.predict(features)
    
        # --- Đây là phần giả lập kết quả dự đoán ---
        # Thay thế bằng logic dự đoán thực tế của mô hình của bạn
        input_features = data.get('features', [0]) # Lấy features, mặc định là [0] nếu không có
        # Giả lập kết quả dựa trên input
        simulated_prediction = sum(input_features) * 10 # Ví dụ đơn giản
        # --- Kết thúc phần giả lập ---
        # Trả về kết quả dự đoán dưới dạng JSON
        # Dạng trả về có thể là một giá trị, một list, hoặc một object phức tạp
        return jsonify({
            'status': 'success',
            'prediction': simulated_prediction
            # 'prediction': prediction_result.tolist() # Convert numpy array result to list
        })

    except KeyError:
         # Xử lý trường hợp thiếu 'features' hoặc key khác cần thiết
        return jsonify({'error': 'Dữ liệu đầu vào không đúng định dạng JSON hoặc thiếu key cần thiết.'}), 400 # Bad Request

    except Exception as e:
        # Bắt các lỗi khác trong quá trình xử lý hoặc dự đoán
        print(f"Lỗi trong quá trình dự đoán: {e}")
        return jsonify({'error': f'Đã xảy ra lỗi server: {str(e)}'}), 500 # Internal Server Error

if __name__ == '__main__':
    # Chạy ứng dụng Flask. Trong môi trường production,
    # nên dùng các server mạnh mẽ hơn như Gunicorn, Waitress.
    print("Ứng dụng Flask AI Backend đang chạy...")
    app.run(debug=True, port=5000) # Chạy ở chế độ debug, cổng 5000
```

*Giải thích code Backend:*
*   `from flask import Flask, request, jsonify`: Import các module cần thiết từ Flask.
*   `app = Flask(__name__)`: Khởi tạo ứng dụng Flask.
*   Phần code được comment `# Load mô hình AI...`: Minh họa cách bạn nên load mô hình *một lần* khi ứng dụng khởi động, không phải trong mỗi request. Thay thế `pickle.load` bằng thư viện phù hợp với mô hình của bạn.
*   `@app.route('/predict', methods=['POST'])`: Định nghĩa một endpoint `/predict` chỉ chấp nhận request HTTP POST.
*   `request.get_json(force=True)`: Lấy dữ liệu JSON gửi từ frontend trong body của request POST.
*   Phần code được comment `# features = np.array(data['features']).reshape(1, -1)` và `# prediction_result = model.predict(features)`: Minh họa cách bạn xử lý dữ liệu nhận được và gọi phương thức dự đoán của mô hình đã load.
*   Phần code giữa `# --- Đây là phần giả lập... ---`: Là logic *giả lập* việc xử lý dữ liệu và trả về kết quả. Bạn sẽ thay thế nó bằng code gọi mô hình AI thực tế của mình.
*   `jsonify({...})`: Chuyển kết quả dự đoán thành phản hồi JSON để gửi về frontend.
*   `app.run(...)`: Chạy server Flask. `debug=True` hữu ích khi phát triển.
  • Frontend (JavaScript - dùng Fetch API):

    /**
     * Gửi dữ liệu đến backend AI API để lấy kết quả dự đoán.
     * @param {number[]} features - Mảng các đặc trưng (input) cho mô hình AI.
     * @returns {Promise<any>} - Promise trả về kết quả dự đoán từ backend.
     */
    async function callBackendPredictAPI(features) {
      // URL của endpoint predict trên backend của bạn
      const apiUrl = 'http://localhost:5000/predict'; // Thay đổi nếu backend chạy ở địa chỉ/cổng khác
    
      try {
        console.log('Đang gửi dữ liệu đến backend:', features);
        const response = await fetch(apiUrl, {
          method: 'POST', // Phương thức HTTP POST
          headers: {
            'Content-Type': 'application/json' // Cho biết body là JSON
          },
          body: JSON.stringify({ features: features }) // Chuyển dữ liệu features thành chuỗi JSON
        });
    
        // Kiểm tra status code của response
        if (!response.ok) {
          // Nếu status code không phải 2xx, có lỗi
          const errorData = await response.json(); // Lấy thông tin lỗi nếu có
          console.error(`Lỗi HTTP! Status: ${response.status}`, errorData);
          throw new Error(`API request failed with status ${response.status}: ${errorData.error || response.statusText}`);
        }
    
        // Parse response body thành JSON
        const result = await response.json();
        console.log('Nhận kết quả từ backend:', result);
    
        // Trả về phần prediction từ kết quả
        return result.prediction; // Tùy thuộc vào cấu trúc JSON trả về từ backend
    
      } catch (error) {
        console.error('Lỗi khi gọi API backend:', error);
        // Xử lý lỗi ở đây (ví dụ: hiển thị thông báo cho người dùng)
        throw error; // Ném lỗi để nơi gọi hàm này có thể bắt
      }
    }
    
    // Cách sử dụng (ví dụ):
    // const inputFeatures = [0.5, 1.2, 0.8];
    // callBackendPredictAPI(inputFeatures)
    //   .then(prediction => {
    //     console.log('Dự đoán cuối cùng:', prediction);
    //     // Cập nhật UI với kết quả prediction
    //   })
    //   .catch(error => {
    //     console.error('Không lấy được dự đoán:', error);
    //     // Cập nhật UI báo lỗi
    //   });
    

    Giải thích code Frontend:

    • fetch(apiUrl, { ... }): Sử dụng Fetch API để gửi request HTTP đến backend.
    • method: 'POST': Chỉ định đây là request POST.
    • headers: { 'Content-Type': 'application/json' }: Cài đặt header để báo cho server biết dữ liệu gửi đi là JSON.
    • body: JSON.stringify({ features: features }): Chuyển object/array features thành chuỗi JSON để gửi trong body của request. Key 'features' phải khớp với key mà backend mong đợi.
    • response.ok: Kiểm tra xem response có thành công (status code 2xx) hay không.
    • response.json(): Parse body của response từ chuỗi JSON thành object JavaScript.
    • Sử dụng .then().catch() hoặc async/await để xử lý kết quả thành công hoặc lỗi.
3. Triển Khai Serverless (FaaS - Function as a Service)

Sử dụng các dịch vụ như AWS Lambda, Google Cloud Functions, Azure Functions để chạy code AI. Mô hình AI được đóng gói cùng code xử lý và chạy trong một "function" chỉ khi có request đến.

  • Ưu điểm:
    • Tự động scale: Nền tảng tự động quản lý việc mở rộng dựa trên lượng request.
    • Chi phí theo usage: Chỉ trả tiền cho thời gian code chạy, phù hợp với tải lượng biến động.
    • Giảm thiểu quản lý server: Không cần lo lắng về việc quản lý hệ điều hành, patching, scaling máy chủ.
  • Nhược điểm:
    • Cold start: Lần đầu tiên function được gọi sau một thời gian không hoạt động có thể mất thêm thời gian để khởi động môi trường và load mô hình, gây ra độ trễ ban đầu.
    • Giới hạn về thời gian chạy và bộ nhớ: Mỗi function có giới hạn về thời gian thực thi và tài nguyên RAM/CPU được cấp.
    • Quản lý dependencies phức tạp: Đóng gói mô hình và các thư viện AI cần thiết vào function có thể phức tạp.

Code minh hoạ (AWS Lambda - Python):

# Example for AWS Lambda function using Python
import json
# import your_model_loading_library # e.g., tensorflow, pytorch, scikit-learn
# import your_model # Load model outside handler for warm starts

# Khai báo biến global để lưu mô hình đã load (cho phép reuse giữa các lần gọi)
# model = None # Placeholder for loaded model

def lambda_handler(event, context):
    """
    Hàm xử lý chính của Lambda.
    Được gọi mỗi khi có request (ví dụ từ API Gateway).
    """
    # global model # Sử dụng biến global để truy cập mô hình đã load

    # Tải mô hình nếu chưa được tải (chỉ chạy ở lần gọi đầu tiên hoặc sau cold start)
    # if model is None:
    #     print("Đang load mô hình...")
    #     # Thay thế bằng logic load mô hình của bạn
    #     # model = load_your_model('path/to/your/model.pkl') # Mô hình thường được lưu cùng function code
    #     print("Mô hình đã load.")

    try:
        # Lấy dữ liệu từ body của request HTTP (thường đến từ API Gateway)
        # Body thường là một chuỗi JSON
        body = json.loads(event['body'])

        # Giả định body là JSON object có key 'features', ví dụ: {'features': [v1, v2, v3]}
        features = body.get('features')
        if features is None:
             return {
                'statusCode': 400,
                'headers': { 'Content-Type': 'application/json' },
                'body': json.dumps({ 'error': 'Dữ liệu đầu vào thiếu key "features".' })
            }

        # --- Đây là phần giả lập kết quả dự đoán ---
        # Thay thế bằng logic dự đoán thực tế của mô hình của bạn
        simulated_prediction = sum(features) * 100 # Ví dụ đơn giản
        # --- Kết thúc phần giả lập ---

        # Thực hiện dự đoán bằng mô hình đã load
        # prediction_result = model.predict([features])[0] # Ví dụ cho mô hình Scikit-learn

        # Trả về kết quả theo định dạng mong muốn của API Gateway
        return {
            'statusCode': 200, # HTTP status code
            'headers': { 'Content-Type': 'application/json' }, # Header của response
            'body': json.dumps({ 'prediction': simulated_prediction }) # Body của response (chuỗi JSON)
        }

    except json.JSONDecodeError:
         return {
            'statusCode': 400,
            'headers': { 'Content-Type': 'application/json' },
            'body': json.dumps({ 'error': 'Body request không phải là JSON hợp lệ.' })
        }

    except Exception as e:
        # Bắt các lỗi khác
        print(f"Lỗi trong quá trình xử lý Lambda: {e}") # Log lỗi
        return {
            'statusCode': 500,
            'headers': { 'Content-Type': 'application/json' },
            'body': json.dumps({ 'error': f'Đã xảy ra lỗi server: {str(e)}' })
        }

# Lưu ý: Không có phần `if __name__ == '__main__':` trong code Lambda handler
# Môi trường Lambda sẽ gọi hàm `lambda_handler` tự động.

Giải thích code Serverless:

  • lambda_handler(event, context): Đây là hàm entry point mà dịch vụ Serverless gọi. event chứa thông tin về request (ví dụ: body, headers từ API Gateway), context chứa thông tin về môi trường thực thi.
  • Phần code được comment # global model và logic if model is None: ...: Là cách để giữ mô hình trong bộ nhớ giữa các lần gọi (nếu function không bị unload do idle), giúp giảm "cold start". Mô hình cần được đóng gói cùng code khi deploy function.
  • json.loads(event['body']): Parse chuỗi JSON từ body của request (thường được API Gateway đặt vào event['body']).
  • Phần code giữa # --- Đây là phần giả lập... ---: Logic giả lập xử lý input và tạo output, thay thế bằng code gọi mô hình thực tế.
  • Cấu trúc trả về { 'statusCode': ..., 'headers': ..., 'body': ... }: Định dạng tiêu chuẩn mà API Gateway (hoặc các dịch vụ tương tự) mong đợi để chuyển đổi thành phản hồi HTTP.
4. Triển Khai trên Nền Tảng Chuyên Dụng (Managed AI/ML Platforms)

Sử dụng các dịch vụ được quản lý hoàn toàn bởi các nhà cung cấp Cloud lớn như AWS SageMaker, Google AI Platform, Azure Machine Learning. Các nền tảng này cung cấp công cụ và hạ tầng chuyên biệt cho toàn bộ vòng đời của ứng dụng ML, bao gồm cả deployment.

  • Ưu điểm:
    • Đơn giản hóa quy trình: Nền tảng lo phần lớn công việc cấu hình, scaling, monitoring.
    • Tích hợp tốt: Thường đi kèm với các công cụ MLOps (quản lý phiên bản mô hình, pipeline huấn luyện...).
    • Hạ tầng mạnh mẽ: Dễ dàng sử dụng GPU, TPU và các phần cứng chuyên biệt khác.
  • Nhược điểm:
    • Chi phí cao: Thường đắt hơn việc tự quản lý server.
    • Vendor lock-in: Khó di chuyển sang nền tảng khác.
    • Ít linh hoạt: Có thể bị giới hạn bởi các tùy chọn cấu hình sẵn có của nền tảng.

Chúng ta sẽ không đi sâu vào code minh họa cho chiến lược này vì nó phụ thuộc nhiều vào giao diện và SDK cụ thể của từng nền tảng. Tuy nhiên, hiểu rằng đây là một lựa chọn mạnh mẽ cho các ứng dụng AI phức tạp hoặc quy mô lớn.

Các Yếu Tố Cần Cân Nhắc Khi Lựa Chọn Chiến Lược

Khi quyết định deploy AI của bạn theo cách nào, hãy tự hỏi:

  • Kích thước và độ phức tạp của mô hình: Mô hình quá lớn hoặc cần GPU chuyên dụng thường phải chạy trên backend/cloud.
  • Yêu cầu về độ trễ (Latency): Ứng dụng cần phản hồi ngay lập tức (ví dụ: phân tích video realtime) nên ưu tiên Frontend AI hoặc backend API có hiệu năng cao, độ trễ thấp.
  • Lượng truy cập dự kiến và khả năng mở rộng (Scalability): Backend API hoặc Serverless là lựa chọn tốt cho ứng dụng có lượng truy cập biến động hoặc tăng trưởng nhanh.
  • Chi phí: Frontend AI hoặc Serverless (cho tải lượng thấp/biến động) có thể tiết kiệm chi phí hơn việc duy trì server riêng hoạt động liên tục.
  • Yêu cầu bảo mật và quyền riêng tư: Frontend AI giữ dữ liệu trên máy người dùng; Backend/Serverless xử lý dữ liệu trên server (cần tuân thủ quy định).
  • Độ phức tạp của việc quản lý và bảo trì: Nền tảng chuyên dụng giúp giảm gánh nặng quản lý, trong khi tự deploy trên server riêng yêu cầu nhiều công sức hơn.
  • Ngôn ngữ và kỹ năng của đội ngũ: Nếu đội ngũ mạnh về JavaScript, Frontend AI hoặc Node.js backend có thể là lựa chọn tự nhiên. Nếu mạnh về Python, backend Python là phổ biến.

Đóng gói và Quản lý Dependencies (Đặc biệt cho Backend/Serverless)

Một thách thức lớn khi deploy AI là đảm bảo môi trường chạy mô hình có đủ các thư viện cần thiết (TensorFlow, PyTorch, Scikit-learn, NumPy, Pandas, v.v.) với đúng phiên bản.

  • Containerization (Docker): Docker là công cụ cực kỳ hữu ích. Bạn có thể đóng gói toàn bộ ứng dụng backend, mô hình AI và tất cả dependencies vào một Docker image. Điều này đảm bảo ứng dụng chạy nhất quán trên mọi môi trường hỗ trợ Docker (server riêng, Cloud VMs, Kubernetes...).

    Ý tưởng (không code Dockerfile đầy đủ):

    • File Dockerfile sẽ bắt đầu bằng một base image (ví dụ: Python).
    • Copy code backend và mô hình vào image.
    • Cài đặt các thư viện Python cần thiết (từ file requirements.txt).
    • Chạy lệnh để khởi động server Flask/FastAPI/... khi container chạy.
  • Environment Management (Virtual Environments): Trước khi đóng gói bằng Docker hoặc deploy serverless, hãy đảm bảo bạn đã quản lý các thư viện trong môi trường ảo (venv, conda) và ghi lại danh sách các thư viện cần thiết (ví dụ: pip freeze > requirements.txt).

Kết Nối Frontend và Backend AI

Trong kịch bản Backend hoặc Serverless AI, Frontend của bạn (được xây dựng bằng HTML, CSS, JavaScript, React, Next.js, v.v.) sẽ là nơi:

  1. Thu thập dữ liệu đầu vào từ người dùng (input text, file ảnh, giá trị từ form...).
  2. Gửi dữ liệu này đến endpoint API của backend AI (sử dụng fetch API, axios...).
  3. Nhận kết quả dự đoán từ backend.
  4. Hiển thị kết quả đó cho người dùng trên giao diện web.

Như bạn đã thấy trong code minh họa cho chiến lược Backend, việc giao tiếp giữa frontend và backend AI API về bản chất giống với việc frontend giao tiếp với bất kỳ API backend nào khác. Điểm khác biệt là backend này chạy mô hình AI thay vì chỉ thao tác với database thông thường.

Thực Hành

Bài tập thực hành cho bài này sẽ là:

  1. Chọn một mô hình AI đơn giản mà bạn đã xây dựng (ví dụ: mô hình phân loại ảnh nhỏ với TensorFlow/PyTorch, mô hình dự đoán giá nhà với Scikit-learn...).
  2. Chọn một trong các chiến lược deployment (Frontend với TF.js hoặc Backend với Flask/FastAPI là hai lựa chọn phổ biến nhất để bắt đầu).
  3. Chuẩn bị mô hình để deploy (convert sang định dạng TF.js nếu cần, hoặc lưu lại file .pkl, .h5, .pth...).
  4. Xây dựng một ứng dụng web cực kỳ đơn giản (có thể chỉ là một trang HTML, JS) làm giao diện người dùng.
  5. Triển khai mô hình AI theo chiến lược đã chọn.
    • Nếu chọn Frontend: Viết code JS để tải mô hình TF.js và chạy nó khi có sự kiện (ví dụ: người dùng chọn ảnh).
    • Nếu chọn Backend: Viết code backend API (Python Flask/FastAPI) để load mô hình và tạo endpoint /predict. Viết code JS frontend để gửi request POST với dữ liệu lên API đó và hiển thị kết quả.
  6. Kiểm tra xem ứng dụng web có thể gửi dữ liệu, nhận kết quả từ mô hình AI và hiển thị đúng không.

Việc thực hành này sẽ giúp bạn nắm vững luồng đi từ việc có mô hình đến việc biến nó thành một ứng dụng có thể tương tác được. Đừng ngại bắt đầu với những thứ đơn giản nhất!

Chúc bạn thành công với bài tập thực hành deploy ứng dụng AI đầu tiên của mình!

Comments

There are no comments at the moment.