fix(vision): enable ML training on production server
Research confirmed TensorFlow has wheels for Linux x86_64 (including Synology NAS). The previous failures were due to: 1. Training scripts not being copied to Docker image 2. Venv path not being writable in container Changes: - Update isPlatformSupported() to include Linux ARM64 support - Move venv to data/vision-training/.venv (mounted volume, writable) - Add python3-venv to Docker image dependencies - Copy training scripts to Docker image - Create vision-training directories in Docker build Sources: - https://www.tensorflow.org/install/pip - https://pypi.org/project/tensorflow/ (shows manylinux_2_17_aarch64 wheels) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
2eee17e159
commit
a40087284c
|
|
@ -568,7 +568,8 @@
|
||||||
"Bash(scripts/train-column-classifier/.venv/bin/python:*)",
|
"Bash(scripts/train-column-classifier/.venv/bin/python:*)",
|
||||||
"Bash(brew list:*)",
|
"Bash(brew list:*)",
|
||||||
"Bash(scripts/train-column-classifier/.venv/bin/pip index:*)",
|
"Bash(scripts/train-column-classifier/.venv/bin/pip index:*)",
|
||||||
"Bash(scripts/train-column-classifier/.venv/bin/pip:*)"
|
"Bash(scripts/train-column-classifier/.venv/bin/pip:*)",
|
||||||
|
"WebFetch(domain:pypi.org)"
|
||||||
],
|
],
|
||||||
"deny": [],
|
"deny": [],
|
||||||
"ask": []
|
"ask": []
|
||||||
|
|
|
||||||
|
|
@ -110,9 +110,11 @@ FROM node:20-slim AS runner
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Install ONLY runtime dependencies (no build tools)
|
# Install ONLY runtime dependencies (no build tools)
|
||||||
|
# python3-venv is needed for creating virtual environments for ML training
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
python3 \
|
python3 \
|
||||||
python3-pip \
|
python3-pip \
|
||||||
|
python3-venv \
|
||||||
qpdf \
|
qpdf \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
@ -154,6 +156,9 @@ COPY --from=builder --chown=nextjs:nodejs /app/packages/templates ./packages/tem
|
||||||
# Copy abacus-react package (needed for calendar generation scripts)
|
# Copy abacus-react package (needed for calendar generation scripts)
|
||||||
COPY --from=builder --chown=nextjs:nodejs /app/packages/abacus-react ./packages/abacus-react
|
COPY --from=builder --chown=nextjs:nodejs /app/packages/abacus-react ./packages/abacus-react
|
||||||
|
|
||||||
|
# Copy ML training scripts (for vision model training)
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/scripts/train-column-classifier ./apps/web/scripts/train-column-classifier
|
||||||
|
|
||||||
# Install Python dependencies for flashcard generation
|
# Install Python dependencies for flashcard generation
|
||||||
RUN pip3 install --no-cache-dir --break-system-packages -r packages/core/requirements.txt
|
RUN pip3 install --no-cache-dir --break-system-packages -r packages/core/requirements.txt
|
||||||
|
|
||||||
|
|
@ -164,8 +169,8 @@ COPY --from=builder --chown=nextjs:nodejs /app/apps/web/package.json ./apps/web/
|
||||||
# Set up environment
|
# Set up environment
|
||||||
WORKDIR /app/apps/web
|
WORKDIR /app/apps/web
|
||||||
|
|
||||||
# Create data directory for SQLite database and uploads
|
# Create data directory for SQLite database, uploads, and vision training
|
||||||
RUN mkdir -p data/uploads && chown -R nextjs:nodejs data
|
RUN mkdir -p data/uploads data/vision-training/collected data/vision-training/.venv && chown -R nextjs:nodejs data
|
||||||
|
|
||||||
USER nextjs
|
USER nextjs
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
|
||||||
|
|
@ -64,4 +64,5 @@ data/uploads/
|
||||||
# ML training data
|
# ML training data
|
||||||
training-data/
|
training-data/
|
||||||
data/vision-training/collected/
|
data/vision-training/collected/
|
||||||
|
data/vision-training/.venv/
|
||||||
scripts/train-column-classifier/.venv/
|
scripts/train-column-classifier/.venv/
|
||||||
|
|
|
||||||
|
|
@ -17,30 +17,27 @@ const cwd = process.cwd()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the current platform supports TensorFlow training.
|
* Check if the current platform supports TensorFlow training.
|
||||||
* TensorFlow doesn't have wheels for all platforms (e.g., ARM-based NAS devices).
|
* TensorFlow has wheels for:
|
||||||
|
* - macOS x86_64 and arm64 (Apple Silicon with tensorflow-macos)
|
||||||
|
* - Linux x86_64 and aarch64
|
||||||
|
* - Windows x86_64
|
||||||
*/
|
*/
|
||||||
export function isPlatformSupported(): { supported: boolean; reason?: string } {
|
export function isPlatformSupported(): { supported: boolean; reason?: string } {
|
||||||
const platform = process.platform
|
const platform = process.platform
|
||||||
const arch = process.arch
|
const arch = process.arch
|
||||||
|
|
||||||
// TensorFlow supports:
|
|
||||||
// - macOS on x86_64 and arm64 (Apple Silicon with tensorflow-macos)
|
|
||||||
// - Linux on x86_64 (and some arm64 builds)
|
|
||||||
// - Windows on x86_64
|
|
||||||
|
|
||||||
if (platform === 'darwin') {
|
if (platform === 'darwin') {
|
||||||
// macOS - both Intel and Apple Silicon are supported
|
// macOS - both Intel and Apple Silicon are supported
|
||||||
return { supported: true }
|
return { supported: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (platform === 'linux') {
|
if (platform === 'linux') {
|
||||||
if (arch === 'x64') {
|
if (arch === 'x64' || arch === 'arm64') {
|
||||||
return { supported: true }
|
return { supported: true }
|
||||||
}
|
}
|
||||||
// ARM Linux (like Synology NAS) typically doesn't have TensorFlow wheels
|
|
||||||
return {
|
return {
|
||||||
supported: false,
|
supported: false,
|
||||||
reason: `TensorFlow is not available for Linux ${arch}. Training should be done on a machine with x86_64 or Apple Silicon.`,
|
reason: `TensorFlow is not available for Linux ${arch}. Training requires x86_64 or ARM64.`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,7 +47,7 @@ export function isPlatformSupported(): { supported: boolean; reason?: string } {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
supported: false,
|
supported: false,
|
||||||
reason: `TensorFlow is not available for ${platform} ${arch}. Training should be done on macOS, Linux x86_64, or Windows x86_64.`,
|
reason: `TensorFlow is not available for ${platform} ${arch}. Training should be done on macOS, Linux (x86_64/ARM64), or Windows x86_64.`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,8 +58,12 @@ export const TRAINING_SCRIPTS_DIR = path.join(cwd, 'scripts/train-column-classif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Path to the venv directory
|
* Path to the venv directory
|
||||||
|
* We use data/vision-training/.venv because:
|
||||||
|
* 1. The data/ directory is mounted as a volume in Docker (persists across restarts)
|
||||||
|
* 2. It's writable by the container
|
||||||
|
* 3. Scripts directory may not exist in production Docker images
|
||||||
*/
|
*/
|
||||||
const VENV_DIR = path.join(TRAINING_SCRIPTS_DIR, '.venv')
|
const VENV_DIR = path.join(cwd, 'data/vision-training/.venv')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Path to the Python executable in the venv
|
* Path to the Python executable in the venv
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue