Pradhap commited on
Commit
468f02c
·
1 Parent(s): 8fe6cc7

Set up devis-matcher encoder API

Browse files
Files changed (3) hide show
  1. README.md +24 -8
  2. app.py +56 -4
  3. requirements.txt +3 -0
README.md CHANGED
@@ -1,15 +1,31 @@
1
  ---
2
- title: Test
3
- emoji: 🐢
4
- colorFrom: gray
5
- colorTo: indigo
6
  sdk: gradio
7
- sdk_version: 6.14.0
8
- python_version: '3.13'
9
  app_file: app.py
10
  pinned: false
11
  license: mit
12
- short_description: test
13
  ---
14
 
15
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Devis Matcher Encoder
3
+ emoji: 🪛
4
+ colorFrom: indigo
5
+ colorTo: pink
6
  sdk: gradio
7
+ sdk_version: 4.44.0
 
8
  app_file: app.py
9
  pinned: false
10
  license: mit
 
11
  ---
12
 
13
+ # Devis Matcher Encoder
14
+
15
+ HF Space exposing `Pradhap/devis-matcher` (fine-tuned camembert-large, ~440 MB)
16
+ as a sentence-embedding API for French construction document matching.
17
+
18
+ Used by the ConstructCRM backend (FastAPI on Render) to keep heavy model
19
+ weights off the 512 MB worker.
20
+
21
+ ## API
22
+
23
+ ```
24
+ POST /api/encode/
25
+ Content-Type: application/json
26
+ Body: {"data": [["text 1", "text 2"]]}
27
+ Returns: {"data": [[[float, ...], [float, ...]]], ...}
28
+ ```
29
+
30
+ Send as many strings as you can in one call — the model encodes batches
31
+ significantly faster than one-at-a-time.
app.py CHANGED
@@ -1,7 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
- def greet(name):
4
- return "Hello " + name + "!!"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- demo = gr.Interface(fn=greet, inputs="text", outputs="text")
7
- demo.launch()
 
1
+ """HF Space exposing Pradhap/devis-matcher as a sentence-embedding API.
2
+
3
+ The fine-tuned camembert-large model (~440 MB) is loaded once at Space startup
4
+ into the container's 16 GB RAM, then used to encode batches of strings on
5
+ demand. The ConstructCRM backend (Render free tier, 512 MB) calls this Space
6
+ instead of loading the model locally — which would OOM the worker.
7
+
8
+ API surface (auto-generated by Gradio):
9
+
10
+ POST /api/encode/
11
+ body: {"data": [["text 1", "text 2"]]}
12
+ returns: {"data": [[[float, ...], [float, ...]]], ...}
13
+
14
+ For batch efficiency, send as many texts as you can in a single call.
15
+ """
16
  import gradio as gr
17
+ from sentence_transformers import SentenceTransformer
18
+
19
+ MODEL_NAME = "Pradhap/devis-matcher"
20
+
21
+ print(f"[Space] Loading {MODEL_NAME} (cold start may take a minute)…")
22
+ model = SentenceTransformer(MODEL_NAME)
23
+ print(f"[Space] Loaded. Embedding dim: {model.get_sentence_embedding_dimension()}")
24
+
25
+
26
+ def encode(texts):
27
+ """Encode a list of strings into sentence embeddings."""
28
+ if texts is None:
29
+ return []
30
+ if isinstance(texts, str):
31
+ texts = [texts]
32
+ if not isinstance(texts, list):
33
+ return {"error": f"expected list[str], got {type(texts).__name__}"}
34
+ texts = [t for t in texts if isinstance(t, str)]
35
+ if not texts:
36
+ return []
37
+ embs = model.encode(texts, convert_to_numpy=True, normalize_embeddings=False)
38
+ return embs.tolist()
39
+
40
 
41
+ demo = gr.Interface(
42
+ fn=encode,
43
+ inputs=gr.JSON(label="Texts (JSON array of strings)"),
44
+ outputs=gr.JSON(label="Embeddings (2D float array)"),
45
+ title="Devis Matcher Encoder",
46
+ description=(
47
+ f"Sentence embeddings via **{MODEL_NAME}** "
48
+ "(camembert-large fine-tuned on French construction documents). "
49
+ "POST a list of strings, receive a 2D array of embedding vectors."
50
+ ),
51
+ examples=[
52
+ [["PEINTURE SUR MURS", "Carrelage faïence salle de bain", "Plomberie cuisine"]],
53
+ ],
54
+ api_name="encode",
55
+ allow_flagging="never",
56
+ )
57
 
58
+ if __name__ == "__main__":
59
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ sentence-transformers>=2.7.0
2
+ gradio>=4.44.0
3
+ torch>=2.0.0