Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify dependencies & split CPU/GPU backend Dockerfiles #3

Merged
merged 36 commits into from
Feb 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
378d1ed
uv for Docker & local (cpu for now)
LouisAsanaka Feb 10, 2025
1159168
Fixed model download instructions
LouisAsanaka Feb 10, 2025
dc2e622
Restore OmniParser
LouisAsanaka Feb 10, 2025
85b3e83
Added frontend
Feb 13, 2025
cda1c0f
Added support for GPU builds (not fully tested)
LouisAsanaka Feb 14, 2025
d6918b1
Don't push test input/outputs
LouisAsanaka Feb 15, 2025
851c5c1
Merge branch 'main' into build-instructions
LouisAsanaka Feb 15, 2025
0c1b18f
Moved Dockerfile for server
LouisAsanaka Feb 15, 2025
e9e83b7
Build CPU version of server Docker image
LouisAsanaka Feb 15, 2025
6503ee2
Set proper workdir for Docker build
LouisAsanaka Feb 15, 2025
d59883d
Remove Docker build context from GitHub workflow
LouisAsanaka Feb 15, 2025
9b17191
Debug CI failure
LouisAsanaka Feb 15, 2025
8bd6894
Download model files before building Docker image
LouisAsanaka Feb 15, 2025
66b0792
Share model download script
LouisAsanaka Feb 15, 2025
d093d9c
Actually use download script in workflow...
LouisAsanaka Feb 15, 2025
faff6e4
Factor out server Docker build job
LouisAsanaka Feb 15, 2025
8d5f5f9
Add logging for download_models.py
LouisAsanaka Feb 15, 2025
ba2ea3d
Sanity check for downloaded model files
LouisAsanaka Feb 15, 2025
c18955a
Remove redundant weights
LouisAsanaka Feb 16, 2025
318e4fb
Removed unused Omniparser & added Docker compose development instruct…
LouisAsanaka Feb 16, 2025
0f3fe60
Removed default paths from configs & clarified README instructions
LouisAsanaka Feb 16, 2025
e54e1b8
Merge branch 'frontend' into build-instructions
LouisAsanaka Feb 16, 2025
7ddd781
Moved frontend to root project directory
LouisAsanaka Feb 16, 2025
e0268a1
added middleware
meg-ghana Feb 15, 2025
1def6c0
Formatting
LouisAsanaka Feb 16, 2025
c405b8a
Dockerfile for frontend & working Docker compose
LouisAsanaka Feb 16, 2025
f0c478a
Updated setup documentation
LouisAsanaka Feb 16, 2025
3622368
Added CI job for building frontend
LouisAsanaka Feb 16, 2025
d904e14
Updated README with fixes for local environment
LouisAsanaka Feb 19, 2025
7be5246
Add flask
LouisAsanaka Feb 19, 2025
5e4bdad
Add OmniParser back
LouisAsanaka Feb 19, 2025
e37b242
Restore OmniParser task
LouisAsanaka Feb 19, 2025
b333555
Restored OmniParser in config
LouisAsanaka Feb 19, 2025
510ced7
Restored OmniParser in config (again)
LouisAsanaka Feb 19, 2025
6c5d220
More clarifications for uv commands
LouisAsanaka Feb 19, 2025
a726433
Simplify Docker image naming
LouisAsanaka Feb 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .dockerignore

This file was deleted.

1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.sh text eol=lf
138 changes: 117 additions & 21 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ on:
- main
- staging
- expt

pull_request:

branches:
- main
- staging
# Trigger the workflow on release activity
release:
# Only use the types keyword to narrow down the activity types that will trigger your workflow.
Expand All @@ -21,21 +22,22 @@ env:
DOCKERHUB_ORG: classtranscribe

jobs:
docker:
build-server:
name: Build server Docker image
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
name:
- latextranscribe
include:
- name: latextranscribe
FOLDER: .
IMAGE: latextranscribe

env:
FOLDER: ./server
IMAGE: latextranscribe
DOCKERFILE: Dockerfile.cpu
steps:
- uses: actions/checkout@v2

- uses: actions/checkout@v4
- name: Install the latest version of uv
uses: astral-sh/setup-uv@v5
- name: Download model weights using huggingface_hub
run: |
cd server
HF_HUB_ENABLE_HF_TRANSFER=1 uv run download_models.py
du -hs models/
# calculate some variables that are used later
- name: github branch
run: |
Expand All @@ -45,7 +47,7 @@ jobs:
BRANCH=${GITHUB_REF##*/}
fi
echo "GITHUB_BRANCH=${BRANCH}" >> $GITHUB_ENV

# Commit was for main/release branch, build a new version
if [ "$BRANCH" == "master" -o "$BRANCH" == "main" ]; then
version="$(cat gui/package.json | jq -r .version)"
Expand All @@ -65,7 +67,7 @@ jobs:

# build the docker image, this will always run to make sure
# the Dockerfile still works.
- name: Build image
- name: Build Docker image
uses: elgohr/Publish-Docker-Github-Action@2.22
env:
BRANCH: ${{ env.GITHUB_BRANCH }}
Expand All @@ -74,11 +76,12 @@ jobs:
GITSHA1: ${{ github.sha }}
with:
registry: docker.pkg.github.com
name: ${{ github.repository_owner }}/${{ github.event.repository.name }}/${{ matrix.IMAGE }}
name: ${{ github.repository_owner }}/${{ github.event.repository.name }}/${{ env.IMAGE }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
context: ${{ matrix.FOLDER }}
workdir: ${{ env.FOLDER }}
tags: "${{ env.TAGS }}"
dockerfile: ${{ env.DOCKERFILE }}
buildargs: BRANCH,VERSION,BUILDNUMBER,GITSHA1
no_push: true

Expand Down Expand Up @@ -111,9 +114,102 @@ jobs:
BUILDNUMBER: ${{ github.run_number }}
GITSHA1: ${{ github.sha }}
with:
name: ${{ env.DOCKERHUB_ORG }}/${{ matrix.IMAGE }}
name: ${{ env.DOCKERHUB_ORG }}/${{ env.IMAGE }}
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
context: ${{ matrix.FOLDER }}
workdir: ${{ env.FOLDER }}
tags: "${{ env.TAGS }}"
dockerfile: ${{ env.DOCKERFILE }}
buildargs: BRANCH,VERSION,BUILDNUMBER,GITSHA1
build-frontend:
name: Build frontend Docker image
runs-on: ubuntu-latest
env:
FOLDER: ./frontend
IMAGE: latextranscribe-frontend
DOCKERFILE: Dockerfile
steps:
- uses: actions/checkout@v4
# calculate some variables that are used later
- name: github branch
run: |
if [ "${{ github.event.release.target_commitish }}" != "" ]; then
BRANCH="${{ github.event.release.target_commitish }}"
else
BRANCH=${GITHUB_REF##*/}
fi
echo "GITHUB_BRANCH=${BRANCH}" >> $GITHUB_ENV

# Commit was for main/release branch, build a new version
if [ "$BRANCH" == "master" -o "$BRANCH" == "main" ]; then
version="$(cat gui/package.json | jq -r .version)"
echo "VERSION=$(version)" >> $GITHUB_ENV
tags="latest"
oldversion=""
while [ "${oldversion}" != "${version}" ]; do
oldversion="${version}"
tags="${tags},${version}"
version=${version%.*}
done
echo "TAGS=${tags}" >> $GITHUB_ENV
else
echo "VERSION=$BRANCH" >> $GITHUB_ENV
echo "TAGS=$BRANCH" >> $GITHUB_ENV
fi

# build the docker image, this will always run to make sure
# the Dockerfile still works.
- name: Build Docker image
uses: elgohr/Publish-Docker-Github-Action@2.22
env:
BRANCH: ${{ env.GITHUB_BRANCH }}
VERSION: ${{ env.VERSION }}
BUILDNUMBER: ${{ github.run_number }}
GITSHA1: ${{ github.sha }}
with:
registry: docker.pkg.github.com
name: ${{ github.repository_owner }}/${{ github.event.repository.name }}/${{ env.IMAGE }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
workdir: ${{ env.FOLDER }}
tags: "${{ env.TAGS }}"
dockerfile: ${{ env.DOCKERFILE }}
buildargs: BRANCH,VERSION,BUILDNUMBER,GITSHA1
no_push: true

# TODO: need publish permissions for ghcr.io
# this will publish to github container registry
#- name: Publish to GitHub
# if: github.event_name != 'pull_request' && github.repository == env.MAIN_REPO
# uses: elgohr/Publish-Docker-Github-Action@2.22
# env:
# BRANCH: ${{ env.GITHUB_BRANCH }}
# VERSION: ${{ env.VERSION }}
# BUILDNUMBER: ${{ github.run_number }}
# GITSHA1: ${{ github.sha }}
# with:
# registry: ghcr.io
# name: ${{ github.repository_owner }}/${{ matrix.IMAGE }}
# username: ${{ secrets.GHCR_USERNAME }}
# password: ${{ secrets.GHCR_PASSWORD }}
# context: ${{ matrix.FOLDER }}
# tags: "${{ env.TAGS }}"
# buildargs: BRANCH,VERSION,BUILDNUMBER,GITSHA1

# this will publish to dockerhub
- name: Publish to Docker Hub
if: github.event_name != 'pull_request' && github.repository == env.MAIN_REPO
uses: elgohr/Publish-Docker-Github-Action@2.22
env:
BRANCH: ${{ env.GITHUB_BRANCH }}
VERSION: ${{ env.VERSION }}
BUILDNUMBER: ${{ github.run_number }}
GITSHA1: ${{ github.sha }}
with:
name: ${{ env.DOCKERHUB_ORG }}/${{ env.IMAGE }}
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
workdir: ${{ env.FOLDER }}
tags: "${{ env.TAGS }}"
dockerfile: ${{ env.DOCKERFILE }}
buildargs: BRANCH,VERSION,BUILDNUMBER,GITSHA1
11 changes: 7 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# Custom
server/models/Layout/*
server/models/MFD/*
server/models/MFR/*
server/models/TabRec/*
server/models/Layout/
server/models/MFD/
server/models/MFR/
server/models/TabRec/

server/inputs/
server/outputs/

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
46 changes: 0 additions & 46 deletions Dockerfile

This file was deleted.

128 changes: 95 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,101 @@
# Latex Transcribe

## Running the official DockerHub image

(This is sketch and these instructions are untested - assume there are typos, errors, guesses (e.g. Port number), and ommissions that need to be fixed)

docker pull classtranscribe/latextranscribe:latest

docker run -i -p 8080:8080 -t latextranscribe

## Building Locally

### Local build with Docker
## Quick Start
### Backend
- To develop locally, [download the ML models](#downloading-the-ml-models-for-pipeline), then [setup the backend/frontend environment without Docker](#local-build-without-docker).
- To build a full Docker image, [download the ML models](#downloading-the-ml-models-for-pipeline), then [build the backend (CPU / GPU) and frontend images](#building-docker-image-locally).

## Running the official DockerHub image
- Only up-to-date with the main branch.
```sh
docker build -t latextranscribe .

docker run -p 127.0.0.1:8000:8000 latextranscribe
docker pull classtranscribe/latextranscribe:latest
docker run -i -p 8080:80 -t latextranscribe
```

Then open http://127.0.0.1:8000 in your favorite browser

### Local build without docker

(This is sketch and these instructions are untested - assume there are typos, errors, guesses, and ommissions that need to be fixed)


Assuming you have python3.11 installed. Note these instructions essentialy mirror the steps in Dockerfile.

````sh
python3.11 -m venv venv
source ./venv/bin/activate

pip install --upgrade pip
pip install -r requirements.txt
Hmm todo

````

## Downloading the ML models for Pipeline
- Recommended: Install the [uv](https://docs.astral.sh/uv/getting-started/installation/#installation-methods) package manager.
- First, download the ML models (warning: large download).
- With `uv` (no dependencies required thanks to [inline script dependencies](https://docs.astral.sh/uv/guides/scripts/#declaring-script-dependencies)):
```sh
cd server && uv run download_models.py
```
- Or with `pip`:
```sh
pip install huggingface-hub
cd server && python download_models.py
```
## Building Docker Image Locally
### Backend
- Build and run the backend Docker image:
- CPU:
```sh
docker build -t latextranscribe -f server/Dockerfile.cpu ./server/
docker run --name latextranscribe --rm -i -p 8081:80 -t latextranscribe
```
- GPU (CUDA >= 12.4):
```sh
docker build -t latextranscribe -f server/Dockerfile.gpu ./server/
docker run --name latextranscribe --rm --gpus '"device=0"' -i -p 8081:80 -t latextranscribe
```
- Go to `http://localhost:8081` and you should now see `The server is running!`
### Frontend
- Build and run the frontend Docker image:
```sh
docker build -t latextranscribe-frontend -f frontend/Dockerfile ./frontend/
docker run --name latextranscribe-frontend --rm -i -p 8080:80 -t latextranscribe-frontend
```
- Go to `http://localhost:8080` and you should now see the frontend.

## Developing Locally
- There are two options to develop locally.
### Docker Compose Watch
- Run in the project root:
```sh
docker compose up --build --watch
```
- Go to `http://localhost:8080` and you should now see the frontend.
### Local build without Docker
#### Backend
- Switch into the `server` directory:
```sh
cd server/
```
- Create a virtual environment and install the dependencies:
- CPU:
```sh
uv venv --seed # creates the virtual environment
uv sync --extra cpu --no-install-package detectron2 --no-install-package struct-eqtable # installs dependencies other than the two source packages
uv sync --extra cpu # installs the two source packages
```
- GPU (CUDA >= 12.4):
```sh
uv venv --seed # creates the virtual environment
uv sync --extra cu124 --no-install-package detectron2 --no-install-package struct-eqtable # installs dependencies other than the two source packages
uv sync --extra cu124 # installs the two source packages
```
- Run the server (`uv run` runs `python` in the virtual environment):
```sh
uv run uvicorn app:app --host 0.0.0.0 --port 8081
```
- TESTING – Or run the ML pipeline:
```sh
uv run main.py
```
#### Frontend
- Switch into the `frontend` directory:
```sh
cd frontend/
```
- Install the dependencies:
```sh
npm install
```
- Run the development server:
```sh
npm run dev
```
- Go to `http://localhost:5173` and you should now see the frontend.

## Others
- To add a project dependency: [`uv add`](https://docs.astral.sh/uv/reference/cli/#uv-add)
- To sync the project dependencies again: `uv sync --extra cpu` or `uv sync --extra cu124`
Loading