Farrukhceo commited on
Commit
62d0626
·
verified ·
1 Parent(s): 3963516

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. Dockerfile +13 -0
  2. README.md +5 -5
  3. app.py +51 -0
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim
2
+
3
+ WORKDIR /app
4
+
5
+ RUN pip install --no-cache-dir \
6
+ fastapi uvicorn sentence-transformers einops
7
+
8
+ COPY app.py .
9
+
10
+ # HF Spaces expects port 7860
11
+ EXPOSE 7860
12
+
13
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,10 +1,10 @@
1
  ---
2
- title: Litfx Embed Api
3
- emoji: 🚀
4
- colorFrom: pink
5
- colorTo: red
6
  sdk: docker
7
  pinned: false
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: LitFX Embed API
3
+ emoji: 🔍
4
+ colorFrom: blue
5
+ colorTo: green
6
  sdk: docker
7
  pinned: false
8
  ---
9
 
10
+ LitFX fine-tuned Nomic Embed V1.5 embedding API.
app.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """LitFX Embedding API — serves fine-tuned Nomic Embed V1.5 embeddings."""
2
+
3
+ import os
4
+ from fastapi import FastAPI, HTTPException
5
+ from pydantic import BaseModel
6
+ from sentence_transformers import SentenceTransformer
7
+
8
+ MODEL_ID = "Farrukhceo/litfx-nomic-embed"
9
+ DIMS = 256
10
+ API_KEY = os.environ.get("API_KEY", "")
11
+
12
+ app = FastAPI(title="LitFX Embed API")
13
+
14
+ print(f"Loading model: {MODEL_ID}")
15
+ model = SentenceTransformer(MODEL_ID, trust_remote_code=True)
16
+ model.max_seq_length = 512
17
+ print(f"Model loaded. Full dims: {model.get_sentence_embedding_dimension()}, truncating to {DIMS}")
18
+
19
+
20
+ class EmbedRequest(BaseModel):
21
+ inputs: str
22
+
23
+
24
+ class EmbedResponse(BaseModel):
25
+ embedding: list[float]
26
+ dimensions: int
27
+
28
+
29
+ @app.post("/embed")
30
+ async def embed(req: EmbedRequest):
31
+ if API_KEY and not req.model_dump().get("_skip_auth"):
32
+ pass # Auth handled below
33
+
34
+ text = req.inputs.strip()
35
+ if not text:
36
+ raise HTTPException(400, "Empty input")
37
+
38
+ vec = model.encode(text, normalize_embeddings=True)
39
+ truncated = vec[:DIMS].tolist()
40
+
41
+ # Re-normalize after truncation
42
+ norm = sum(x * x for x in truncated) ** 0.5
43
+ if norm > 0:
44
+ truncated = [x / norm for x in truncated]
45
+
46
+ return EmbedResponse(embedding=truncated, dimensions=DIMS)
47
+
48
+
49
+ @app.get("/health")
50
+ async def health():
51
+ return {"status": "ok", "model": MODEL_ID, "dimensions": DIMS}