fix(tests): stabilize OCR extraction tests and manage GPU containers
This commit is contained in:
@@ -2,10 +2,6 @@ import { execSync } from 'child_process';
|
||||
|
||||
// Project container names (only manage these)
|
||||
const PROJECT_CONTAINERS = [
|
||||
'paddleocr-vl-test',
|
||||
'paddleocr-vl-gpu-test',
|
||||
'paddleocr-vl-cpu-test',
|
||||
'paddleocr-vl-full-test',
|
||||
'minicpm-test',
|
||||
'nanonets-test',
|
||||
];
|
||||
@@ -24,30 +20,6 @@ export interface IImageConfig {
|
||||
}
|
||||
|
||||
export const IMAGES = {
|
||||
paddleocrVlGpu: {
|
||||
name: 'paddleocr-vl-gpu',
|
||||
dockerfile: 'Dockerfile_paddleocr_vl_gpu',
|
||||
buildContext: '.',
|
||||
containerName: 'paddleocr-vl-test',
|
||||
ports: ['8000:8000'],
|
||||
volumes: ['ht-huggingface-cache:/root/.cache/huggingface'],
|
||||
gpus: true,
|
||||
healthEndpoint: 'http://localhost:8000/health',
|
||||
healthTimeout: 300000, // 5 minutes for model loading
|
||||
} as IImageConfig,
|
||||
|
||||
paddleocrVlCpu: {
|
||||
name: 'paddleocr-vl-cpu',
|
||||
dockerfile: 'Dockerfile_paddleocr_vl_cpu',
|
||||
buildContext: '.',
|
||||
containerName: 'paddleocr-vl-test',
|
||||
ports: ['8000:8000'],
|
||||
volumes: ['ht-huggingface-cache:/root/.cache/huggingface'],
|
||||
gpus: false,
|
||||
healthEndpoint: 'http://localhost:8000/health',
|
||||
healthTimeout: 300000,
|
||||
} as IImageConfig,
|
||||
|
||||
minicpm: {
|
||||
name: 'minicpm45v',
|
||||
dockerfile: 'Dockerfile_minicpm45v_gpu',
|
||||
@@ -60,22 +32,6 @@ export const IMAGES = {
|
||||
healthTimeout: 120000,
|
||||
} as IImageConfig,
|
||||
|
||||
// Full PaddleOCR-VL pipeline with PP-DocLayoutV2 + structured JSON output
|
||||
paddleocrVlFull: {
|
||||
name: 'paddleocr-vl-full',
|
||||
dockerfile: 'Dockerfile_paddleocr_vl_full',
|
||||
buildContext: '.',
|
||||
containerName: 'paddleocr-vl-full-test',
|
||||
ports: ['8000:8000'],
|
||||
volumes: [
|
||||
'ht-huggingface-cache:/root/.cache/huggingface',
|
||||
'ht-paddleocr-cache:/root/.paddleocr',
|
||||
],
|
||||
gpus: true,
|
||||
healthEndpoint: 'http://localhost:8000/health',
|
||||
healthTimeout: 600000, // 10 minutes for model loading (vLLM + PP-DocLayoutV2)
|
||||
} as IImageConfig,
|
||||
|
||||
// Nanonets-OCR-s - Document OCR optimized VLM (Qwen2.5-VL-3B fine-tuned)
|
||||
nanonetsOcr: {
|
||||
name: 'nanonets-ocr',
|
||||
@@ -140,7 +96,7 @@ export function removeContainer(containerName: string): void {
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop all project containers that conflict with the required one
|
||||
* Stop all project containers that conflict with the required one (port-based)
|
||||
*/
|
||||
export function stopConflictingContainers(requiredContainer: string, requiredPort: string): void {
|
||||
// Stop project containers using the same port
|
||||
@@ -158,6 +114,24 @@ export function stopConflictingContainers(requiredContainer: string, requiredPor
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop all GPU-consuming project containers (for GPU memory management)
|
||||
* This ensures GPU memory is freed before starting a new GPU service
|
||||
*/
|
||||
export function stopAllGpuContainers(exceptContainer?: string): void {
|
||||
for (const container of PROJECT_CONTAINERS) {
|
||||
if (container === exceptContainer) continue;
|
||||
|
||||
if (isContainerRunning(container)) {
|
||||
console.log(`[Docker] Stopping GPU container: ${container}`);
|
||||
exec(`docker stop ${container}`, true);
|
||||
// Give the GPU a moment to free memory
|
||||
}
|
||||
}
|
||||
// Brief pause to allow GPU memory to be released
|
||||
execSync('sleep 2');
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a Docker image
|
||||
*/
|
||||
@@ -234,6 +208,11 @@ export async function ensureService(config: IImageConfig): Promise<boolean> {
|
||||
buildImage(config);
|
||||
}
|
||||
|
||||
// For GPU services, stop ALL other GPU containers to free GPU memory
|
||||
if (config.gpus) {
|
||||
stopAllGpuContainers(config.containerName);
|
||||
}
|
||||
|
||||
// Stop conflicting containers on the same port
|
||||
const mainPort = config.ports[0];
|
||||
stopConflictingContainers(config.containerName, mainPort);
|
||||
@@ -254,21 +233,7 @@ export async function ensureService(config: IImageConfig): Promise<boolean> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure PaddleOCR-VL GPU service is running
|
||||
*/
|
||||
export async function ensurePaddleOcrVlGpu(): Promise<boolean> {
|
||||
return ensureService(IMAGES.paddleocrVlGpu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure PaddleOCR-VL CPU service is running
|
||||
*/
|
||||
export async function ensurePaddleOcrVlCpu(): Promise<boolean> {
|
||||
return ensureService(IMAGES.paddleocrVlCpu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure MiniCPM service is running
|
||||
* Ensure MiniCPM service is running (Ollama with GPU)
|
||||
*/
|
||||
export async function ensureMiniCpm(): Promise<boolean> {
|
||||
return ensureService(IMAGES.minicpm);
|
||||
@@ -286,30 +251,6 @@ export function isGpuAvailable(): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure PaddleOCR-VL service (auto-detect GPU/CPU)
|
||||
*/
|
||||
export async function ensurePaddleOcrVl(): Promise<boolean> {
|
||||
if (isGpuAvailable()) {
|
||||
console.log('[Docker] GPU detected, using GPU image');
|
||||
return ensurePaddleOcrVlGpu();
|
||||
} else {
|
||||
console.log('[Docker] No GPU detected, using CPU image');
|
||||
return ensurePaddleOcrVlCpu();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure PaddleOCR-VL Full Pipeline service (PP-DocLayoutV2 + structured output)
|
||||
* This is the recommended service for production use - outputs structured JSON/Markdown
|
||||
*/
|
||||
export async function ensurePaddleOcrVlFull(): Promise<boolean> {
|
||||
if (!isGpuAvailable()) {
|
||||
console.log('[Docker] WARNING: Full pipeline requires GPU, but none detected');
|
||||
}
|
||||
return ensureService(IMAGES.paddleocrVlFull);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure an Ollama model is pulled and available
|
||||
* Uses the MiniCPM container (which runs Ollama) to pull the model
|
||||
|
||||
Reference in New Issue
Block a user