Devam0 commited on
Commit
37069da
·
1 Parent(s): 8c05c5b

Added my server

Browse files
.gitignore ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ pnpm-debug.log*
8
+ lerna-debug.log*
9
+
10
+ node_modules
11
+ dist
12
+ dist-ssr
13
+ *.local
14
+
15
+ # Editor directories and files
16
+ .vscode/*
17
+ !.vscode/extensions.json
18
+ .idea
19
+ .DS_Store
20
+ *.suo
21
+ *.ntvs*
22
+ *.njsproj
23
+ *.sln
24
+ *.sw?
25
+
26
+ # Python
27
+ __pycache__/
28
+ *.py[cod]
29
+ *$py.class
30
+ *.so
31
+ .Python
32
+ env/
33
+ venv/
34
+ ENV/
35
+ env.bak/
36
+ venv.bak/
37
+
38
+
39
+ # Uploads and temporary files
40
+ uploads/
41
+ *.tmp
42
+ *.temp
43
+
44
+
45
+
46
+ # Profiles (if they contain sensitive data)
47
+ profiles/*.json
48
+
49
+ # Environment variables
50
+ .env
51
+ .env.local
52
+ .env.development.local
53
+ .env.test.local
54
+ .env.production.local
Dockerfile ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Base image
2
+ FROM python:3.9
3
+
4
+ # Create non-root user
5
+ RUN useradd -m -u 1000 user
6
+ USER user
7
+
8
+
9
+ # Set working directory
10
+ WORKDIR /app
11
+
12
+ # Copy and install dependencies
13
+ COPY --chown=user ./requirements.txt requirements.txt
14
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
15
+
16
+ # Copy project files
17
+ COPY --chown=user . /app
18
+
19
+ # Expose Hugging Face Space port
20
+ EXPOSE 7860
21
+
22
+ # Start FastAPI server
23
+ CMD ["uvicorn", "inference_server:app", "--host", "0.0.0.0", "--port", "7860"]
Procfile ADDED
@@ -0,0 +1 @@
 
 
1
+ web: uvicorn inference_server:app --host 0.0.0.0 --port $PORT
README.md CHANGED
@@ -1,10 +1,115 @@
 
 
 
 
 
 
 
 
 
 
1
  ---
2
- title: Devam
3
- emoji:
4
- colorFrom: purple
5
- colorTo: purple
6
- sdk: docker
7
- pinned: false
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
+ # 🦄 FastAPI Inference Server
2
+
3
+ A blazing-fast inference server for computer vision tasks using FastAPI, YOLO, DINOv2, and FAISS! 🚀
4
+
5
+ ## Features
6
+ - **YOLOv8 Segmentation**: Detect and segment objects in images
7
+ - **DINOv2 Embeddings**: Extract powerful image features
8
+ - **FAISS Vector Search**: Find similar items using vector search
9
+ - **Easy REST API**: Simple endpoints for integration with any frontend
10
+
11
  ---
12
+
13
+ ## 🛠️ Setup
14
+
15
+ ### 1. Clone the repository
16
+ ```bash
17
+ git clone <your-repo-url>
18
+ cd <your-project-directory>
19
+ ```
20
+
21
+ ### 2. Install dependencies
22
+ ```bash
23
+ pip install -r requirements.txt
24
+ ```
25
+
26
+ ### 3. Download/Place Model Files
27
+ - Place your YOLO model at `models/deepfashion2_yolov8s-seg.pt`
28
+ - Place your FAISS index and metadata at `index/jersey_index.faiss` and `index/jersey_metadata.npy`
29
+
30
+ ### 4. Start the server
31
+ ```bash
32
+ uvicorn inference_server:app --host 0.0.0.0 --port 8000 --reload
33
+ ```
34
+
35
+ ---
36
+
37
+ ## 🔥 API Endpoints
38
+
39
+ ### `POST /yolo`
40
+ - **Description:** Run YOLOv8 segmentation on an image
41
+ - **Request:** Multipart/form-data with an image file
42
+ - **Response:** JSON with detected polygons
43
+
44
+ ### `POST /dino`
45
+ - **Description:** Extract DINOv2 features from an image
46
+ - **Request:** Multipart/form-data with an image file
47
+ - **Response:** JSON with feature vector
48
+
49
+ ### `POST /faiss`
50
+ - **Description:** Search for similar items using FAISS
51
+ - **Request:** JSON with `features` (list of floats)
52
+ - **Response:** JSON with ranked search results
53
+
54
+ ---
55
+
56
+ ## 🧑‍💻 Example Usage
57
+
58
+ ### YOLO Inference (Python)
59
+ ```python
60
+ import requests
61
+
62
+ with open('your_image.jpg', 'rb') as f:
63
+ response = requests.post('http://localhost:8000/yolo', files={'file': f})
64
+ print(response.json())
65
+ ```
66
+
67
+ ### DINOv2 Inference (Python)
68
+ ```python
69
+ import requests
70
+
71
+ with open('your_image.jpg', 'rb') as f:
72
+ response = requests.post('http://localhost:8000/dino', files={'file': f})
73
+ print(response.json())
74
+ ```
75
+
76
+ ### FAISS Search (Python)
77
+ ```python
78
+ import requests
79
+ features = [0.1, 0.2, ...] # Replace with your feature vector
80
+ response = requests.post('http://localhost:8000/faiss', json={'features': features})
81
+ print(response.json())
82
+ ```
83
+
84
+ ---
85
+
86
+ ## 🌐 CORS
87
+ If using a frontend on a different port, make sure to enable CORS in `inference_server.py`:
88
+ ```python
89
+ from fastapi.middleware.cors import CORSMiddleware
90
+ app.add_middleware(
91
+ CORSMiddleware,
92
+ allow_origins=["https://localhost:8081"],
93
+ allow_credentials=True,
94
+ allow_methods=["*"],
95
+ allow_headers=["*"],
96
+ )
97
+ ```
98
+
99
+ ---
100
+
101
+ ## 📂 Project Structure
102
+ ```
103
+ ├── inference_server.py # FastAPI app and endpoints
104
+ ├── requirements.txt # Python dependencies
105
+ ├── models/
106
+ │ └── deepfashion2_yolov8s-seg.pt
107
+ ├── index/
108
+ │ ├── jersey_index.faiss
109
+ │ └── jersey_metadata.npy
110
+ ```
111
+
112
  ---
113
 
114
+ ## 📝 License
115
+ MIT License
index/jersey_metadata.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5d9c7554b9a4ee1afa74586d50ffdde0b0e66b5899b4755fe2a06d1dc089049b
3
+ size 5027
inference_server.py ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, File, UploadFile
2
+ from pydantic import BaseModel
3
+ from typing import List
4
+ import torch
5
+ from transformers import AutoImageProcessor, AutoModel
6
+ from ultralytics import YOLO
7
+ import faiss
8
+ import numpy as np
9
+ from PIL import Image
10
+ import io
11
+
12
+ app = FastAPI()
13
+
14
+ # Load models and index ONCE at startup
15
+ device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
16
+ processor = AutoImageProcessor.from_pretrained('facebook/dinov2-base')
17
+ dino_model = AutoModel.from_pretrained('facebook/dinov2-base').to(device)
18
+ yolo_model = YOLO("models/deepfashion2_yolov8s-seg.pt")
19
+ faiss_index = faiss.read_index("index/jersey_index.faiss")
20
+
21
+ loaded_data = np.load("index/jersey_metadata.npy", allow_pickle=True)
22
+ if isinstance(loaded_data, dict):
23
+ index_to_path = {int(k): v for k, v in loaded_data.items()}
24
+ elif isinstance(loaded_data, np.ndarray):
25
+ index_to_path = {i: str(item) for i, item in enumerate(loaded_data)}
26
+ else:
27
+ index_to_path = {}
28
+
29
+ class FeaturesRequest(BaseModel):
30
+ features: List[float] | List[List[float]]
31
+
32
+ @app.post("/dino")
33
+ async def dino_inference(file: UploadFile = File(...)):
34
+ image_bytes = await file.read()
35
+ image = Image.open(io.BytesIO(image_bytes)).convert('RGB')
36
+ with torch.no_grad():
37
+ inputs = processor(images=image, return_tensors="pt").to(device)
38
+ outputs = dino_model(**inputs)
39
+ features = outputs.last_hidden_state.mean(dim=1).detach().cpu().numpy()[0]
40
+ return {"features": features.tolist()}
41
+
42
+ @app.post("/faiss")
43
+ async def faiss_search(request: FeaturesRequest):
44
+ features = request.features
45
+ if isinstance(features[0], list):
46
+ vector = np.array(features, dtype=np.float32)
47
+ else:
48
+ vector = np.array([features], dtype=np.float32)
49
+ if vector.shape[1] != faiss_index.d:
50
+ error_msg = f"Feature vector length {vector.shape[1]} does not match FAISS index dimension {faiss_index.d}"
51
+ return {"error": error_msg}
52
+ faiss.normalize_L2(vector)
53
+ distances, indices = faiss_index.search(vector, 15)
54
+ results = []
55
+ for i, (distance, idx) in enumerate(zip(distances[0], indices[0])):
56
+ if idx in index_to_path:
57
+ key = idx
58
+ results.append({
59
+ "rank": i + 1,
60
+ "distance": float(distance),
61
+ "file_path": index_to_path[key],
62
+ "full_path": f"catalogue/{index_to_path[key]}"
63
+ })
64
+ return {"results": results}
65
+
66
+ @app.post("/yolo")
67
+ async def yolo_inference(file: UploadFile = File(...)):
68
+ image_bytes = await file.read()
69
+ image = Image.open(io.BytesIO(image_bytes)).convert('RGB')
70
+ results = yolo_model(image, device=0 if torch.cuda.is_available() else 'cpu', verbose=False)[0]
71
+ polygons = []
72
+ if hasattr(results, 'masks') and results.masks is not None and hasattr(results.masks, 'xy'):
73
+ for mask in results.masks.xy:
74
+ polygons.append(mask.tolist())
75
+ return {"polygons": polygons}
models/deepfashion2_yolov8s-seg.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c319c15e86443ea61f70b40620909d737c47ff2a39381536503ac5c54772f8ac
3
+ size 23852321
requirements.txt ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Core ML libraries
2
+ torch>=2.0.0
3
+ torchvision>=0.15.0
4
+ ultralytics>=8.0.0
5
+ transformers>=4.30.0
6
+ Pillow>=9.0.0
7
+
8
+ # Computer Vision
9
+ opencv-python>=4.8.0
10
+
11
+ # Vector search
12
+ faiss-cpu>=1.7.0
13
+ # For GPU support, use: faiss-gpu>=1.7.0
14
+
15
+ # Utilities
16
+ numpy>=1.24.0
17
+ scikit-image>=0.20.0
18
+ tqdm>=4.65.0
19
+
20
+ # Optional: For better performance
21
+ # tensorrt # Only if you have NVIDIA GPU
22
+ # onnxruntime-gpu # Only if you have NVIDIA GPU
23
+
24
+ fastapi
25
+ uvicorn[standard]