itsalloverig commited on
Commit
3f299a4
·
verified ·
1 Parent(s): 2000e33

Create MIKE v4 Indian legal triage demo

Browse files
Files changed (4) hide show
  1. README.md +27 -7
  2. __pycache__/app.cpython-312.pyc +0 -0
  3. app.py +198 -0
  4. requirements.txt +9 -0
README.md CHANGED
@@ -1,13 +1,33 @@
1
  ---
2
- title: MIKE Demo
3
- emoji: 👀
4
- colorFrom: red
5
- colorTo: purple
6
  sdk: gradio
7
- sdk_version: 6.19.0
8
- python_version: '3.13'
9
  app_file: app.py
10
  pinned: false
 
 
 
 
 
 
 
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: MIKE Indian Legal Triage
3
+ emoji: "⚖️"
4
+ colorFrom: indigo
5
+ colorTo: blue
6
  sdk: gradio
7
+ sdk_version: 5.49.1
 
8
  app_file: app.py
9
  pinned: false
10
+ license: llama4
11
+ suggested_hardware: a100-large
12
+ suggested_storage: medium
13
+ models:
14
+ - itsalloverig/MIKE
15
+ datasets:
16
+ - itsalloverig/adaption-indian-legal-triage-samples-v4
17
  ---
18
 
19
+ # MIKE Indian Legal Triage Demo
20
+
21
+ Interactive demonstration of the selected MIKE v4 controlled-fused LoRA
22
+ adapter. MIKE supports India-focused legal research triage and is not a
23
+ substitute for advice from a qualified legal professional.
24
+
25
+ - Model: https://huggingface.co/itsalloverig/MIKE
26
+ - Dataset: https://huggingface.co/datasets/itsalloverig/adaption-indian-legal-triage-samples-v4
27
+ - Adaption held-out pairwise score: 92.16%
28
+ - Separate Indian-law domain score: 65.66%
29
+
30
+ The Space requires GPU hardware and persistent storage because the Llama 4
31
+ Scout base is a large mixture-of-experts model. It deliberately does not fall
32
+ back to a different model when the V4 checkpoint cannot be loaded.
33
+
__pycache__/app.cpython-312.pyc ADDED
Binary file (8.41 kB). View file
 
app.py ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import threading
3
+ from typing import Any
4
+
5
+ import gradio as gr
6
+
7
+
8
+ MODEL_ID = "itsalloverig/MIKE"
9
+ BASE_MODEL_ID = "bnb-community/Llama-4-Scout-17B-16E-Instruct-bnb-4bit"
10
+ DATASET_ID = "itsalloverig/adaption-indian-legal-triage-samples-v4"
11
+
12
+ SYSTEM_PROMPT = """You are MIKE, an India-only English legal research-triage
13
+ assistant. Preserve source-bounded facts. Never invent statutes, section or
14
+ article numbers, cases, deadlines, forums, or outcomes. Cite a numbered
15
+ authority only when it is present in the supplied context. Cover both legacy
16
+ IPC, CrPC and Indian Evidence Act terminology and current BNS, BNSS and BSA
17
+ terminology when the source supports it. Separate facts, assumptions, missing
18
+ evidence, forum or remedy options, urgency, and next research steps. Frame all
19
+ outputs as legal research assistance, not legal advice."""
20
+
21
+ model: Any = None
22
+ processor: Any = None
23
+ load_error: str | None = None
24
+ load_state = "waiting_for_gpu"
25
+ load_lock = threading.Lock()
26
+
27
+
28
+ def gpu_available() -> bool:
29
+ try:
30
+ import torch
31
+
32
+ return torch.cuda.is_available()
33
+ except Exception:
34
+ return False
35
+
36
+
37
+ def load_model() -> None:
38
+ global model, processor, load_error, load_state
39
+ with load_lock:
40
+ if model is not None or load_state == "loading":
41
+ return
42
+ if not gpu_available():
43
+ load_state = "waiting_for_gpu"
44
+ return
45
+ try:
46
+ load_state = "loading"
47
+ import torch
48
+ from peft import PeftModel
49
+ from transformers import AutoProcessor, Llama4ForConditionalGeneration
50
+
51
+ processor = AutoProcessor.from_pretrained(MODEL_ID)
52
+ base = Llama4ForConditionalGeneration.from_pretrained(
53
+ BASE_MODEL_ID,
54
+ device_map="auto",
55
+ torch_dtype=torch.bfloat16,
56
+ low_cpu_mem_usage=True,
57
+ )
58
+ model = PeftModel.from_pretrained(base, MODEL_ID)
59
+ model.eval()
60
+ load_state = "ready"
61
+ except Exception as error:
62
+ load_error = f"{type(error).__name__}: {error}"
63
+ load_state = "failed"
64
+
65
+
66
+ def status_markdown() -> str:
67
+ labels = {
68
+ "waiting_for_gpu": "Waiting for GPU hardware",
69
+ "loading": "Loading Llama 4 Scout and the MIKE v4 adapter",
70
+ "ready": "MIKE v4 is ready",
71
+ "failed": "Model loading failed",
72
+ }
73
+ result = f"**Runtime:** {labels.get(load_state, load_state)}"
74
+ if load_error:
75
+ result += f"\n\n`{load_error}`"
76
+ return result
77
+
78
+
79
+ def generate_reply(
80
+ message: str,
81
+ history: list[dict[str, str]],
82
+ source_context: str,
83
+ max_new_tokens: int,
84
+ ) -> str:
85
+ if model is None:
86
+ load_model()
87
+ if model is None:
88
+ return (
89
+ "MIKE v4 is not loaded. This Space requires the configured GPU "
90
+ "hardware and persistent storage. No substitute model was used."
91
+ )
92
+
93
+ import torch
94
+
95
+ messages: list[dict[str, str]] = [{"role": "system", "content": SYSTEM_PROMPT}]
96
+ for item in history[-6:]:
97
+ role = item.get("role")
98
+ content = item.get("content")
99
+ if role in {"user", "assistant"} and isinstance(content, str):
100
+ messages.append({"role": role, "content": content})
101
+
102
+ user_content = message.strip()
103
+ if source_context.strip():
104
+ user_content += (
105
+ "\n\nSUPPLIED CONTEXT (cite only authorities explicitly present here):\n"
106
+ + source_context.strip()
107
+ )
108
+ messages.append({"role": "user", "content": user_content})
109
+
110
+ inputs = processor.apply_chat_template(
111
+ messages,
112
+ add_generation_prompt=True,
113
+ tokenize=True,
114
+ return_tensors="pt",
115
+ return_dict=True,
116
+ )
117
+ first_device = next(model.parameters()).device
118
+ inputs = {key: value.to(first_device) for key, value in inputs.items()}
119
+
120
+ with torch.inference_mode():
121
+ output = model.generate(
122
+ **inputs,
123
+ max_new_tokens=int(max_new_tokens),
124
+ do_sample=False,
125
+ repetition_penalty=1.05,
126
+ )
127
+ generated = output[0][inputs["input_ids"].shape[-1] :]
128
+ return processor.decode(generated, skip_special_tokens=True).strip()
129
+
130
+
131
+ if gpu_available():
132
+ threading.Thread(target=load_model, daemon=True).start()
133
+
134
+
135
+ CSS = """
136
+ .gradio-container {max-width: 1100px !important;}
137
+ .legal-note {border-left: 4px solid #4f46e5; padding-left: 12px;}
138
+ """
139
+
140
+ with gr.Blocks(css=CSS, title="MIKE Indian Legal Triage") as demo:
141
+ gr.Markdown(
142
+ """
143
+ # ⚖️ MIKE — Indian Legal Research Triage
144
+
145
+ Ask an India-focused legal research question. Add authoritative source
146
+ text when you want citation-aware analysis.
147
+
148
+ <div class="legal-note"><strong>Important:</strong> MIKE provides legal
149
+ research assistance, not legal advice. Verify outputs against current
150
+ official sources and a qualified Indian legal professional.</div>
151
+ """
152
+ )
153
+ runtime = gr.Markdown(value=status_markdown, every=10)
154
+ context = gr.Textbox(
155
+ label="Optional supplied legal context",
156
+ placeholder="Paste the relevant statute, order, contract excerpt, or case material.",
157
+ lines=6,
158
+ )
159
+ token_limit = gr.Slider(
160
+ minimum=128,
161
+ maximum=1024,
162
+ value=640,
163
+ step=64,
164
+ label="Maximum response tokens",
165
+ )
166
+ gr.ChatInterface(
167
+ fn=generate_reply,
168
+ additional_inputs=[context, token_limit],
169
+ chatbot=gr.Chatbot(height=520, type="messages"),
170
+ textbox=gr.Textbox(
171
+ placeholder="Describe the legal issue, relevant dates, documents, and desired research outcome.",
172
+ lines=3,
173
+ ),
174
+ examples=[
175
+ [
176
+ "A complaint concerns conduct spanning June and August 2024. Explain what facts determine whether IPC/CrPC or BNS/BNSS terminology applies.",
177
+ "",
178
+ 640,
179
+ ],
180
+ [
181
+ "Create a source-bounded document and evidence checklist for an employment termination dispute. Do not invent statutory sections.",
182
+ "",
183
+ 640,
184
+ ],
185
+ [
186
+ "Triage a consumer dispute involving a defective online purchase and identify missing facts, evidence, urgency, and research steps.",
187
+ "",
188
+ 640,
189
+ ],
190
+ ],
191
+ )
192
+ gr.Markdown(
193
+ f"Model: [{MODEL_ID}](https://huggingface.co/{MODEL_ID}) · "
194
+ f"Dataset: [{DATASET_ID}](https://huggingface.co/datasets/{DATASET_ID}) · "
195
+ "Adaption pairwise score: **92.16%** · Domain score: **65.66%**"
196
+ )
197
+
198
+ demo.queue(default_concurrency_limit=1).launch()
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ accelerate>=1.7.0
2
+ bitsandbytes>=0.45.5
3
+ gradio==5.49.1
4
+ huggingface_hub>=0.34.0
5
+ peft>=0.15.1
6
+ safetensors>=0.5.3
7
+ torch>=2.6.0
8
+ transformers>=4.51.3
9
+