akhaliq HF Staff commited on
Commit
69231c1
·
1 Parent(s): 912eb02

openjev NLI workflow on ZeroGPU: bound jev-classify/jev-rerank fn nodes, requirements, gradio 6.28.0

Browse files
Files changed (4) hide show
  1. README.md +1 -1
  2. requirements.txt +3 -0
  3. run.py +50 -1
  4. workflow.json +74 -1
README.md CHANGED
@@ -4,7 +4,7 @@ emoji: ⚡
4
  colorFrom: indigo
5
  colorTo: indigo
6
  sdk: gradio
7
- sdk_version: 6.25.0
8
  app_file: run.py
9
  pinned: false
10
  hf_oauth: true
 
4
  colorFrom: indigo
5
  colorTo: indigo
6
  sdk: gradio
7
+ sdk_version: 6.28.0
8
  app_file: run.py
9
  pinned: false
10
  hf_oauth: true
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ spaces
2
+ torch
3
+ transformers
run.py CHANGED
@@ -1,6 +1,55 @@
 
 
1
  import gradio as gr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
- demo = gr.Workflow()
 
 
 
4
 
5
  if __name__ == "__main__":
6
  demo.launch()
 
1
+ import json
2
+
3
  import gradio as gr
4
+ import spaces
5
+ import torch
6
+ from transformers import AutoModelForSequenceClassification, AutoTokenizer
7
+
8
+ MODEL_ID = "AlexWortega/openjev"
9
+ SUBFOLDER = "qwen3.5-4b-nli-v2"
10
+ LABELS = ["contradiction", "entailment", "neutral"]
11
+
12
+ # Load at module level on cuda — ZeroGPU emulates CUDA at startup and
13
+ # attaches a real GPU inside @spaces.GPU functions.
14
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, subfolder=SUBFOLDER)
15
+ model = AutoModelForSequenceClassification.from_pretrained(
16
+ MODEL_ID, subfolder=SUBFOLDER, trust_remote_code=True, torch_dtype=torch.bfloat16
17
+ ).to("cuda").eval()
18
+
19
+
20
+ @spaces.GPU(duration=60)
21
+ def classify(premise: str, hypothesis: str) -> str:
22
+ """Run openjev NLI: returns contradiction / entailment / neutral probabilities."""
23
+ text = model.config.nli_template.format(premise=premise, hypothesis=hypothesis)
24
+ inputs = tokenizer(text, return_tensors="pt").to("cuda")
25
+ with torch.no_grad():
26
+ probs = model(**inputs).logits.softmax(-1)[0].float().cpu()
27
+ result = {label: round(float(p), 4) for label, p in zip(LABELS, probs)}
28
+ result["prediction"] = LABELS[int(probs.argmax())]
29
+ return json.dumps(result, indent=2)
30
+
31
+
32
+ @spaces.GPU(duration=60)
33
+ def rerank(question: str, options: str) -> str:
34
+ """Pick the option with the highest entailment against the question.
35
+ Options are one per line."""
36
+ best_idx, best_score, scores = -1, -1.0, []
37
+ for i, option in enumerate([o.strip() for o in options.splitlines() if o.strip()]):
38
+ text = model.config.nli_template.format(premise=question, hypothesis=option)
39
+ inputs = tokenizer(text, return_tensors="pt").to("cuda")
40
+ with torch.no_grad():
41
+ probs = model(**inputs).logits.softmax(-1)[0].float().cpu()
42
+ score = float(probs[1]) # entailment
43
+ scores.append((option, round(score, 4)))
44
+ if score > best_score:
45
+ best_idx, best_score = i, score
46
+ return json.dumps({"answer_index": best_idx, "scores": scores}, indent=2)
47
+
48
 
49
+ demo = gr.Workflow(
50
+ graph="workflow.json",
51
+ bind={"jev-classify": classify, "jev-rerank": rerank},
52
+ )
53
 
54
  if __name__ == "__main__":
55
  demo.launch()
workflow.json CHANGED
@@ -1 +1,74 @@
1
- {"schema_version":"2","name":"My Workflow","runtime":{"default":"client"},"references":[],"operators":[],"subjects":[],"edges":[],"view":{"default":"canvas"}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "schema_version": "2",
3
+ "name": "openjev NLI",
4
+ "runtime": {"default": "client"},
5
+ "references": [
6
+ {
7
+ "id": "ref_premise",
8
+ "label": "Premise",
9
+ "role": "reference",
10
+ "asset_type": "text",
11
+ "data": {"value": "The bird is 0.05 below the centre of the gap."},
12
+ "inputs": [{"id": "in", "label": "Text", "type": "text"}],
13
+ "outputs": [{"id": "out", "label": "Text", "type": "text"}],
14
+ "x": 60, "y": 80
15
+ },
16
+ {
17
+ "id": "ref_hypothesis",
18
+ "label": "Hypothesis",
19
+ "role": "reference",
20
+ "asset_type": "text",
21
+ "data": {"value": "The bird is below the centre of the gap."},
22
+ "inputs": [{"id": "in", "label": "Text", "type": "text"}],
23
+ "outputs": [{"id": "out", "label": "Text", "type": "text"}],
24
+ "x": 60, "y": 320
25
+ }
26
+ ],
27
+ "operators": [
28
+ {
29
+ "id": "op_classify",
30
+ "label": "jev-classify",
31
+ "role": "operator",
32
+ "kind": "fn",
33
+ "fn": "jev-classify",
34
+ "inputs": [
35
+ {"id": "premise", "label": "Premise", "type": "text", "required": true},
36
+ {"id": "hypothesis", "label": "Hypothesis", "type": "text", "required": true}
37
+ ],
38
+ "outputs": [{"id": "out_0", "label": "Result", "type": "text", "output_index": 0}],
39
+ "x": 460, "y": 180
40
+ }
41
+ ],
42
+ "subjects": [
43
+ {
44
+ "id": "sub_result",
45
+ "label": "NLI Result",
46
+ "role": "subject",
47
+ "asset_type": "text",
48
+ "inputs": [{"id": "in", "label": "Text", "type": "text"}],
49
+ "outputs": [{"id": "out", "label": "Text", "type": "text"}],
50
+ "x": 840, "y": 200
51
+ }
52
+ ],
53
+ "edges": [
54
+ {
55
+ "id": "e1",
56
+ "from_node_id": "ref_premise", "from_port_id": "out",
57
+ "to_node_id": "op_classify", "to_port_id": "premise",
58
+ "type": "text"
59
+ },
60
+ {
61
+ "id": "e2",
62
+ "from_node_id": "ref_hypothesis", "from_port_id": "out",
63
+ "to_node_id": "op_classify", "to_port_id": "hypothesis",
64
+ "type": "text"
65
+ },
66
+ {
67
+ "id": "e3",
68
+ "from_node_id": "op_classify", "from_port_id": "out_0",
69
+ "to_node_id": "sub_result", "to_port_id": "in",
70
+ "type": "text"
71
+ }
72
+ ],
73
+ "view": {"default": "canvas"}
74
+ }