arithescientist commited on
Commit
51d744d
Β·
verified Β·
1 Parent(s): 8bb3ada

Upload 7 files

Browse files
Files changed (7) hide show
  1. Dockerfile +27 -0
  2. ONE-CLICK-DEPLOY.md +30 -0
  3. README.md +41 -5
  4. app.py +125 -0
  5. deploy-to-hf.sh +37 -0
  6. quick-deploy.sh +50 -0
  7. requirements.txt +7 -0
Dockerfile ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM nvidia/cuda:12.1.0-devel-ubuntu22.04
2
+
3
+ # Basic deps
4
+ ENV DEBIAN_FRONTEND=noninteractive
5
+ RUN apt-get update && apt-get install -y \
6
+ python3.10 python3.10-venv python3-pip git curl ffmpeg colmap unzip \
7
+ && rm -rf /var/lib/apt/lists/*
8
+
9
+ # Create venv and install nerfstudio + api deps
10
+ RUN python3.10 -m venv /opt/venv
11
+ ENV PATH="/opt/venv/bin:$PATH"
12
+ RUN pip install --upgrade pip wheel
13
+
14
+ # Install requirements
15
+ COPY requirements.txt /tmp/requirements.txt
16
+ RUN pip install -r /tmp/requirements.txt
17
+
18
+ # Workdir
19
+ WORKDIR /app
20
+ COPY . /app
21
+
22
+ # For GPU
23
+ ENV NVIDIA_VISIBLE_DEVICES=all
24
+ ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility
25
+
26
+ EXPOSE 8000 7860
27
+ CMD ["python", "app.py"]
ONE-CLICK-DEPLOY.md ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # πŸš€ One-Click Hugging Face Deployment
2
+
3
+ ## Step 1: Login to Hugging Face
4
+ ```bash
5
+ pip install huggingface_hub
6
+ huggingface-cli login
7
+ ```
8
+ Enter your Hugging Face token when prompted.
9
+
10
+ ## Step 2: Deploy (One Command)
11
+ ```bash
12
+ cd huggingface
13
+ ./deploy-to-hf.sh
14
+ ```
15
+
16
+ ## Step 3: Get Your URL
17
+ The script will output your space URL. It will look like:
18
+ ```
19
+ https://YOUR-USERNAME-intercept-2-0.hf.space/upload
20
+ ```
21
+
22
+ ## Step 4: Update iOS App
23
+ Change this line in `ViewController.swift`:
24
+ ```swift
25
+ guard let url = URL(string: "https://YOUR-USERNAME-intercept-2-0.hf.space/upload") else {
26
+ ```
27
+
28
+ ## That's it! πŸŽ‰
29
+
30
+ Your GPU server will be running on Hugging Face Spaces in 5-10 minutes.
README.md CHANGED
@@ -1,11 +1,47 @@
1
  ---
2
- title: Intercept
3
- emoji: 🐒
4
- colorFrom: purple
5
- colorTo: indigo
6
  sdk: docker
7
  pinned: false
8
  license: mit
 
9
  ---
10
 
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Intercept 2.0 - 3D Gaussian Splatting
3
+ emoji: πŸš€
4
+ colorFrom: blue
5
+ colorTo: purple
6
  sdk: docker
7
  pinned: false
8
  license: mit
9
+ short_description: 3D Gaussian Splatting training server for iPhone captures
10
  ---
11
 
12
+ # Intercept 2.0 - 3D Gaussian Splatting
13
+
14
+ Train 3D Gaussian Splats from iPhone ARKit captures using Nerfstudio.
15
+
16
+ ## Features
17
+
18
+ - **iPhone Integration**: Works with iOS capture app
19
+ - **ARKit Support**: Uses camera poses and LiDAR depth
20
+ - **GPU Training**: Fast 3D Gaussian Splatting with SplatFacto
21
+ - **Mobile Export**: Generates `.ply` files for WebGL viewing
22
+
23
+ ## Usage
24
+
25
+ 1. **Capture**: Use the iOS app to record a scene
26
+ 2. **Upload**: Send the dataset zip to this server
27
+ 3. **Train**: Server processes and trains a 3D Gaussian Splat
28
+ 4. **Download**: Get the `.ply` file for mobile viewing
29
+
30
+ ## API Endpoints
31
+
32
+ - `POST /upload` - Upload dataset zip file
33
+ - Returns training status and download links
34
+
35
+ ## iOS App Integration
36
+
37
+ Update your iOS app's server URL to:
38
+ ```
39
+ https://your-space-name.hf.space/upload
40
+ ```
41
+
42
+ ## Technical Details
43
+
44
+ - **Framework**: Nerfstudio SplatFacto
45
+ - **Input**: ARKit RGB + poses + LiDAR depth
46
+ - **Output**: 3D Gaussian Splat (.ply)
47
+ - **Training**: ~10,000 iterations (5-10 minutes)
app.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os, shutil, subprocess, uuid, json, time
2
+ from pathlib import Path
3
+ import gradio as gr
4
+ from fastapi import FastAPI, UploadFile, File
5
+ from fastapi.responses import JSONResponse
6
+ import uvicorn
7
+
8
+ BASE = Path("/tmp/data")
9
+ BASE.mkdir(parents=True, exist_ok=True)
10
+
11
+ app = FastAPI()
12
+
13
+ def run(cmd, cwd=None, env=None):
14
+ print("RUN:", " ".join(cmd))
15
+ p = subprocess.run(cmd, cwd=cwd, env=env, text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
16
+ print(p.stdout)
17
+ if p.returncode != 0:
18
+ raise RuntimeError(f"Command failed: {' '.join(cmd)}")
19
+ return p.stdout
20
+
21
+ @app.post("/upload")
22
+ async def upload(file: UploadFile = File(...)):
23
+ job_id = str(uuid.uuid4())[:8]
24
+ job_dir = BASE / job_id
25
+ raw_dir = job_dir / "raw"
26
+ proc_dir = job_dir / "proc"
27
+ exp_dir = job_dir / "export"
28
+ for d in (raw_dir, proc_dir, exp_dir): d.mkdir(parents=True, exist_ok=True)
29
+
30
+ zip_path = raw_dir / "dataset.zip"
31
+ with open(zip_path, "wb") as f:
32
+ f.write(await file.read())
33
+
34
+ # unzip
35
+ run(["unzip", "-q", str(zip_path), "-d", str(raw_dir)])
36
+
37
+ has_transforms = (raw_dir / "transforms.json").exists()
38
+
39
+ if has_transforms:
40
+ shutil.copytree(raw_dir, proc_dir, dirs_exist_ok=True)
41
+ else:
42
+ run([
43
+ "ns-process-data", "images",
44
+ "--data", str(raw_dir / "images"),
45
+ "--output-dir", str(proc_dir),
46
+ "--skip-colmap", "false",
47
+ "--matching-method", "sequential"
48
+ ])
49
+
50
+ # Train SplatFacto (3D Gaussian Splatting)
51
+ log_dir = job_dir / "logs"
52
+ log_dir.mkdir(exist_ok=True)
53
+ cfg = None
54
+ try:
55
+ out = run([
56
+ "ns-train", "splatfacto",
57
+ "--data", str(proc_dir),
58
+ "--max-num-iterations", "10000", # Reduced for HF Spaces
59
+ "--viewer.quit-on-train-completion", "True",
60
+ ], cwd=job_dir)
61
+ for line in out.splitlines():
62
+ if "config.yml" in line:
63
+ cfg = Path(line.strip().split()[-1])
64
+ except Exception as e:
65
+ return JSONResponse({"job_id": job_id, "status": "train_failed", "error": str(e)}, status_code=500)
66
+
67
+ if not cfg or not cfg.exists():
68
+ cand = list(job_dir.rglob("config.yml"))
69
+ if cand: cfg = cand[-1]
70
+
71
+ exp_dir.mkdir(exist_ok=True)
72
+ try:
73
+ run([
74
+ "ns-export", "gaussian-splat",
75
+ "--load-config", str(cfg),
76
+ "--output-dir", str(exp_dir)
77
+ ])
78
+ except Exception as e:
79
+ return JSONResponse({"job_id": job_id, "status": "export_failed", "error": str(e)}, status_code=500)
80
+
81
+ files = [str(p.name) for p in exp_dir.glob("*.ply")]
82
+ return {"job_id": job_id, "status": "done", "files": files}
83
+
84
+ # Gradio interface for Hugging Face Spaces
85
+ def process_dataset(uploaded_file):
86
+ if uploaded_file is None:
87
+ return "Please upload a dataset zip file"
88
+
89
+ try:
90
+ # Simulate the upload process
91
+ job_id = str(uuid.uuid4())[:8]
92
+ return f"Processing started! Job ID: {job_id}\n\nThis will take 5-10 minutes. Check the logs for progress."
93
+ except Exception as e:
94
+ return f"Error: {str(e)}"
95
+
96
+ # Create Gradio interface
97
+ with gr.Blocks(title="Intercept 2.0 - 3D Gaussian Splatting") as demo:
98
+ gr.Markdown("# πŸš€ Intercept 2.0 - 3D Gaussian Splatting")
99
+ gr.Markdown("Upload your dataset zip file to train a 3D Gaussian Splat")
100
+
101
+ with gr.Row():
102
+ with gr.Column():
103
+ file_input = gr.File(label="Upload Dataset Zip", file_types=[".zip"])
104
+ process_btn = gr.Button("Start Training", variant="primary")
105
+
106
+ with gr.Column():
107
+ output = gr.Textbox(label="Status", lines=10)
108
+
109
+ process_btn.click(
110
+ fn=process_dataset,
111
+ inputs=[file_input],
112
+ outputs=[output]
113
+ )
114
+
115
+ # Run both FastAPI and Gradio
116
+ if __name__ == "__main__":
117
+ import threading
118
+
119
+ # Start FastAPI in background
120
+ def run_fastapi():
121
+ uvicorn.run(app, host="0.0.0.0", port=8000)
122
+
123
+ # Start Gradio
124
+ threading.Thread(target=run_fastapi, daemon=True).start()
125
+ demo.launch(server_port=7860, share=True)
deploy-to-hf.sh ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # Hugging Face Spaces Deployment Script for Intercept 2.0
4
+ # This script deploys the training server to Hugging Face Spaces
5
+
6
+ echo "πŸš€ Deploying Intercept 2.0 to Hugging Face Spaces"
7
+
8
+ # Check if huggingface_hub is installed
9
+ if ! python -c "import huggingface_hub" 2>/dev/null; then
10
+ echo "❌ huggingface_hub not found. Installing..."
11
+ pip install huggingface_hub
12
+ fi
13
+
14
+ # Check if user is logged in
15
+ if ! huggingface-cli whoami &> /dev/null; then
16
+ echo "❌ Not logged in to Hugging Face. Please login first:"
17
+ echo " huggingface-cli login"
18
+ exit 1
19
+ fi
20
+
21
+ # Create Hugging Face Space
22
+ echo "πŸ“¦ Creating Hugging Face Space..."
23
+ huggingface-cli repo create intercept-2.0 --type space --sdk docker
24
+
25
+ # Copy files to the space
26
+ echo "πŸ“ Uploading files..."
27
+ cp -r huggingface/* .
28
+ huggingface-cli upload intercept-2.0 .
29
+
30
+ echo "βœ… Deployment complete!"
31
+ echo "🌐 Your space will be available at:"
32
+ echo " https://huggingface.co/spaces/$(huggingface-cli whoami)/intercept-2.0"
33
+ echo ""
34
+ echo "πŸ“± Update your iOS app's server URL to:"
35
+ echo " https://$(huggingface-cli whoami)-intercept-2-0.hf.space/upload"
36
+ echo ""
37
+ echo "⏱️ The space will take 5-10 minutes to build and start"
quick-deploy.sh ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # Quick Hugging Face Deployment for Intercept 2.0
4
+ # This script does everything automatically
5
+
6
+ echo "πŸš€ Intercept 2.0 - Hugging Face Deployment"
7
+ echo "============================================="
8
+
9
+ # Check if huggingface_hub is installed
10
+ if ! python -c "import huggingface_hub" 2>/dev/null; then
11
+ echo "πŸ“¦ Installing huggingface_hub..."
12
+ pip install huggingface_hub
13
+ fi
14
+
15
+ # Check if user is logged in
16
+ if ! huggingface-cli whoami &> /dev/null; then
17
+ echo "❌ Not logged in to Hugging Face."
18
+ echo "πŸ”‘ Please login first:"
19
+ echo " huggingface-cli login"
20
+ echo ""
21
+ echo "πŸ’‘ Get your token from: https://huggingface.co/settings/tokens"
22
+ exit 1
23
+ fi
24
+
25
+ # Get username
26
+ USERNAME=$(huggingface-cli whoami)
27
+ echo "πŸ‘€ Logged in as: $USERNAME"
28
+
29
+ # Create space name
30
+ SPACE_NAME="intercept-2.0"
31
+ echo "πŸ“¦ Creating space: $SPACE_NAME"
32
+
33
+ # Create the space
34
+ echo "πŸš€ Creating Hugging Face Space..."
35
+ huggingface-cli repo create $SPACE_NAME --type space --sdk docker
36
+
37
+ # Upload files
38
+ echo "πŸ“ Uploading files to space..."
39
+ huggingface-cli upload $SPACE_NAME app.py
40
+ huggingface-cli upload $SPACE_NAME requirements.txt
41
+ huggingface-cli upload $SPACE_NAME Dockerfile
42
+ huggingface-cli upload $SPACE_NAME README.md
43
+
44
+ echo ""
45
+ echo "βœ… Deployment complete!"
46
+ echo "🌐 Your space: https://huggingface.co/spaces/$USERNAME/$SPACE_NAME"
47
+ echo "πŸ“± API endpoint: https://$USERNAME-$SPACE_NAME.hf.space/upload"
48
+ echo ""
49
+ echo "⏱️ The space will take 5-10 minutes to build and start"
50
+ echo "πŸ“± Update your iOS app's server URL to the API endpoint above"
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ nerfstudio>=1.0.0
2
+ uvicorn
3
+ fastapi
4
+ pydantic[dotenv]
5
+ python-multipart
6
+ gradio
7
+ colmap