naicoi commited on
Commit
8532e19
Β·
1 Parent(s): cae75e9

feature/uv-migration (#6)

Browse files

- Migrate to uv for local dev, use pip for HuggingFace Spaces (5f4271a0df17dc82ec5f88b955a285d5855207a6)

.gitignore CHANGED
@@ -3,4 +3,18 @@ checkpoints/**/*.pt
3
  checkpoints/**/*.pkl
4
  checkpoints/**/*.zip
5
  checkpoints/**/*.safetensors
6
- checkpoints/**/*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  checkpoints/**/*.pkl
4
  checkpoints/**/*.zip
5
  checkpoints/**/*.safetensors
6
+ checkpoints/**/*
7
+
8
+ # Ignore local dependencies (installed via pip/uv)
9
+ latentsync/
10
+ tigersound/
11
+ FastAudioSR/
12
+ descript-audiotools/
13
+
14
+ # Python cache and virtual environment
15
+ __pycache__/
16
+ *.pyc
17
+ .pytest_cache/
18
+ .coverage
19
+ .venv/
20
+ uv.lock
AGENTS.md CHANGED
@@ -4,18 +4,35 @@ This file provides guidance for agentic coding assistants working in this reposi
4
 
5
  ## Build/Install Commands
6
 
 
7
  ```bash
8
- # Install dependencies (includes LatentSync v1.6)
9
  pip install -r requirements.txt
 
 
 
 
 
 
 
10
 
11
- # Download checkpoints from HuggingFace
12
- ./download_checkpoints.sh
 
13
 
14
- # Run the application
 
 
 
 
 
 
 
 
15
  python app.py
16
  ```
17
 
18
- **Note**: This project currently has NO linting, formatting, or test infrastructure configured. When making changes, ensure the application runs successfully with `python app.py`.
19
 
20
  ---
21
 
@@ -204,3 +221,6 @@ The application uses modular helper functions for better maintainability:
204
  - **Large Models**: Models are loaded at startup; avoid unnecessary reloading
205
  - **Session Management**: Each user session creates a unique output directory that should be cleaned up
206
  - **Clean Code**: Each function should have a single responsibility - prefer creating new helper functions over adding complexity to existing ones
 
 
 
 
4
 
5
  ## Build/Install Commands
6
 
7
+ ### HuggingFace Spaces (Deployment)
8
  ```bash
9
+ # HuggingFace automatically runs:
10
  pip install -r requirements.txt
11
+ python app.py
12
+ ```
13
+
14
+ ### Local Development (with uv)
15
+ ```bash
16
+ # Setup (one-time)
17
+ ./setup_local.sh
18
 
19
+ # Or manually:
20
+ uv venv
21
+ uv pip install -r requirements.txt
22
 
23
+ # Run app
24
+ uv run python app.py
25
+ ```
26
+
27
+ ### Local Development (with pip - standard)
28
+ ```bash
29
+ python3 -m venv .venv
30
+ source .venv/bin/activate
31
+ pip install -r requirements.txt
32
  python app.py
33
  ```
34
 
35
+ **Note**: Use uv for faster dependency installation (10-100x faster than pip). This project currently has NO linting, formatting, or test infrastructure configured. When making changes, ensure the application runs successfully with `uv run python app.py` (or `python app.py` after activating venv).
36
 
37
  ---
38
 
 
221
  - **Large Models**: Models are loaded at startup; avoid unnecessary reloading
222
  - **Session Management**: Each user session creates a unique output directory that should be cleaned up
223
  - **Clean Code**: Each function should have a single responsibility - prefer creating new helper functions over adding complexity to existing ones
224
+ - **Flash-attn-3**: Only available for Linux x86_64. Comment out in requirements.txt for local testing on macOS
225
+ - **Dependencies Managed via uv (local) / pip (HuggingFace)**: All packages are installed in `.venv/` (gitignored)
226
+ - **Local Dependencies Ignored**: latentsync/, tigersound/, FastAudioSR/, descript-audiotools/ directories are gitignored - packages are installed from git repos via requirements.txt
README.md CHANGED
@@ -67,17 +67,79 @@ git push https://huggingface.co/spaces/YOUR_USERNAME/YOUR_SPACE_NAME main
67
 
68
  ---
69
 
70
- ## Local Installation
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
  ```bash
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  # Install dependencies
74
  pip install -r requirements.txt
75
 
76
- # Download checkpoints from LatentSync v1.6
77
- ./download_checkpoints.sh
78
-
79
- # Run app
80
  python app.py
81
  ```
82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
67
 
68
  ---
69
 
70
+ ## πŸš€ Deployment
71
+
72
+ ### HuggingFace Spaces
73
+
74
+ 1. Create a Space on HuggingFace
75
+ 2. Push this repository to your Space
76
+ 3. Done! HuggingFace will automatically:
77
+ - Create Python environment
78
+ - Install dependencies from requirements.txt
79
+ - Start the application
80
+
81
+ **Requirements:**
82
+ - Hardware: A10G GPU (recommended, 24GB VRAM)
83
+ - Python: 3.10
84
+
85
+ ## πŸ’» Local Development
86
+
87
+ ### Option 1: Using uv (Fast - Recommended)
88
 
89
  ```bash
90
+ # Install uv (macOS/Linux)
91
+ curl -LsSf https://astral.sh/uv/install.sh | sh
92
+ # Or: brew install uv
93
+
94
+ # Setup and install
95
+ ./setup_local.sh
96
+
97
+ # Run application
98
+ uv run python app.py
99
+ ```
100
+
101
+ **Why uv?** 10-100x faster than pip for dependency management!
102
+
103
+ ### Option 2: Using pip (Standard)
104
+
105
+ ```bash
106
+ # Create venv
107
+ python3 -m venv .venv
108
+ source .venv/bin/activate # Windows: .venv\Scripts\activate
109
+
110
  # Install dependencies
111
  pip install -r requirements.txt
112
 
113
+ # Run application
 
 
 
114
  python app.py
115
  ```
116
 
117
+ ## πŸ“¦ Dependencies
118
+
119
+ - **requirements.txt**: All dependencies for application
120
+ - Packages are installed in `.venv/` (ignored by git)
121
+ - Git dependencies: LatentSync, FastAudioSR, tigersound, descript-audiotools
122
+
123
+ ## ⚠️ Important Notes
124
+
125
+ ### Flash-attn-3 for Local Testing
126
+
127
+ The `flash-attn-3` package only provides wheels for Linux x86_64:
128
+ - **HuggingFace (Linux)**: βœ… Works automatically
129
+ - **Local (macOS)**: ❌ Will fail during installation
130
+
131
+ **Workaround for local testing:**
132
+ ```bash
133
+ # Comment out flash-attn-3 in requirements.txt for local testing
134
+ # Uncomment before pushing to HuggingFace
135
+ ```
136
+
137
+ ### Checkpoints
138
+
139
+ Checkpoints are automatically downloaded from `ByteDance/LatentSync-1.6` on startup.
140
+
141
+ ### Audio Language
142
+
143
+ Target audio supports **English only**.
144
+
145
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
README_LOCAL.md ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Local Development Guide
2
+
3
+ ## ⚠️ macOS ARM64 (Apple Silicon) Limitations
4
+
5
+ If you're using macOS with Apple Silicon (M1/M2/M3), several ML packages **cannot be installed** because they only have wheels for Linux x86_64 and Windows:
6
+
7
+ ### Unavailable Packages:
8
+ - **triton** - GPU compute library (Linux/Windows only)
9
+ - **onnxruntime-gpu** - GPU ONNX runtime (Linux/Windows only)
10
+ - **decord** - Video processing library (Linux/Windows only)
11
+ - **flash-attn-3** - Attention mechanism (Linux x86_64 only)
12
+
13
+ ### Impact:
14
+ ❌ **ML functionality will NOT work** on macOS local development
15
+ ❌ Cannot run lipsync pipeline locally
16
+ βœ… **Can test**: UI, basic imports, code logic
17
+
18
+ ---
19
+
20
+ ## πŸš€ Recommended Workflow
21
+
22
+ ### Option 1: Use HuggingFace Spaces (Recommended)
23
+
24
+ For full ML functionality, deploy to HuggingFace Spaces:
25
+
26
+ ```bash
27
+ # 1. Create Space on HuggingFace
28
+ # 2. Push code
29
+ git push origin main
30
+
31
+ # 3. Deploy
32
+ # HuggingFace will handle all dependencies
33
+ ```
34
+
35
+ ### Option 2: Use Linux/Windows Machine
36
+
37
+ If you need local ML testing:
38
+
39
+ 1. Use a cloud VM (AWS EC2, GCP, Azure)
40
+ 2. Use WSL2 on Windows
41
+ 3. Dual-boot Linux
42
+
43
+ ---
44
+
45
+ ## πŸ’» Local Development on macOS
46
+
47
+ ### Setup
48
+
49
+ ```bash
50
+ # Run setup script
51
+ ./setup_local.sh
52
+
53
+ # This will install:
54
+ # - gradio
55
+ # - huggingface_hub
56
+ # - Basic dependencies
57
+ ```
58
+
59
+ ### What You Can Test
60
+
61
+ - βœ… Gradio UI
62
+ - βœ… File upload/download
63
+ - βœ… Basic imports
64
+ - βœ… Code logic and structure
65
+ - ❌ ML models and inference
66
+
67
+ ### Running the App
68
+
69
+ ```bash
70
+ # Using uv (recommended)
71
+ uv run python app.py
72
+
73
+ # Or activate venv
74
+ source .venv/bin/activate
75
+ python app.py
76
+ ```
77
+
78
+ ---
79
+
80
+ ## πŸ“¦ Requirements Files
81
+
82
+ - **requirements.txt**: Full dependencies for HuggingFace Spaces (Linux GPU)
83
+ - **requirements_minimal.txt**: Basic dependencies for macOS local testing
84
+ - **requirements_local.txt**: Excludes GPU-only packages (deprecated)
85
+
86
+ ---
87
+
88
+ ## πŸ”§ Troubleshooting
89
+
90
+ ### Error: "Package not available for macOS ARM64"
91
+
92
+ This is expected for ML packages. Use HuggingFace Spaces for full functionality.
93
+
94
+ ### Error: "CUDA out of memory"
95
+
96
+ Happens on GPU environments. Try shorter videos or lower resolution.
97
+
98
+ ---
99
+
100
+ ## πŸ“š Resources
101
+
102
+ - [HuggingFace Spaces Docs](https://huggingface.co/docs/hub/spaces)
103
+ - [uv Package Manager](https://docs.astral.sh/uv/)
104
+ - [LatentSync GitHub](https://github.com/OutofAi/LatentSync-batch)
UV_SETUP.md DELETED
@@ -1,99 +0,0 @@
1
- # UV Setup Guide
2
-
3
- This project uses [uv](https://github.com/astral-sh/uv) for fast Python dependency management.
4
-
5
- ## Prerequisites
6
-
7
- Install uv:
8
- ```bash
9
- # macOS/Linux
10
- curl -LsSf https://astral.sh/uv/install.sh | sh
11
-
12
- # Or with Homebrew (already installed)
13
- brew install uv
14
- ```
15
-
16
- ## Setup Virtual Environment
17
-
18
- ```bash
19
- # Create virtual environment with Python 3.10
20
- uv venv --python 3.10
21
-
22
- # Activate environment (Linux/macOS)
23
- source .venv/bin/activate
24
-
25
- # Or use uv run (no activation needed)
26
- uv run python app.py
27
- ```
28
-
29
- ## Install Dependencies
30
-
31
- ```bash
32
- # Install all dependencies from pyproject.toml
33
- uv sync
34
-
35
- # Install with dev dependencies (if any)
36
- uv sync --all-extras
37
-
38
- # Or install from requirements.txt (backward compatibility)
39
- uv pip install -r requirements.txt
40
- ```
41
-
42
- ## Run Application
43
-
44
- ```bash
45
- # Method 1: Activate venv first
46
- source .venv/bin/activate
47
- python app.py
48
-
49
- # Method 2: Use uv run (recommended)
50
- uv run python app.py
51
- ```
52
-
53
- ## Dependency Management
54
-
55
- ### Add new dependency
56
- ```bash
57
- uv add package-name
58
-
59
- # Add with version constraint
60
- uv add "package>=1.0,<2.0"
61
-
62
- # Add from git
63
- uv add git+https://github.com/user/repo.git
64
- ```
65
-
66
- ### Update dependencies
67
- ```bash
68
- # Update lockfile
69
- uv lock --upgrade
70
-
71
- # Sync with lockfile (exact versions)
72
- uv sync --frozen
73
- ```
74
-
75
- ### Python version
76
- ```bash
77
- # Check Python version
78
- uv python list
79
-
80
- # Install Python version
81
- uv python install 3.11
82
- ```
83
-
84
- ## HuggingFace Spaces Deployment
85
-
86
- When deploying to HuggingFace Spaces, use:
87
-
88
- ```yaml
89
- # README.md metadata (already configured)
90
- sdk: gradio
91
- python_version: "3.10"
92
- ```
93
-
94
- Space will automatically:
95
- 1. Install uv (already in HuggingFace environment)
96
- 2. Create venv
97
- 3. Run `uv sync`
98
- 4. Start application with `uv run python app.py`
99
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app.py CHANGED
@@ -5,29 +5,12 @@ Main Gradio UI module
5
 
6
  import os
7
  import shutil
8
- import subprocess
9
- import sys
10
-
11
- import torchvision.transforms.functional as _F
12
-
13
- sys.modules["torchvision.transforms.functional_tensor"] = _F
14
-
15
  import gradio as gr
16
- import sys
17
-
18
  import torchvision.transforms.functional as _F
19
-
20
- sys.modules["torchvision.transforms.functional_tensor"] = _F
21
-
22
  from huggingface_hub import hf_hub_download
23
- sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
24
  from processing import lipsync_with_audio_target
25
 
26
-
27
- subprocess.check_call(
28
- "pip uninstall onnxruntime onnxruntime-gpu -y && pip install onnxruntime-gpu",
29
- shell=True,
30
- )
31
 
32
  checkpoint_dir = "checkpoints"
33
  os.makedirs(checkpoint_dir, exist_ok=True)
@@ -48,7 +31,7 @@ os.environ["PROCESSED_RESULTS"] = os.path.join(os.getcwd(), "processed_results")
48
  os.makedirs(os.environ["PROCESSED_RESULTS"], exist_ok=True)
49
 
50
  src = "checkpoints"
51
- dst = "/home/userapp/.cache/torch/hub/checkpoints"
52
 
53
  os.makedirs(dst, exist_ok=True)
54
 
 
5
 
6
  import os
7
  import shutil
 
 
 
 
 
 
 
8
  import gradio as gr
 
 
9
  import torchvision.transforms.functional as _F
 
 
 
10
  from huggingface_hub import hf_hub_download
 
11
  from processing import lipsync_with_audio_target
12
 
13
+ sys.modules["torchvision.transforms.functional_tensor"] = _F
 
 
 
 
14
 
15
  checkpoint_dir = "checkpoints"
16
  os.makedirs(checkpoint_dir, exist_ok=True)
 
31
  os.makedirs(os.environ["PROCESSED_RESULTS"], exist_ok=True)
32
 
33
  src = "checkpoints"
34
+ dst = os.path.expanduser("~/.cache/torch/hub/checkpoints")
35
 
36
  os.makedirs(dst, exist_ok=True)
37
 
audio_processing.py CHANGED
@@ -48,13 +48,14 @@ def extract_audio_to_wav(input_video: str, output_dir: str) -> tuple:
48
  ]
49
  subprocess.run(cmd, check=True)
50
 
 
51
  audio, sr = torchaudio.load(audio_file)
52
- audio = audio.to("cuda")
53
 
54
  with torch.no_grad():
55
  from tigersound.look2hear.models import TIGERDNR
56
 
57
- dnr_model = TIGERDNR.from_pretrained("JusperLee/TIGER-DnR").to("cuda").eval()
58
  dialog, effect, music = dnr_model(audio[None])
59
 
60
  torchaudio.save(vocal_file, dialog.cpu(), sr)
 
48
  ]
49
  subprocess.run(cmd, check=True)
50
 
51
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
52
  audio, sr = torchaudio.load(audio_file)
53
+ audio = audio.to(device)
54
 
55
  with torch.no_grad():
56
  from tigersound.look2hear.models import TIGERDNR
57
 
58
+ dnr_model = TIGERDNR.from_pretrained("JusperLee/TIGER-DnR").to(device).eval()
59
  dialog, effect, music = dnr_model(audio[None])
60
 
61
  torchaudio.save(vocal_file, dialog.cpu(), sr)
changes.patch ADDED
@@ -0,0 +1,771 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ diff --git a/.gitignore b/.gitignore
2
+ index 44c5b3f..156b834 100644
3
+ --- a/.gitignore
4
+ +++ b/.gitignore
5
+ @@ -3,4 +3,18 @@ checkpoints/**/*.pt
6
+ checkpoints/**/*.pkl
7
+ checkpoints/**/*.zip
8
+ checkpoints/**/*.safetensors
9
+ -checkpoints/**/*
10
+
11
+ +checkpoints/**/*
12
+ +
13
+ +# Ignore local dependencies (installed via pip/uv)
14
+ +latentsync/
15
+ +tigersound/
16
+ +FastAudioSR/
17
+ +descript-audiotools/
18
+ +
19
+ +# Python cache and virtual environment
20
+ +__pycache__/
21
+ +*.pyc
22
+ +.pytest_cache/
23
+ +.coverage
24
+ +.venv/
25
+ +uv.lock
26
+
27
+ diff --git a/AGENTS.md b/AGENTS.md
28
+ index 68e12ad..a60779d 100644
29
+ --- a/AGENTS.md
30
+ +++ b/AGENTS.md
31
+ @@ -4,18 +4,35 @@ This file provides guidance for agentic coding assistants working in this reposi
32
+
33
+ ## Build/Install Commands
34
+
35
+ +### HuggingFace Spaces (Deployment)
36
+ ```bash
37
+ -# Install dependencies (includes LatentSync v1.6)
38
+ +# HuggingFace automatically runs:
39
+ pip install -r requirements.txt
40
+ +python app.py
41
+ +```
42
+ +
43
+ +### Local Development (with uv)
44
+ +```bash
45
+ +# Setup (one-time)
46
+ +./setup_local.sh
47
+
48
+ -# Download checkpoints from HuggingFace
49
+ -./download_checkpoints.sh
50
+ +# Or manually:
51
+ +uv venv
52
+ +uv pip install -r requirements.txt
53
+
54
+ -# Run the application
55
+ +# Run app
56
+ +uv run python app.py
57
+ +```
58
+ +
59
+ +### Local Development (with pip - standard)
60
+ +```bash
61
+ +python3 -m venv .venv
62
+ +source .venv/bin/activate
63
+ +pip install -r requirements.txt
64
+ python app.py
65
+ ```
66
+
67
+ -**Note**: This project currently has NO linting, formatting, or test infrastructure configured. When making changes, ensure the application runs successfully with `python app.py`.
68
+ +**Note**: Use uv for faster dependency installation (10-100x faster than pip). This project currently has NO linting, formatting, or test infrastructure configured. When making changes, ensure the application runs successfully with `uv run python app.py` (or `python app.py` after activating venv).
69
+
70
+ ---
71
+
72
+ @@ -204,3 +221,6 @@ The application uses modular helper functions for better maintainability:
73
+ - **Large Models**: Models are loaded at startup; avoid unnecessary reloading
74
+ - **Session Management**: Each user session creates a unique output directory that should be cleaned up
75
+ - **Clean Code**: Each function should have a single responsibility - prefer creating new helper functions over adding complexity to existing ones
76
+ +- **Flash-attn-3**: Only available for Linux x86_64. Comment out in requirements.txt for local testing on macOS
77
+ +- **Dependencies Managed via uv (local) / pip (HuggingFace)**: All packages are installed in `.venv/` (gitignored)
78
+ +- **Local Dependencies Ignored**: latentsync/, tigersound/, FastAudioSR/, descript-audiotools/ directories are gitignored - packages are installed from git repos via requirements.txt
79
+ diff --git a/README.md b/README.md
80
+ index c52cd64..4af0bbb 100644
81
+ --- a/README.md
82
+ +++ b/README.md
83
+ @@ -67,17 +67,79 @@ git push https://huggingface.co/spaces/YOUR_USERNAME/YOUR_SPACE_NAME main
84
+
85
+ ---
86
+
87
+ -## Local Installation
88
+ +## πŸš€ Deployment
89
+ +
90
+ +### HuggingFace Spaces
91
+ +
92
+ +1. Create a Space on HuggingFace
93
+ +2. Push this repository to your Space
94
+ +3. Done! HuggingFace will automatically:
95
+ + - Create Python environment
96
+ + - Install dependencies from requirements.txt
97
+ + - Start the application
98
+ +
99
+ +**Requirements:**
100
+ +- Hardware: A10G GPU (recommended, 24GB VRAM)
101
+ +- Python: 3.10
102
+ +
103
+ +## πŸ’» Local Development
104
+ +
105
+ +### Option 1: Using uv (Fast - Recommended)
106
+
107
+ ```bash
108
+ +# Install uv (macOS/Linux)
109
+ +curl -LsSf https://astral.sh/uv/install.sh | sh
110
+ +# Or: brew install uv
111
+ +
112
+ +# Setup and install
113
+ +./setup_local.sh
114
+ +
115
+ +# Run application
116
+ +uv run python app.py
117
+ +```
118
+ +
119
+ +**Why uv?** 10-100x faster than pip for dependency management!
120
+ +
121
+ +### Option 2: Using pip (Standard)
122
+ +
123
+ +```bash
124
+ +# Create venv
125
+ +python3 -m venv .venv
126
+ +source .venv/bin/activate # Windows: .venv\Scripts\activate
127
+ +
128
+ # Install dependencies
129
+ pip install -r requirements.txt
130
+
131
+ -# Download checkpoints from LatentSync v1.6
132
+ -./download_checkpoints.sh
133
+ -
134
+ -# Run app
135
+ +# Run application
136
+ python app.py
137
+ ```
138
+
139
+ +## πŸ“¦ Dependencies
140
+ +
141
+ +- **requirements.txt**: All dependencies for application
142
+ +- Packages are installed in `.venv/` (ignored by git)
143
+ +- Git dependencies: LatentSync, FastAudioSR, tigersound, descript-audiotools
144
+ +
145
+ +## ⚠️ Important Notes
146
+ +
147
+ +### Flash-attn-3 for Local Testing
148
+ +
149
+ +The `flash-attn-3` package only provides wheels for Linux x86_64:
150
+ +- **HuggingFace (Linux)**: βœ… Works automatically
151
+ +- **Local (macOS)**: ❌ Will fail during installation
152
+ +
153
+ +**Workaround for local testing:**
154
+ +```bash
155
+ +# Comment out flash-attn-3 in requirements.txt for local testing
156
+ +# Uncomment before pushing to HuggingFace
157
+ +```
158
+ +
159
+ +### Checkpoints
160
+ +
161
+ +Checkpoints are automatically downloaded from `ByteDance/LatentSync-1.6` on startup.
162
+ +
163
+ +### Audio Language
164
+ +
165
+ +Target audio supports **English only**.
166
+ +
167
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
168
+ diff --git a/README_LOCAL.md b/README_LOCAL.md
169
+ new file mode 100644
170
+ index 0000000..e2b14aa
171
+ --- /dev/null
172
+ +++ b/README_LOCAL.md
173
+ @@ -0,0 +1,104 @@
174
+ +# Local Development Guide
175
+ +
176
+ +## ⚠️ macOS ARM64 (Apple Silicon) Limitations
177
+ +
178
+ +If you're using macOS with Apple Silicon (M1/M2/M3), several ML packages **cannot be installed** because they only have wheels for Linux x86_64 and Windows:
179
+ +
180
+ +### Unavailable Packages:
181
+ +- **triton** - GPU compute library (Linux/Windows only)
182
+ +- **onnxruntime-gpu** - GPU ONNX runtime (Linux/Windows only)
183
+ +- **decord** - Video processing library (Linux/Windows only)
184
+ +- **flash-attn-3** - Attention mechanism (Linux x86_64 only)
185
+ +
186
+ +### Impact:
187
+ +❌ **ML functionality will NOT work** on macOS local development
188
+ +❌ Cannot run lipsync pipeline locally
189
+ +βœ… **Can test**: UI, basic imports, code logic
190
+ +
191
+ +---
192
+ +
193
+ +## πŸš€ Recommended Workflow
194
+ +
195
+ +### Option 1: Use HuggingFace Spaces (Recommended)
196
+ +
197
+ +For full ML functionality, deploy to HuggingFace Spaces:
198
+ +
199
+ +```bash
200
+ +# 1. Create Space on HuggingFace
201
+ +# 2. Push code
202
+ +git push origin main
203
+ +
204
+ +# 3. Deploy
205
+ +# HuggingFace will handle all dependencies
206
+ +```
207
+ +
208
+ +### Option 2: Use Linux/Windows Machine
209
+ +
210
+ +If you need local ML testing:
211
+ +
212
+ +1. Use a cloud VM (AWS EC2, GCP, Azure)
213
+ +2. Use WSL2 on Windows
214
+ +3. Dual-boot Linux
215
+ +
216
+ +---
217
+ +
218
+ +## πŸ’» Local Development on macOS
219
+ +
220
+ +### Setup
221
+ +
222
+ +```bash
223
+ +# Run setup script
224
+ +./setup_local.sh
225
+ +
226
+ +# This will install:
227
+ +# - gradio
228
+ +# - huggingface_hub
229
+ +# - Basic dependencies
230
+ +```
231
+ +
232
+ +### What You Can Test
233
+ +
234
+ +- βœ… Gradio UI
235
+ +- βœ… File upload/download
236
+ +- βœ… Basic imports
237
+ +- βœ… Code logic and structure
238
+ +- ❌ ML models and inference
239
+ +
240
+ +### Running the App
241
+ +
242
+ +```bash
243
+ +# Using uv (recommended)
244
+ +uv run python app.py
245
+ +
246
+ +# Or activate venv
247
+ +source .venv/bin/activate
248
+ +python app.py
249
+ +```
250
+ +
251
+ +---
252
+ +
253
+ +## πŸ“¦ Requirements Files
254
+ +
255
+ +- **requirements.txt**: Full dependencies for HuggingFace Spaces (Linux GPU)
256
+ +- **requirements_minimal.txt**: Basic dependencies for macOS local testing
257
+ +- **requirements_local.txt**: Excludes GPU-only packages (deprecated)
258
+ +
259
+ +---
260
+ +
261
+ +## πŸ”§ Troubleshooting
262
+ +
263
+ +### Error: "Package not available for macOS ARM64"
264
+ +
265
+ +This is expected for ML packages. Use HuggingFace Spaces for full functionality.
266
+ +
267
+ +### Error: "CUDA out of memory"
268
+ +
269
+ +Happens on GPU environments. Try shorter videos or lower resolution.
270
+ +
271
+ +---
272
+ +
273
+ +## πŸ“š Resources
274
+ +
275
+ +- [HuggingFace Spaces Docs](https://huggingface.co/docs/hub/spaces)
276
+ +- [uv Package Manager](https://docs.astral.sh/uv/)
277
+ +- [LatentSync GitHub](https://github.com/OutofAi/LatentSync-batch)
278
+ diff --git a/UV_SETUP.md b/UV_SETUP.md
279
+ deleted file mode 100644
280
+ index d8d46b4..0000000
281
+ --- a/UV_SETUP.md
282
+ +++ /dev/null
283
+ @@ -1,99 +0,0 @@
284
+ -# UV Setup Guide
285
+ -
286
+ -This project uses [uv](https://github.com/astral-sh/uv) for fast Python dependency management.
287
+ -
288
+ -## Prerequisites
289
+ -
290
+ -Install uv:
291
+ -```bash
292
+ -# macOS/Linux
293
+ -curl -LsSf https://astral.sh/uv/install.sh | sh
294
+ -
295
+ -# Or with Homebrew (already installed)
296
+ -brew install uv
297
+ -```
298
+ -
299
+ -## Setup Virtual Environment
300
+ -
301
+ -```bash
302
+ -# Create virtual environment with Python 3.10
303
+ -uv venv --python 3.10
304
+ -
305
+ -# Activate environment (Linux/macOS)
306
+ -source .venv/bin/activate
307
+ -
308
+ -# Or use uv run (no activation needed)
309
+ -uv run python app.py
310
+ -```
311
+ -
312
+ -## Install Dependencies
313
+ -
314
+ -```bash
315
+ -# Install all dependencies from pyproject.toml
316
+ -uv sync
317
+ -
318
+ -# Install with dev dependencies (if any)
319
+ -uv sync --all-extras
320
+ -
321
+ -# Or install from requirements.txt (backward compatibility)
322
+ -uv pip install -r requirements.txt
323
+ -```
324
+ -
325
+ -## Run Application
326
+ -
327
+ -```bash
328
+ -# Method 1: Activate venv first
329
+ -source .venv/bin/activate
330
+ -python app.py
331
+ -
332
+ -# Method 2: Use uv run (recommended)
333
+ -uv run python app.py
334
+ -```
335
+ -
336
+ -## Dependency Management
337
+ -
338
+ -### Add new dependency
339
+ -```bash
340
+ -uv add package-name
341
+ -
342
+ -# Add with version constraint
343
+ -uv add "package>=1.0,<2.0"
344
+ -
345
+ -# Add from git
346
+ -uv add git+https://github.com/user/repo.git
347
+ -```
348
+ -
349
+ -### Update dependencies
350
+ -```bash
351
+ -# Update lockfile
352
+ -uv lock --upgrade
353
+ -
354
+ -# Sync with lockfile (exact versions)
355
+ -uv sync --frozen
356
+ -```
357
+ -
358
+ -### Python version
359
+ -```bash
360
+ -# Check Python version
361
+ -uv python list
362
+ -
363
+ -# Install Python version
364
+ -uv python install 3.11
365
+ -```
366
+ -
367
+ -## HuggingFace Spaces Deployment
368
+ -
369
+ -When deploying to HuggingFace Spaces, use:
370
+ -
371
+ -```yaml
372
+ -# README.md metadata (already configured)
373
+ -sdk: gradio
374
+ -python_version: "3.10"
375
+ -```
376
+ -
377
+ -Space will automatically:
378
+ -1. Install uv (already in HuggingFace environment)
379
+ -2. Create venv
380
+ -3. Run `uv sync`
381
+ -4. Start application with `uv run python app.py`
382
+ -```
383
+ diff --git a/app.py b/app.py
384
+ index c9dd4f2..d8948ee 100644
385
+ --- a/app.py
386
+ +++ b/app.py
387
+ @@ -5,29 +5,12 @@ Main Gradio UI module
388
+
389
+ import os
390
+ import shutil
391
+ -import subprocess
392
+ -import sys
393
+ -
394
+ -import torchvision.transforms.functional as _F
395
+ -
396
+ -sys.modules["torchvision.transforms.functional_tensor"] = _F
397
+ -
398
+ import gradio as gr
399
+ -import sys
400
+ -
401
+ import torchvision.transforms.functional as _F
402
+ -
403
+ -sys.modules["torchvision.transforms.functional_tensor"] = _F
404
+ -
405
+ from huggingface_hub import hf_hub_download
406
+ -sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
407
+ from processing import lipsync_with_audio_target
408
+
409
+ -
410
+ -subprocess.check_call(
411
+ - "pip uninstall onnxruntime onnxruntime-gpu -y && pip install onnxruntime-gpu",
412
+ - shell=True,
413
+ -)
414
+ +sys.modules["torchvision.transforms.functional_tensor"] = _F
415
+
416
+ checkpoint_dir = "checkpoints"
417
+ os.makedirs(checkpoint_dir, exist_ok=True)
418
+ @@ -48,7 +31,7 @@ os.environ["PROCESSED_RESULTS"] = os.path.join(os.getcwd(), "processed_results")
419
+ os.makedirs(os.environ["PROCESSED_RESULTS"], exist_ok=True)
420
+
421
+ src = "checkpoints"
422
+ -dst = "/home/userapp/.cache/torch/hub/checkpoints"
423
+ +dst = os.path.expanduser("~/.cache/torch/hub/checkpoints")
424
+
425
+ os.makedirs(dst, exist_ok=True)
426
+
427
+ diff --git a/audio_processing.py b/audio_processing.py
428
+ index 83b6706..61ec7d9 100644
429
+ --- a/audio_processing.py
430
+ +++ b/audio_processing.py
431
+ @@ -48,13 +48,14 @@ def extract_audio_to_wav(input_video: str, output_dir: str) -> tuple:
432
+ ]
433
+ subprocess.run(cmd, check=True)
434
+
435
+ + device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
436
+ audio, sr = torchaudio.load(audio_file)
437
+ - audio = audio.to("cuda")
438
+ + audio = audio.to(device)
439
+
440
+ with torch.no_grad():
441
+ from tigersound.look2hear.models import TIGERDNR
442
+
443
+ - dnr_model = TIGERDNR.from_pretrained("JusperLee/TIGER-DnR").to("cuda").eval()
444
+ + dnr_model = TIGERDNR.from_pretrained("JusperLee/TIGER-DnR").to(device).eval()
445
+ dialog, effect, music = dnr_model(audio[None])
446
+
447
+ torchaudio.save(vocal_file, dialog.cpu(), sr)
448
+ diff --git a/config.py b/config.py
449
+ index da48f4e..d804c47 100644
450
+ --- a/config.py
451
+ +++ b/config.py
452
+ @@ -8,4 +8,4 @@ MIN_DURATION = 5
453
+ MAX_DURATION = 60
454
+
455
+ # Processing directory
456
+ -PROCESSED_RESULTS_DIR = "proprocess_results"
457
+ +PROCESSED_RESULTS_DIR = "processed_results"
458
+ diff --git a/lipsync_processing.py b/lipsync_processing.py
459
+ index 5e51806..3411fe9 100644
460
+ --- a/lipsync_processing.py
461
+ +++ b/lipsync_processing.py
462
+ @@ -2,6 +2,7 @@
463
+
464
+ import os
465
+ import traceback
466
+ +from lipsync import apply_lipsync
467
+
468
+
469
+ def apply_lipsync_to_video(
470
+ @@ -19,9 +20,7 @@ def apply_lipsync_to_video(
471
+ """
472
+ try:
473
+ lipsynced_video = os.path.join(output_dir, "output_with_lipsync.mp4")
474
+ - apply_lipsync(
475
+ - video_path, audio_16k_path, lipsynced_video, method=lipsync_method
476
+ - )
477
+ + apply_lipsync(video_path, audio_16k_path, lipsynced_video)
478
+ return lipsynced_video
479
+ except RuntimeError as e:
480
+ if "out of memory" in str(e).lower():
481
+ diff --git a/processing.py b/processing.py
482
+ index d7ee836..61c1a73 100644
483
+ --- a/processing.py
484
+ +++ b/processing.py
485
+ @@ -136,7 +136,7 @@ def process_lipsync_with_audio_target(
486
+
487
+ with timer("Applying lipsync"):
488
+ lipsynced_video = apply_lipsync_to_video(
489
+ - video_looped, audio_16k, output_dir, lipsync_method
490
+ + video_looped, audio_16k, output_dir
491
+ )
492
+
493
+ with timer("Upscaling video to original resolution"):
494
+ diff --git a/pyproject.toml b/pyproject.toml
495
+ deleted file mode 100644
496
+ index 6d43dcb..0000000
497
+ --- a/pyproject.toml
498
+ +++ /dev/null
499
+ @@ -1,62 +0,0 @@
500
+ -[project]
501
+ -name = "outoflipsync"
502
+ -version = "0.1.0"
503
+ -description = "LipSync application using LatentSync v1.6 with video and audio input"
504
+ -readme = "README.md"
505
+ -requires-python = ">=3.9"
506
+ -dependencies = [
507
+ - "torchaudio==2.8.0",
508
+ - "torchvision==0.23.0",
509
+ - "triton",
510
+ - "deepspeed==0.17.1",
511
+ - "flash-attn-3 @ https://huggingface.co/alexnasa/flash-attn-3/resolve/main/128/flash_attn_3-3.0.0b1-cp39-abi3-linux_x86_64.whl",
512
+ - "latentsync @ git+https://github.com/OutofAi/LatentSync-batch.git",
513
+ - "FastAudioSR @ git+https://github.com/ysharma3501/FlashSR.git",
514
+ - "DeepCache",
515
+ - "pydub==0.25.1",
516
+ - "ffmpeg-python==0.2.0",
517
+ - "python_speech_features==0.6",
518
+ - "librosa==0.10.2.post1",
519
+ - "accelerate==1.8.1",
520
+ - "transformers==4.52.3",
521
+ - "tokenizers==0.21.0",
522
+ - "sentencepiece",
523
+ - "g2p-en==2.1.0",
524
+ - "omegaconf==2.3.0",
525
+ - "munch==4.0.0",
526
+ - "tqdm",
527
+ - "diffusers==0.33.1",
528
+ - "huggingface-hub<1.0",
529
+ - "imageio==2.27.0",
530
+ - "decord==0.6.0",
531
+ - "opencv-python==4.9.0.80",
532
+ - "mediapipe==0.10.11",
533
+ - "av",
534
+ - "torch-fidelity==0.3.0",
535
+ - "torchmetrics==1.3.1",
536
+ - "lpips==0.1.4",
537
+ - "face-alignment==1.4.1",
538
+ - "insightface==0.7.3",
539
+ - "kornia==0.8.0",
540
+ - "numpy==1.26.2",
541
+ - "matplotlib==3.8.2",
542
+ - "numba==0.58.1",
543
+ - "Cython==3.0.7",
544
+ - "einops==0.7.0",
545
+ - "ninja==1.11.1.1",
546
+ - "descript-audiotools @ git+https://github.com/descriptinc/audiotools.git",
547
+ - "tigersound @ git+https://github.com/OutofAi/tigersound.git",
548
+ - "hf-xet==1.1.8",
549
+ - "modelscope==1.27.0",
550
+ - "onnxruntime-gpu==1.21.0",
551
+ - "realesrgan>=0.3.0",
552
+ - "basicsr>=1.4.2",
553
+ - "gradio==6.4.0",
554
+ -]
555
+ -
556
+ -[build-system]
557
+ -requires = ["setuptools>=64", "wheel"]
558
+ -build-backend = "setuptools.build_meta"
559
+ -
560
+ -[tool.uv]
561
+ -dev-dependencies = []
562
+ diff --git a/requirements.txt b/requirements.txt
563
+ index 7dc40a0..a3a9e67 100644
564
+ --- a/requirements.txt
565
+ +++ b/requirements.txt
566
+ @@ -3,9 +3,9 @@ torchaudio==2.8.0
567
+ torchvision
568
+ triton
569
+ deepspeed==0.17.1
570
+ -flash-attn-3 @ https://huggingface.co/alexnasa/flash-attn-3/resolve/main/128/flash_attn_3-3.0.0b1-cp39-abi3-linux_x86_64.whl
571
+ -latentsync @ git+https://github.com/OutofAi/LatentSync-batch.git
572
+ -FastAudioSR @ git+https://github.com/ysharma3501/FlashSR.git
573
+ +https://huggingface.co/alexnasa/flash-attn-3/resolve/main/128/flash_attn_3-3.0.0b1-cp39-abi3-linux_x86_64.whl
574
+ +git+https://github.com/OutofAi/LatentSync-batch.git
575
+ +git+https://github.com/ysharma3501/FlashSR.git
576
+ DeepCache
577
+
578
+ pydub==0.25.1
579
+ @@ -45,8 +45,8 @@ einops==0.7.0
580
+ ninja==1.11.1.1
581
+
582
+ # --- Model Repos & Tools ---
583
+ -descript-audiotools @ git+https://github.com/descriptinc/audiotools.git
584
+ -tigersound @ git+https://github.com/OutofAi/tigersound.git
585
+ +git+https://github.com/descriptinc/audiotools.git
586
+ +git+https://github.com/OutofAi/tigersound.git
587
+ hf-xet==1.1.8
588
+ modelscope==1.27.0
589
+ onnxruntime-gpu==1.21.0
590
+ diff --git a/requirements_local.txt b/requirements_local.txt
591
+ new file mode 100644
592
+ index 0000000..4a78a20
593
+ --- /dev/null
594
+ +++ b/requirements_local.txt
595
+ @@ -0,0 +1,54 @@
596
+ +# --- Core Torch Stack ---
597
+ +torchaudio==2.8.0
598
+ +torchvision
599
+ +triton
600
+ +deepspeed==0.17.1
601
+ +git+https://github.com/OutofAi/LatentSync-batch.git
602
+ +git+https://github.com/ysharma3501/FlashSR.git
603
+ +DeepCache
604
+ +
605
+ +pydub==0.25.1
606
+ +ffmpeg-python==0.2.0
607
+ +python_speech_features==0.6
608
+ +librosa==0.10.2.post1
609
+ +
610
+ +accelerate==1.8.1
611
+ +transformers==4.52.3
612
+ +tokenizers==0.21.0
613
+ +sentencepiece
614
+ +g2p-en==2.1.0
615
+ +omegaconf==2.3.0
616
+ +munch==4.0.0
617
+ +tqdm
618
+ +
619
+ +diffusers==0.33.1
620
+ +huggingface-hub<1.0
621
+ +imageio==2.27.0
622
+ +opencv-python==4.9.0.80
623
+ +mediapipe==0.10.11
624
+ +av
625
+ +torch-fidelity==0.3.0
626
+ +torchmetrics==1.3.1
627
+ +lpips==0.1.4
628
+ +face-alignment==1.4.1
629
+ +insightface==0.7.3
630
+ +kornia==0.8.0
631
+ +
632
+ +# --- Numerical / Scientific ---
633
+ +numpy==1.26.2
634
+ +matplotlib==3.8.2
635
+ +numba==0.58.1
636
+ +Cython==3.0.7
637
+ +einops==0.7.0
638
+ +ninja==1.11.1.1
639
+ +
640
+ +# --- Model Repos & Tools ---
641
+ +git+https://github.com/descriptinc/audiotools.git
642
+ +git+https://github.com/OutofAi/tigersound.git
643
+ +hf-xet==1.1.8
644
+ +modelscope==1.27.0
645
+ +onnxruntime==1.21.0
646
+ +
647
+ +# --- Real-ESRGAN for Video Upscaling ---
648
+ +realesrgan>=0.3.0
649
+ +basicsr
650
+ diff --git a/requirements_minimal.txt b/requirements_minimal.txt
651
+ new file mode 100644
652
+ index 0000000..e5a2d30
653
+ --- /dev/null
654
+ +++ b/requirements_minimal.txt
655
+ @@ -0,0 +1,13 @@
656
+ +# Minimal requirements for local testing on macOS (ARM64)
657
+ +# Excludes GPU-only packages: triton, onnxruntime-gpu, decord, flash-attn-3
658
+ +
659
+ +gradio==6.4.0
660
+ +huggingface-hub<1.0
661
+ +omegaconf==2.3.0
662
+ +tqdm
663
+ +ffmpeg-python==0.2.0
664
+ +python_speech_features==0.6
665
+ +numpy
666
+ +imageio
667
+ +opencv-python
668
+ +pillow
669
+ diff --git a/setup_local.sh b/setup_local.sh
670
+ new file mode 100755
671
+ index 0000000..6a20031
672
+ --- /dev/null
673
+ +++ b/setup_local.sh
674
+ @@ -0,0 +1,41 @@
675
+ +#!/bin/bash
676
+ +set -e
677
+ +
678
+ +echo "πŸš€ Setting up OutofLipSync with uv (local development)..."
679
+ +
680
+ +# Check if uv is installed
681
+ +if ! command -v uv &> /dev/null; then
682
+ + echo "πŸ“¦ Installing uv..."
683
+ + curl -LsSf https://astral.sh/uv/install.sh | sh
684
+ + export PATH="$HOME/.cargo/bin:$PATH"
685
+ +fi
686
+ +
687
+ +echo "πŸ”§ Creating virtual environment..."
688
+ +uv venv
689
+ +
690
+ +# Detect OS
691
+ +OS="$(uname -s)"
692
+ +ARCH="$(uname -m)"
693
+ +
694
+ +if [[ "$OS" == "Darwin" && "$ARCH" == "arm64" ]]; then
695
+ + echo "⚠️ macOS ARM64 detected"
696
+ + echo "πŸ“¦ Installing minimal dependencies (GPU packages not supported on macOS ARM64)..."
697
+ + uv pip install -r requirements_minimal.txt
698
+ + echo ""
699
+ + echo "⚠️ WARNING: The following packages cannot be installed on macOS ARM64:"
700
+ + echo " - triton (GPU compute)"
701
+ + echo " - onnxruntime-gpu (GPU inference)"
702
+ + echo " - decord (video processing)"
703
+ + echo " - flash-attn-3 (attention mechanism)"
704
+ + echo ""
705
+ + echo " Full ML functionality is NOT available on macOS."
706
+ + echo " For testing, use HuggingFace Spaces (Linux GPU environment)."
707
+ +else
708
+ + echo "πŸ“₯ Installing all dependencies from requirements.txt..."
709
+ + uv pip install -r requirements.txt
710
+ +fi
711
+ +
712
+ +echo ""
713
+ +echo "βœ… Setup complete!"
714
+ +echo "πŸŽ‰ Run app with: uv run python app.py"
715
+ +echo " Or: source .venv/bin/activate && python app.py"
716
+ diff --git a/time_util.py b/time_util.py
717
+ index 3f23746..7e90c1e 100644
718
+ --- a/time_util.py
719
+ +++ b/time_util.py
720
+ @@ -1,9 +1,11 @@
721
+ import time
722
+ from contextlib import contextmanager
723
+
724
+ +
725
+ @contextmanager
726
+ def timer(name: str):
727
+ start = time.time()
728
+ print(f"{name}...")
729
+ yield
730
+ - print(f" -> {name} completed in {time.time() - start:.2f} sec")
731
+
732
+ + print(f" -> {name} completed in {time.time() - start:.2f} sec")
733
+ +
734
+ diff --git a/video_processing.py b/video_processing.py
735
+ index 0647df9..ab1d19c 100644
736
+ --- a/video_processing.py
737
+ +++ b/video_processing.py
738
+ @@ -7,6 +7,7 @@ import subprocess
739
+ import cv2
740
+ import numpy as np
741
+ import torch
742
+ +from fractions import Fraction
743
+
744
+ import torchvision.transforms.functional as F
745
+
746
+ @@ -110,7 +111,7 @@ def get_video_info(video_path: str) -> dict:
747
+
748
+ width = data["streams"][0]["width"]
749
+ height = data["streams"][0]["height"]
750
+ - fps = eval(data["streams"][0]["r_frame_rate"])
751
+ + fps = float(Fraction(data["streams"][0]["r_frame_rate"]))
752
+ duration = float(data["format"]["duration"])
753
+
754
+ return {"width": width, "height": height, "fps": fps, "duration": duration}
755
+ @@ -247,6 +248,7 @@ def upscale_video(video_path: str, width: int, height: int, output_dir: str) ->
756
+ num_grow_ch=32,
757
+ scale=4,
758
+ )
759
+ + device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
760
+ upsampler = RealESRGANer(
761
+ scale=4,
762
+ model_path=model_path,
763
+ @@ -255,7 +257,7 @@ def upscale_video(video_path: str, width: int, height: int, output_dir: str) ->
764
+ tile_pad=10,
765
+ pre_pad=0,
766
+ half=True,
767
+ - device=torch.device("cuda"),
768
+ + device=device,
769
+ )
770
+
771
+ cap = cv2.VideoCapture(video_path)
config.py CHANGED
@@ -8,4 +8,4 @@ MIN_DURATION = 5
8
  MAX_DURATION = 60
9
 
10
  # Processing directory
11
- PROCESSED_RESULTS_DIR = "proprocess_results"
 
8
  MAX_DURATION = 60
9
 
10
  # Processing directory
11
+ PROCESSED_RESULTS_DIR = "processed_results"
lipsync_processing.py CHANGED
@@ -2,6 +2,7 @@
2
 
3
  import os
4
  import traceback
 
5
 
6
 
7
  def apply_lipsync_to_video(
@@ -19,9 +20,7 @@ def apply_lipsync_to_video(
19
  """
20
  try:
21
  lipsynced_video = os.path.join(output_dir, "output_with_lipsync.mp4")
22
- apply_lipsync(
23
- video_path, audio_16k_path, lipsynced_video, method=lipsync_method
24
- )
25
  return lipsynced_video
26
  except RuntimeError as e:
27
  if "out of memory" in str(e).lower():
 
2
 
3
  import os
4
  import traceback
5
+ from lipsync import apply_lipsync
6
 
7
 
8
  def apply_lipsync_to_video(
 
20
  """
21
  try:
22
  lipsynced_video = os.path.join(output_dir, "output_with_lipsync.mp4")
23
+ apply_lipsync(video_path, audio_16k_path, lipsynced_video)
 
 
24
  return lipsynced_video
25
  except RuntimeError as e:
26
  if "out of memory" in str(e).lower():
processing.py CHANGED
@@ -136,7 +136,7 @@ def process_lipsync_with_audio_target(
136
 
137
  with timer("Applying lipsync"):
138
  lipsynced_video = apply_lipsync_to_video(
139
- video_looped, audio_16k, output_dir, lipsync_method
140
  )
141
 
142
  with timer("Upscaling video to original resolution"):
 
136
 
137
  with timer("Applying lipsync"):
138
  lipsynced_video = apply_lipsync_to_video(
139
+ video_looped, audio_16k, output_dir
140
  )
141
 
142
  with timer("Upscaling video to original resolution"):
pyproject.toml DELETED
@@ -1,62 +0,0 @@
1
- [project]
2
- name = "outoflipsync"
3
- version = "0.1.0"
4
- description = "LipSync application using LatentSync v1.6 with video and audio input"
5
- readme = "README.md"
6
- requires-python = ">=3.9"
7
- dependencies = [
8
- "torchaudio==2.8.0",
9
- "torchvision==0.23.0",
10
- "triton",
11
- "deepspeed==0.17.1",
12
- "flash-attn-3 @ https://huggingface.co/alexnasa/flash-attn-3/resolve/main/128/flash_attn_3-3.0.0b1-cp39-abi3-linux_x86_64.whl",
13
- "latentsync @ git+https://github.com/OutofAi/LatentSync-batch.git",
14
- "FastAudioSR @ git+https://github.com/ysharma3501/FlashSR.git",
15
- "DeepCache",
16
- "pydub==0.25.1",
17
- "ffmpeg-python==0.2.0",
18
- "python_speech_features==0.6",
19
- "librosa==0.10.2.post1",
20
- "accelerate==1.8.1",
21
- "transformers==4.52.3",
22
- "tokenizers==0.21.0",
23
- "sentencepiece",
24
- "g2p-en==2.1.0",
25
- "omegaconf==2.3.0",
26
- "munch==4.0.0",
27
- "tqdm",
28
- "diffusers==0.33.1",
29
- "huggingface-hub<1.0",
30
- "imageio==2.27.0",
31
- "decord==0.6.0",
32
- "opencv-python==4.9.0.80",
33
- "mediapipe==0.10.11",
34
- "av",
35
- "torch-fidelity==0.3.0",
36
- "torchmetrics==1.3.1",
37
- "lpips==0.1.4",
38
- "face-alignment==1.4.1",
39
- "insightface==0.7.3",
40
- "kornia==0.8.0",
41
- "numpy==1.26.2",
42
- "matplotlib==3.8.2",
43
- "numba==0.58.1",
44
- "Cython==3.0.7",
45
- "einops==0.7.0",
46
- "ninja==1.11.1.1",
47
- "descript-audiotools @ git+https://github.com/descriptinc/audiotools.git",
48
- "tigersound @ git+https://github.com/OutofAi/tigersound.git",
49
- "hf-xet==1.1.8",
50
- "modelscope==1.27.0",
51
- "onnxruntime-gpu==1.21.0",
52
- "realesrgan>=0.3.0",
53
- "basicsr>=1.4.2",
54
- "gradio==6.4.0",
55
- ]
56
-
57
- [build-system]
58
- requires = ["setuptools>=64", "wheel"]
59
- build-backend = "setuptools.build_meta"
60
-
61
- [tool.uv]
62
- dev-dependencies = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -3,9 +3,9 @@ torchaudio==2.8.0
3
  torchvision
4
  triton
5
  deepspeed==0.17.1
6
- flash-attn-3 @ https://huggingface.co/alexnasa/flash-attn-3/resolve/main/128/flash_attn_3-3.0.0b1-cp39-abi3-linux_x86_64.whl
7
- latentsync @ git+https://github.com/OutofAi/LatentSync-batch.git
8
- FastAudioSR @ git+https://github.com/ysharma3501/FlashSR.git
9
  DeepCache
10
 
11
  pydub==0.25.1
@@ -45,8 +45,8 @@ einops==0.7.0
45
  ninja==1.11.1.1
46
 
47
  # --- Model Repos & Tools ---
48
- descript-audiotools @ git+https://github.com/descriptinc/audiotools.git
49
- tigersound @ git+https://github.com/OutofAi/tigersound.git
50
  hf-xet==1.1.8
51
  modelscope==1.27.0
52
  onnxruntime-gpu==1.21.0
 
3
  torchvision
4
  triton
5
  deepspeed==0.17.1
6
+ https://huggingface.co/alexnasa/flash-attn-3/resolve/main/128/flash_attn_3-3.0.0b1-cp39-abi3-linux_x86_64.whl
7
+ git+https://github.com/OutofAi/LatentSync-batch.git
8
+ git+https://github.com/ysharma3501/FlashSR.git
9
  DeepCache
10
 
11
  pydub==0.25.1
 
45
  ninja==1.11.1.1
46
 
47
  # --- Model Repos & Tools ---
48
+ git+https://github.com/descriptinc/audiotools.git
49
+ git+https://github.com/OutofAi/tigersound.git
50
  hf-xet==1.1.8
51
  modelscope==1.27.0
52
  onnxruntime-gpu==1.21.0
requirements_local.txt ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # --- Core Torch Stack ---
2
+ torchaudio==2.8.0
3
+ torchvision
4
+ triton
5
+ deepspeed==0.17.1
6
+ git+https://github.com/OutofAi/LatentSync-batch.git
7
+ git+https://github.com/ysharma3501/FlashSR.git
8
+ DeepCache
9
+
10
+ pydub==0.25.1
11
+ ffmpeg-python==0.2.0
12
+ python_speech_features==0.6
13
+ librosa==0.10.2.post1
14
+
15
+ accelerate==1.8.1
16
+ transformers==4.52.3
17
+ tokenizers==0.21.0
18
+ sentencepiece
19
+ g2p-en==2.1.0
20
+ omegaconf==2.3.0
21
+ munch==4.0.0
22
+ tqdm
23
+
24
+ diffusers==0.33.1
25
+ huggingface-hub<1.0
26
+ imageio==2.27.0
27
+ opencv-python==4.9.0.80
28
+ mediapipe==0.10.11
29
+ av
30
+ torch-fidelity==0.3.0
31
+ torchmetrics==1.3.1
32
+ lpips==0.1.4
33
+ face-alignment==1.4.1
34
+ insightface==0.7.3
35
+ kornia==0.8.0
36
+
37
+ # --- Numerical / Scientific ---
38
+ numpy==1.26.2
39
+ matplotlib==3.8.2
40
+ numba==0.58.1
41
+ Cython==3.0.7
42
+ einops==0.7.0
43
+ ninja==1.11.1.1
44
+
45
+ # --- Model Repos & Tools ---
46
+ git+https://github.com/descriptinc/audiotools.git
47
+ git+https://github.com/OutofAi/tigersound.git
48
+ hf-xet==1.1.8
49
+ modelscope==1.27.0
50
+ onnxruntime==1.21.0
51
+
52
+ # --- Real-ESRGAN for Video Upscaling ---
53
+ realesrgan>=0.3.0
54
+ basicsr
requirements_minimal.txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Minimal requirements for local testing on macOS (ARM64)
2
+ # Excludes GPU-only packages: triton, onnxruntime-gpu, decord, flash-attn-3
3
+
4
+ gradio==6.4.0
5
+ huggingface-hub<1.0
6
+ omegaconf==2.3.0
7
+ tqdm
8
+ ffmpeg-python==0.2.0
9
+ python_speech_features==0.6
10
+ numpy
11
+ imageio
12
+ opencv-python
13
+ pillow
setup_local.sh ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ echo "πŸš€ Setting up OutofLipSync with uv (local development)..."
5
+
6
+ # Check if uv is installed
7
+ if ! command -v uv &> /dev/null; then
8
+ echo "πŸ“¦ Installing uv..."
9
+ curl -LsSf https://astral.sh/uv/install.sh | sh
10
+ export PATH="$HOME/.cargo/bin:$PATH"
11
+ fi
12
+
13
+ echo "πŸ”§ Creating virtual environment..."
14
+ uv venv
15
+
16
+ # Detect OS
17
+ OS="$(uname -s)"
18
+ ARCH="$(uname -m)"
19
+
20
+ if [[ "$OS" == "Darwin" && "$ARCH" == "arm64" ]]; then
21
+ echo "⚠️ macOS ARM64 detected"
22
+ echo "πŸ“¦ Installing minimal dependencies (GPU packages not supported on macOS ARM64)..."
23
+ uv pip install -r requirements_minimal.txt
24
+ echo ""
25
+ echo "⚠️ WARNING: The following packages cannot be installed on macOS ARM64:"
26
+ echo " - triton (GPU compute)"
27
+ echo " - onnxruntime-gpu (GPU inference)"
28
+ echo " - decord (video processing)"
29
+ echo " - flash-attn-3 (attention mechanism)"
30
+ echo ""
31
+ echo " Full ML functionality is NOT available on macOS."
32
+ echo " For testing, use HuggingFace Spaces (Linux GPU environment)."
33
+ else
34
+ echo "πŸ“₯ Installing all dependencies from requirements.txt..."
35
+ uv pip install -r requirements.txt
36
+ fi
37
+
38
+ echo ""
39
+ echo "βœ… Setup complete!"
40
+ echo "πŸŽ‰ Run app with: uv run python app.py"
41
+ echo " Or: source .venv/bin/activate && python app.py"
time_util.py CHANGED
@@ -1,9 +1,11 @@
1
  import time
2
  from contextlib import contextmanager
3
 
 
4
  @contextmanager
5
  def timer(name: str):
6
  start = time.time()
7
  print(f"{name}...")
8
  yield
9
- print(f" -> {name} completed in {time.time() - start:.2f} sec")
 
 
1
  import time
2
  from contextlib import contextmanager
3
 
4
+
5
  @contextmanager
6
  def timer(name: str):
7
  start = time.time()
8
  print(f"{name}...")
9
  yield
10
+ print(f" -> {name} completed in {time.time() - start:.2f} sec")
11
+
video_processing.py CHANGED
@@ -7,6 +7,7 @@ import subprocess
7
  import cv2
8
  import numpy as np
9
  import torch
 
10
 
11
  import torchvision.transforms.functional as F
12
 
@@ -110,7 +111,7 @@ def get_video_info(video_path: str) -> dict:
110
 
111
  width = data["streams"][0]["width"]
112
  height = data["streams"][0]["height"]
113
- fps = eval(data["streams"][0]["r_frame_rate"])
114
  duration = float(data["format"]["duration"])
115
 
116
  return {"width": width, "height": height, "fps": fps, "duration": duration}
@@ -247,6 +248,7 @@ def upscale_video(video_path: str, width: int, height: int, output_dir: str) ->
247
  num_grow_ch=32,
248
  scale=4,
249
  )
 
250
  upsampler = RealESRGANer(
251
  scale=4,
252
  model_path=model_path,
@@ -255,7 +257,7 @@ def upscale_video(video_path: str, width: int, height: int, output_dir: str) ->
255
  tile_pad=10,
256
  pre_pad=0,
257
  half=True,
258
- device=torch.device("cuda"),
259
  )
260
 
261
  cap = cv2.VideoCapture(video_path)
 
7
  import cv2
8
  import numpy as np
9
  import torch
10
+ from fractions import Fraction
11
 
12
  import torchvision.transforms.functional as F
13
 
 
111
 
112
  width = data["streams"][0]["width"]
113
  height = data["streams"][0]["height"]
114
+ fps = float(Fraction(data["streams"][0]["r_frame_rate"]))
115
  duration = float(data["format"]["duration"])
116
 
117
  return {"width": width, "height": height, "fps": fps, "duration": duration}
 
248
  num_grow_ch=32,
249
  scale=4,
250
  )
251
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
252
  upsampler = RealESRGANer(
253
  scale=4,
254
  model_path=model_path,
 
257
  tile_pad=10,
258
  pre_pad=0,
259
  half=True,
260
+ device=device,
261
  )
262
 
263
  cap = cv2.VideoCapture(video_path)