Tự động kiểm thử API mô hình FLUX.1 với GitHub Actions

Lý do cần kiểm thử tự động cho API mô hình FLUX.1

Khi phát triển API sinh ảnh dựa trên mô hình FLUX.1, việc xác minh tính đúng đắn sau mỗi lần thay đổi mã nguồn thường tốn nhiều thời gian nếu thực hiện thủ công. Việc này không chỉ dễ bỏ sót lỗi mà còn làm chậm quá trình phát triển.

Một sự cố nhỏ như làm chậm phản hồi API có thể chỉ được phát hiện khi người dùng phàn nàn. Giải pháp là xây dựng hệ thống kiểm thử tự động chạy mỗi khi có commit mới — đảm bảo chức năng, hiệu năng và độ ổn định của API luôn được kiểm chứng liên tục.

GitHub Actions cung cấp nền tảng lý tưởng để thiết lập pipeline CI/CD cho FLUX.1, bao gồm kiểm thử giao diện, benchmark hiệu năng và kiểm thử hồi quy.

Thiết lập môi trường kiểm thử

Cơ sở hạ tầng kiểm thử

Vì FLUX.1 yêu cầu GPU để suy luận, môi trường kiểm thử nên được cấu hình trên self-hosted runner có hỗ trợ CUDA:

test_environment:
  gpu: true
  cuda_version: "11.8"
  python_version: "3.10"
  dependencies:
    - torch==2.0.1
    - torchvision==0.15.2
    - transformers==4.30.0
    - diffusers==0.19.0
    - requests==2.31.0
    - pytest==7.3.1

Nếu không có máy chủ GPU cục bộ, có thể tích hợp runner với instance GPU từ các nhà cung cấp đám mây. Điều quan trọng là môi trường kiểm thử phải gần giống môi trường production.

Dữ liệu kiểm thử

Bộ dữ liệu prompt đa dạng giúp kiểm tra toàn diện khả năng của mô hình:

validation_cases = [
    {
        "text": "Một con mèo đáng yêu đang chơi trong vườn dưới ánh nắng",
        "tags": ["animal", "outdoor", "daylight"]
    },
    {
        "text": "Thành phố tương lai với ánh đèn neon, phong cách cyberpunk, độ phân giải cao",
        "tags": ["urban", "neon", "sci-fi"]
    },
    {
        "text": "Ảnh chụp món ăn chuyên nghiệp: mì Ý, ánh sáng studio, kích thích vị giác",
        "tags": ["food", "pasta", "studio"]
    }
]

Xây dựng pipeline kiểm thử trên GitHub Actions

Cấu hình workflow cơ bản

Tạo file .github/workflows/flux1-validation.yml:

name: FLUX.1 Validation Pipeline

on:
  push:
    branches: [ main, dev ]
  pull_request:
    branches: [ main ]

jobs:
  validate:
    runs-on: [self-hosted, linux, gpu]
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.10'
          
      - name: Install dependencies
        run: |
          pip install -r requirements.txt
          pip install pytest requests pillow opencv-python scikit-image

Kiểm thử chức năng

Sử dụng pytest để xác minh hành vi API:

# tests/test_generation.py
import pytest
import requests
import base64
from PIL import Image
from io import BytesIO

def test_health_check(base_url):
    resp = requests.get(f"{base_url}/health")
    assert resp.status_code == 200
    assert resp.json().get("status") == "ok"

def test_image_generation(base_url):
    payload = {
        "prompt": "Chú chó vàng đang chạy trên bãi cỏ xanh",
        "steps": 20,
        "cfg_scale": 7.5
    }
    resp = requests.post(f"{base_url}/infer", json=payload, timeout=90)
    assert resp.status_code == 200
    
    img_b64 = resp.json().get("output")
    assert img_b64 is not None
    
    img_bytes = base64.b64decode(img_b64)
    img = Image.open(BytesIO(img_bytes))
    assert img.size == (512, 512)
    assert img.mode in ("RGB", "RGBA")

Kiểm thử hiệu năng

Đo độ trễ trung bình qua nhiều lần gọi:

# tests/test_performance.py
import time
import statistics

def test_inference_latency(base_url):
    durations = []
    for _ in range(3):
        start = time.time()
        resp = requests.post(
            f"{base_url}/infer",
            json={"prompt": "benchmark image", "steps": 15},
            timeout=60
        )
        end = time.time()
        assert resp.status_code == 200
        durations.append(end - start)
    
    avg_time = statistics.mean(durations)
    assert avg_time < 35  # giây

Chiến lược kiểm thử nâng cao

Đánh giá chất lượng ảnh

Dùng các chỉ số khách quan để đo lường chất lượng đầu ra:

# tests/test_quality.py
import cv2
import numpy as np

def assess_image_clarity(pil_img):
    arr = np.array(pil_img)
    gray = cv2.cvtColor(arr, cv2.COLOR_RGB2GRAY)
    laplacian_var = cv2.Laplacian(gray, cv2.CV_64F).var()
    return laplacian_var > 120  # ngưỡng sắc nét tối thiểu

def assess_contrast(pil_img):
    arr = np.array(pil_img)
    return np.std(arr) > 45

Bộ kiểm thử hồi quy

Đảm bảo các tính năng cũ không bị ảnh hưởng sau mỗi thay đổi:

# regression-suite.yaml
suites:
  core:
    - tests/test_generation.py::test_health_check
    - tests/test_generation.py::test_image_generation
  edge_cases:
    - tests/test_edge.py::test_empty_prompt
    - tests/test_edge.py::test_unicode_prompt
  performance:
    - tests/test_performance.py::test_inference_latency

Phân tích kết quả và báo cáo

Tích hợp xuất báo cáo JUnit và coverage:

- name: Execute validation suite
  run: pytest --junitxml=results.xml --cov=app --cov-report=xml

- name: Archive artifacts
  uses: actions/upload-artifact@v3
  with:
    name: validation-reports
    path: |
      results.xml
      coverage.xml

- name: Enforce quality gates
  run: |
    python -c "
    import xml.etree.ElementTree as ET
    r = ET.parse('results.xml').getroot()
    if int(r.attrib['failures']) + int(r.attrib['errors']) > 0:
        exit(1)
    c = ET.parse('coverage.xml').getroot()
    if float(c.attrib['line-rate']) < 0.75:
        exit(1)
    "

Thẻ: GitHub Actions FLUX.1 AI testing CI/CD Image Generation

Đăng vào ngày 5 tháng 9 lúc 13:32