Spaces:
Running
Running
Commit
·
532c782
1
Parent(s):
765d77b
changed summary logic
Browse filesFormer-commit-id: d509673b3e597bee08e193e8208ae263c3e35a33
- ' +1 -0
- 0.41.0 +19 -0
- 0.41.0' +0 -0
- ai_med_extract/__pycache__/app.cpython-311.pyc +0 -0
- ai_med_extract/agents/__pycache__/patient_summary_agent.cpython-311.pyc +0 -0
- ai_med_extract/api/__pycache__/routes.cpython-311.pyc +0 -0
- ai_med_extract/api/__pycache__/routes.cpython-311.pyc.REMOVED.git-id +1 -0
- ai_med_extract/api/routes.py +139 -64
- ai_med_extract/utils/__pycache__/model_loader_spaces.cpython-311.pyc +0 -0
- ai_med_extract/utils/__pycache__/openvino_summarizer_utils.cpython-311.pyc +0 -0
- ai_med_extract/utils/__pycache__/patient_summary_utils.cpython-311.pyc +0 -0
- ai_med_extract/utils/model_loader_spaces.py +22 -0
- ai_med_extract/utils/openvino_summarizer_utils.py +162 -0
- export_phi3_openvino.py +9 -0
- old_requirements.txt +165 -0
- ov_models/microsoft_Phi-3-mini-4k-instruct_ir/chat_template.jinja +8 -0
- ov_models/microsoft_Phi-3-mini-4k-instruct_ir/special_tokens_map.json +30 -0
- ov_models/microsoft_Phi-3-mini-4k-instruct_ir/tokenizer.json.REMOVED.git-id +1 -0
'
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
Unable to initialize device PRN
|
0.41.0
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Collecting bitsandbytes
|
2 |
+
Downloading bitsandbytes-0.47.0-py3-none-win_amd64.whl.metadata (11 kB)
|
3 |
+
Requirement already satisfied: torch<3,>=2.2 in c:\users\sachin\appdata\local\programs\python\python311\lib\site-packages (from bitsandbytes) (2.3.0)
|
4 |
+
Requirement already satisfied: numpy>=1.17 in c:\users\sachin\appdata\local\programs\python\python311\lib\site-packages (from bitsandbytes) (1.24.3)
|
5 |
+
Requirement already satisfied: filelock in c:\users\sachin\appdata\local\programs\python\python311\lib\site-packages (from torch<3,>=2.2->bitsandbytes) (3.18.0)
|
6 |
+
Requirement already satisfied: typing-extensions>=4.8.0 in c:\users\sachin\appdata\local\programs\python\python311\lib\site-packages (from torch<3,>=2.2->bitsandbytes) (4.14.1)
|
7 |
+
Requirement already satisfied: sympy in c:\users\sachin\appdata\local\programs\python\python311\lib\site-packages (from torch<3,>=2.2->bitsandbytes) (1.14.0)
|
8 |
+
Requirement already satisfied: networkx in c:\users\sachin\appdata\local\programs\python\python311\lib\site-packages (from torch<3,>=2.2->bitsandbytes) (3.5)
|
9 |
+
Requirement already satisfied: jinja2 in c:\users\sachin\appdata\local\programs\python\python311\lib\site-packages (from torch<3,>=2.2->bitsandbytes) (3.1.6)
|
10 |
+
Requirement already satisfied: fsspec in c:\users\sachin\appdata\local\programs\python\python311\lib\site-packages (from torch<3,>=2.2->bitsandbytes) (2025.7.0)
|
11 |
+
Requirement already satisfied: mkl<=2021.4.0,>=2021.1.1 in c:\users\sachin\appdata\local\programs\python\python311\lib\site-packages (from torch<3,>=2.2->bitsandbytes) (2021.4.0)
|
12 |
+
Requirement already satisfied: intel-openmp==2021.* in c:\users\sachin\appdata\local\programs\python\python311\lib\site-packages (from mkl<=2021.4.0,>=2021.1.1->torch<3,>=2.2->bitsandbytes) (2021.4.0)
|
13 |
+
Requirement already satisfied: tbb==2021.* in c:\users\sachin\appdata\local\programs\python\python311\lib\site-packages (from mkl<=2021.4.0,>=2021.1.1->torch<3,>=2.2->bitsandbytes) (2021.13.1)
|
14 |
+
Requirement already satisfied: MarkupSafe>=2.0 in c:\users\sachin\appdata\local\programs\python\python311\lib\site-packages (from jinja2->torch<3,>=2.2->bitsandbytes) (2.1.5)
|
15 |
+
Requirement already satisfied: mpmath<1.4,>=1.1.0 in c:\users\sachin\appdata\local\programs\python\python311\lib\site-packages (from sympy->torch<3,>=2.2->bitsandbytes) (1.3.0)
|
16 |
+
Downloading bitsandbytes-0.47.0-py3-none-win_amd64.whl (60.7 MB)
|
17 |
+
---------------------------------------- 60.7/60.7 MB 12.1 MB/s 0:00:05
|
18 |
+
Installing collected packages: bitsandbytes
|
19 |
+
Successfully installed bitsandbytes-0.47.0
|
0.41.0'
ADDED
File without changes
|
ai_med_extract/__pycache__/app.cpython-311.pyc
CHANGED
Binary files a/ai_med_extract/__pycache__/app.cpython-311.pyc and b/ai_med_extract/__pycache__/app.cpython-311.pyc differ
|
|
ai_med_extract/agents/__pycache__/patient_summary_agent.cpython-311.pyc
CHANGED
Binary files a/ai_med_extract/agents/__pycache__/patient_summary_agent.cpython-311.pyc and b/ai_med_extract/agents/__pycache__/patient_summary_agent.cpython-311.pyc differ
|
|
ai_med_extract/api/__pycache__/routes.cpython-311.pyc
DELETED
Binary file (45.2 kB)
|
|
ai_med_extract/api/__pycache__/routes.cpython-311.pyc.REMOVED.git-id
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
2129106af05cccbba389f4e2c6915fad2060edfd
|
ai_med_extract/api/routes.py
CHANGED
@@ -260,6 +260,79 @@ def get_summarizer_pipeline(summarizer_model_type, summarizer_model_name):
|
|
260 |
|
261 |
|
262 |
def register_routes(app, agents):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
263 |
# Configure upload directory based on environment
|
264 |
import os
|
265 |
|
@@ -902,16 +975,25 @@ def register_routes(app, agents):
|
|
902 |
|
903 |
@app.route('/generate_patient_summary', methods=['POST'])
|
904 |
def generate_patient_summary():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
905 |
try:
|
906 |
data = request.get_json()
|
907 |
patientid = data.get("patientid")
|
908 |
token = data.get("token")
|
909 |
key = data.get("key")
|
910 |
-
|
911 |
-
|
912 |
-
if not model_name or str(model_name).strip().lower() in {"", "none", "null"}:
|
913 |
-
model_name = "falconsai/medical_summarization"
|
914 |
-
|
915 |
if not patientid or not token or not key:
|
916 |
return jsonify({"error": "Missing required fields: patientid, token, or key"}), 400
|
917 |
|
@@ -920,9 +1002,8 @@ def register_routes(app, agents):
|
|
920 |
"Authorization": f"Bearer {token}",
|
921 |
"x-api-key": key,
|
922 |
"Content-Type": "application/json",
|
923 |
-
|
924 |
body = json.dumps({"patientid": patientid})
|
925 |
-
|
926 |
response = requests.post(api_url, data=body, headers=headers, timeout=30)
|
927 |
if response.status_code != 200:
|
928 |
return jsonify({
|
@@ -930,77 +1011,71 @@ def register_routes(app, agents):
|
|
930 |
"status": response.status_code,
|
931 |
"message": response.text
|
932 |
}), 502
|
933 |
-
|
934 |
-
# Be tolerant to any response format: JSON, text, key-values, etc.
|
935 |
try:
|
936 |
api_data = response.json()
|
937 |
except ValueError:
|
938 |
api_data = response.text
|
939 |
-
|
940 |
-
# If dict, prefer nested 'result'; otherwise pass through
|
941 |
if isinstance(api_data, dict):
|
942 |
-
|
943 |
else:
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
# Optional: return flattened for debugging
|
990 |
-
flattened = flatten_to_string_list(cleaned_data)
|
991 |
-
|
992 |
return jsonify({
|
993 |
-
"summary":
|
994 |
-
"
|
|
|
|
|
995 |
}), 200
|
996 |
-
|
997 |
except requests.exceptions.Timeout:
|
998 |
return jsonify({"error": "Request to EHR API timed out"}), 504
|
999 |
except requests.exceptions.RequestException as e:
|
1000 |
return jsonify({"error": f"Network error: {str(e)}"}), 503
|
1001 |
except Exception as e:
|
1002 |
logger.error(f"Unexpected error: {str(e)}", exc_info=True)
|
1003 |
-
return jsonify({"error": f"Internal server error: {str(e)}"}), 500
|
1004 |
|
1005 |
@app.route("/")
|
1006 |
def home():
|
|
|
260 |
|
261 |
|
262 |
def register_routes(app, agents):
|
263 |
+
from ai_med_extract.utils.openvino_summarizer_utils import (
|
264 |
+
parse_ehr_chartsummarydtl, visits_sorted, compute_deltas, build_compact_baseline, delta_to_text, build_main_prompt, validate_and_compare_summaries
|
265 |
+
)
|
266 |
+
import threading
|
267 |
+
patient_summary_state = {}
|
268 |
+
state_lock = threading.Lock()
|
269 |
+
|
270 |
+
@app.route('/api/patient_summary_openvino', methods=['POST'])
|
271 |
+
def patient_summary_openvino():
|
272 |
+
"""
|
273 |
+
Generate a patient summary using OpenVINO-style prompt, delta, and validation logic.
|
274 |
+
Accepts EHR API response JSON (or just chartsummarydtl) and returns summary and validation.
|
275 |
+
"""
|
276 |
+
try:
|
277 |
+
data = request.get_json()
|
278 |
+
ehr_result = data.get("result") or data
|
279 |
+
chartsummarydtl = ehr_result.get("chartsummarydtl") if isinstance(ehr_result, dict) else None
|
280 |
+
if not chartsummarydtl:
|
281 |
+
return jsonify({"error": "Missing chartsummarydtl in input"}), 400
|
282 |
+
|
283 |
+
# Normalize visits
|
284 |
+
visits = parse_ehr_chartsummarydtl(chartsummarydtl)
|
285 |
+
patient_id = ehr_result.get("patientid") or ehr_result.get("patientnumber") or "default"
|
286 |
+
|
287 |
+
# Track state per patient (in-memory, thread-safe)
|
288 |
+
with state_lock:
|
289 |
+
state = patient_summary_state.setdefault(patient_id, {"visits": [], "last_summary": ""})
|
290 |
+
old_visits = state["visits"]
|
291 |
+
old_summary = state["last_summary"]
|
292 |
+
|
293 |
+
# Compute deltas and prompt
|
294 |
+
delta = compute_deltas(old_visits, visits)
|
295 |
+
all_visits = visits_sorted(old_visits + visits)
|
296 |
+
baseline = build_compact_baseline(all_visits)
|
297 |
+
delta_text = delta_to_text(delta)
|
298 |
+
prompt = build_main_prompt(old_summary, baseline, delta_text)
|
299 |
+
|
300 |
+
# Model selection logic (model_name, model_type)
|
301 |
+
model_name = data.get("model_name") or "microsoft/Phi-3-mini-4k-instruct"
|
302 |
+
model_type = data.get("model_type") or "text-generation"
|
303 |
+
# Use existing model loader abstraction
|
304 |
+
if model_type == "text-generation":
|
305 |
+
loader = agents.get("medical_data_extractor")
|
306 |
+
else:
|
307 |
+
loader = agents.get("summarizer")
|
308 |
+
pipeline = loader.model_loader.load() if hasattr(loader, "model_loader") else None
|
309 |
+
if not pipeline:
|
310 |
+
return jsonify({"error": "Model pipeline not available"}), 500
|
311 |
+
|
312 |
+
# Run inference
|
313 |
+
import torch
|
314 |
+
torch.set_num_threads(2)
|
315 |
+
inputs = pipeline.tokenizer([prompt], return_tensors="pt")
|
316 |
+
outputs = pipeline.model.generate(**inputs, max_new_tokens=400, do_sample=False, pad_token_id=pipeline.tokenizer.eos_token_id or 32000)
|
317 |
+
text = pipeline.tokenizer.decode(outputs[0], skip_special_tokens=True)
|
318 |
+
new_summary = text.split("Now generate the complete, updated clinical summary with all four sections:")[-1].strip()
|
319 |
+
|
320 |
+
# Update state
|
321 |
+
with state_lock:
|
322 |
+
state["visits"] = all_visits
|
323 |
+
state["last_summary"] = new_summary
|
324 |
+
|
325 |
+
# Validation
|
326 |
+
validation_report = validate_and_compare_summaries(old_summary, new_summary, "Update")
|
327 |
+
|
328 |
+
return jsonify({
|
329 |
+
"summary": new_summary,
|
330 |
+
"validation": validation_report,
|
331 |
+
"baseline": baseline,
|
332 |
+
"delta": delta_text
|
333 |
+
}), 200
|
334 |
+
except Exception as e:
|
335 |
+
return jsonify({"error": f"Failed to generate summary: {str(e)}"}), 500
|
336 |
# Configure upload directory based on environment
|
337 |
import os
|
338 |
|
|
|
975 |
|
976 |
@app.route('/generate_patient_summary', methods=['POST'])
|
977 |
def generate_patient_summary():
|
978 |
+
"""
|
979 |
+
Enhanced: Uses OpenVINO-style prompt, delta, and validation logic for patient summary generation.
|
980 |
+
"""
|
981 |
+
from ai_med_extract.utils.openvino_summarizer_utils import (
|
982 |
+
parse_ehr_chartsummarydtl, visits_sorted, compute_deltas, build_compact_baseline, delta_to_text, build_main_prompt, validate_and_compare_summaries
|
983 |
+
)
|
984 |
+
import threading
|
985 |
+
if not hasattr(generate_patient_summary, "state"):
|
986 |
+
generate_patient_summary.state = {}
|
987 |
+
generate_patient_summary.lock = threading.Lock()
|
988 |
+
state = generate_patient_summary.state
|
989 |
+
state_lock = generate_patient_summary.lock
|
990 |
try:
|
991 |
data = request.get_json()
|
992 |
patientid = data.get("patientid")
|
993 |
token = data.get("token")
|
994 |
key = data.get("key")
|
995 |
+
model_name = data.get("patient_summarizer_model_name") or "falconsai/medical_summarization"
|
996 |
+
model_type = data.get("patient_summarizer_model_type") or data.get("model_type") or "summarization"
|
|
|
|
|
|
|
997 |
if not patientid or not token or not key:
|
998 |
return jsonify({"error": "Missing required fields: patientid, token, or key"}), 400
|
999 |
|
|
|
1002 |
"Authorization": f"Bearer {token}",
|
1003 |
"x-api-key": key,
|
1004 |
"Content-Type": "application/json",
|
1005 |
+
}
|
1006 |
body = json.dumps({"patientid": patientid})
|
|
|
1007 |
response = requests.post(api_url, data=body, headers=headers, timeout=30)
|
1008 |
if response.status_code != 200:
|
1009 |
return jsonify({
|
|
|
1011 |
"status": response.status_code,
|
1012 |
"message": response.text
|
1013 |
}), 502
|
|
|
|
|
1014 |
try:
|
1015 |
api_data = response.json()
|
1016 |
except ValueError:
|
1017 |
api_data = response.text
|
|
|
|
|
1018 |
if isinstance(api_data, dict):
|
1019 |
+
ehr_result = api_data.get("result") or api_data
|
1020 |
else:
|
1021 |
+
ehr_result = api_data
|
1022 |
+
chartsummarydtl = ehr_result.get("chartsummarydtl") if isinstance(ehr_result, dict) else None
|
1023 |
+
if not chartsummarydtl:
|
1024 |
+
return jsonify({"error": "Missing chartsummarydtl in EHR response"}), 500
|
1025 |
+
visits = parse_ehr_chartsummarydtl(chartsummarydtl)
|
1026 |
+
# Per-patient state (in-memory)
|
1027 |
+
with state_lock:
|
1028 |
+
patient_state = state.setdefault(patientid, {"visits": [], "last_summary": ""})
|
1029 |
+
old_visits = patient_state["visits"]
|
1030 |
+
old_summary = patient_state["last_summary"]
|
1031 |
+
delta = compute_deltas(old_visits, visits)
|
1032 |
+
all_visits = visits_sorted(old_visits + visits)
|
1033 |
+
baseline = build_compact_baseline(all_visits)
|
1034 |
+
delta_text = delta_to_text(delta)
|
1035 |
+
prompt = build_main_prompt(old_summary, baseline, delta_text)
|
1036 |
+
# Model selection logic (supporting OpenVINO and HuggingFace)
|
1037 |
+
pipeline = None
|
1038 |
+
loader = None
|
1039 |
+
import torch
|
1040 |
+
torch.set_num_threads(2)
|
1041 |
+
if model_type in {"text-generation", "causal-openvino"}:
|
1042 |
+
# Try to use an existing loader if available
|
1043 |
+
loader = agents.get("medical_data_extractor")
|
1044 |
+
if not loader or getattr(loader, 'model_name', None) != model_name:
|
1045 |
+
# Dynamically create OpenVINO loader if needed
|
1046 |
+
from ai_med_extract.utils.model_loader_spaces import get_openvino_pipeline
|
1047 |
+
try:
|
1048 |
+
pipeline = get_openvino_pipeline(model_name)
|
1049 |
+
except Exception as e:
|
1050 |
+
return jsonify({"error": f"Failed to load OpenVINO pipeline: {str(e)}"}), 500
|
1051 |
+
elif model_type == "summarization":
|
1052 |
+
loader = agents.get("summarizer")
|
1053 |
+
# Use loader if available
|
1054 |
+
if not pipeline and loader and hasattr(loader, "model_loader"):
|
1055 |
+
pipeline = loader.model_loader.load()
|
1056 |
+
if not pipeline:
|
1057 |
+
return jsonify({"error": "Model pipeline not available"}), 500
|
1058 |
+
inputs = pipeline.tokenizer([prompt], return_tensors="pt")
|
1059 |
+
outputs = pipeline.model.generate(**inputs, max_new_tokens=400, do_sample=False, pad_token_id=pipeline.tokenizer.eos_token_id or 32000)
|
1060 |
+
text = pipeline.tokenizer.decode(outputs[0], skip_special_tokens=True)
|
1061 |
+
new_summary = text.split("Now generate the complete, updated clinical summary with all four sections:")[-1].strip()
|
1062 |
+
with state_lock:
|
1063 |
+
patient_state["visits"] = all_visits
|
1064 |
+
patient_state["last_summary"] = new_summary
|
1065 |
+
validation_report = validate_and_compare_summaries(old_summary, new_summary, "Update")
|
|
|
|
|
|
|
1066 |
return jsonify({
|
1067 |
+
"summary": new_summary,
|
1068 |
+
"validation": validation_report,
|
1069 |
+
"baseline": baseline,
|
1070 |
+
"delta": delta_text
|
1071 |
}), 200
|
|
|
1072 |
except requests.exceptions.Timeout:
|
1073 |
return jsonify({"error": "Request to EHR API timed out"}), 504
|
1074 |
except requests.exceptions.RequestException as e:
|
1075 |
return jsonify({"error": f"Network error: {str(e)}"}), 503
|
1076 |
except Exception as e:
|
1077 |
logger.error(f"Unexpected error: {str(e)}", exc_info=True)
|
1078 |
+
return jsonify({"error": f"Internal server error: {str(e)}"}), 500
|
1079 |
|
1080 |
@app.route("/")
|
1081 |
def home():
|
ai_med_extract/utils/__pycache__/model_loader_spaces.cpython-311.pyc
ADDED
Binary file (1.58 kB). View file
|
|
ai_med_extract/utils/__pycache__/openvino_summarizer_utils.cpython-311.pyc
ADDED
Binary file (12.8 kB). View file
|
|
ai_med_extract/utils/__pycache__/patient_summary_utils.cpython-311.pyc
CHANGED
Binary files a/ai_med_extract/utils/__pycache__/patient_summary_utils.cpython-311.pyc and b/ai_med_extract/utils/__pycache__/patient_summary_utils.cpython-311.pyc differ
|
|
ai_med_extract/utils/model_loader_spaces.py
CHANGED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torch
|
2 |
+
from transformers import AutoTokenizer
|
3 |
+
from optimum.intel.openvino import OVModelForCausalLM
|
4 |
+
|
5 |
+
class OpenVinoPipeline:
|
6 |
+
def __init__(self, model, tokenizer):
|
7 |
+
self.model = model
|
8 |
+
self.tokenizer = tokenizer
|
9 |
+
|
10 |
+
def get_openvino_pipeline(model_name: str):
|
11 |
+
"""
|
12 |
+
Loads an OpenVINO CausalLM pipeline for the given model name or IR directory.
|
13 |
+
"""
|
14 |
+
# If model_name is a directory, try to load IR from there; else, download and export
|
15 |
+
import os
|
16 |
+
if os.path.isdir(model_name):
|
17 |
+
model = OVModelForCausalLM.from_pretrained(model_name, compile=True, device="CPU")
|
18 |
+
tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=True)
|
19 |
+
else:
|
20 |
+
model = OVModelForCausalLM.from_pretrained(model_name, export=True, compile=True, device="CPU")
|
21 |
+
tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=True)
|
22 |
+
return OpenVinoPipeline(model, tokenizer)
|
ai_med_extract/utils/openvino_summarizer_utils.py
ADDED
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import json
|
3 |
+
import re
|
4 |
+
import textwrap
|
5 |
+
import difflib
|
6 |
+
import logging
|
7 |
+
from copy import deepcopy
|
8 |
+
|
9 |
+
def parse_ehr_chartsummarydtl(chartsummarydtl):
|
10 |
+
"""
|
11 |
+
Converts EHR API chartsummarydtl list to the internal visit format expected by the summarizer.
|
12 |
+
"""
|
13 |
+
visits = []
|
14 |
+
for entry in chartsummarydtl:
|
15 |
+
visit = {}
|
16 |
+
# Parse chartdate
|
17 |
+
visit["chartdate"] = entry.get("chartdate", "")[:10] # YYYY-MM-DD
|
18 |
+
# Parse vitals
|
19 |
+
vitals_dict = {}
|
20 |
+
weight = None
|
21 |
+
if "vitals" in entry:
|
22 |
+
for v in entry["vitals"]:
|
23 |
+
if ":" in v:
|
24 |
+
k, val = v.split(":", 1)
|
25 |
+
k = k.strip()
|
26 |
+
val = val.strip()
|
27 |
+
if k.lower().startswith("weight"):
|
28 |
+
weight = val
|
29 |
+
else:
|
30 |
+
vitals_dict[k] = val
|
31 |
+
visit["vitals"] = vitals_dict
|
32 |
+
if weight:
|
33 |
+
visit["weight"] = weight
|
34 |
+
# Allergies
|
35 |
+
if "allergies" in entry:
|
36 |
+
visit["allergies"] = entry["allergies"]
|
37 |
+
# Diagnosis
|
38 |
+
if "diagnosis" in entry:
|
39 |
+
visit["diagnosis"] = entry["diagnosis"]
|
40 |
+
# Medications
|
41 |
+
if "medications" in entry:
|
42 |
+
visit["medications"] = entry["medications"]
|
43 |
+
# Labtests
|
44 |
+
labtests = []
|
45 |
+
if "labtests" in entry:
|
46 |
+
for l in entry["labtests"]:
|
47 |
+
name = l.get("name", "")
|
48 |
+
value = l.get("value", "")
|
49 |
+
if name or value:
|
50 |
+
labtests.append({"name": name, "value": value})
|
51 |
+
visit["labtests"] = labtests
|
52 |
+
# Radiology orders
|
53 |
+
if "radiologyorders" in entry:
|
54 |
+
visit["radiologyorders"] = [r.get("name", "") for r in entry["radiologyorders"] if r.get("name")]
|
55 |
+
visits.append(visit)
|
56 |
+
return visits
|
57 |
+
|
58 |
+
# ========== PROMPT, DELTA, VALIDATION LOGIC (adapted from your script) =============
|
59 |
+
ALIASES = {("vitals","Bp(sys)(mmHg)"): [("vitals","Bp(sys)(mmHg)"), ("vitals","Bp_sys"), ("vitals","SBP")],
|
60 |
+
("vitals","Bp(dia)(mmHg)"): [("vitals","Bp(dia)(mmHg)"), ("vitals","Bp_dia"), ("vitals","DBP")],
|
61 |
+
("labtests","HbA1c (%)"): [("labtests","HbA1c (%)"), ("labtests","HbA1c")],
|
62 |
+
("labtests","Creatinine Ratio"): [("labtests","Creatinine Ratio"), ("labtests","Creatinine")],
|
63 |
+
}
|
64 |
+
def visits_sorted(v):
|
65 |
+
return sorted(v, key=lambda v: v.get("chartdate", ""))
|
66 |
+
def to_float(val):
|
67 |
+
try:
|
68 |
+
s = str(val); m = re.findall(r"-?\d+\.?\d*", s)
|
69 |
+
return float(m[0]) if m else None
|
70 |
+
except: return None
|
71 |
+
def _latest_value_exact(visits, key_path):
|
72 |
+
v_sorted = visits_sorted(visits)
|
73 |
+
if not v_sorted: return None
|
74 |
+
if key_path[0] == "labtests":
|
75 |
+
for v in reversed(v_sorted):
|
76 |
+
for lab in v.get("labtests", []):
|
77 |
+
if lab.get("name") == key_path[1]: return lab.get("value")
|
78 |
+
return None
|
79 |
+
for v in reversed(v_sorted):
|
80 |
+
cur = v; ok = True
|
81 |
+
for k in key_path:
|
82 |
+
if isinstance(cur, dict) and k in cur: cur = cur[k]
|
83 |
+
else: ok=False; break
|
84 |
+
if ok: return cur
|
85 |
+
return None
|
86 |
+
def latest_value(visits, key_path):
|
87 |
+
for kp in ALIASES.get(key_path, [key_path]):
|
88 |
+
val = _latest_value_exact(visits, kp)
|
89 |
+
if val is not None: return val
|
90 |
+
return None
|
91 |
+
def active_set(visits, field):
|
92 |
+
s = set()
|
93 |
+
for v in visits: s.update(v.get(field, []))
|
94 |
+
return s
|
95 |
+
def _fmt(x, spec=None):
|
96 |
+
if x is None: return "N/A"
|
97 |
+
try: return format(x, spec) if spec else str(x)
|
98 |
+
except Exception: return str(x)
|
99 |
+
def compute_deltas(old_visits, new_visits):
|
100 |
+
prev_all = old_visits
|
101 |
+
curr_all = old_visits + new_visits
|
102 |
+
def get_val(visits, path): return to_float(latest_value(visits, path))
|
103 |
+
w_p, w_c = get_val(prev_all, ("weight",)), get_val(curr_all, ("weight",))
|
104 |
+
s_p, s_c = get_val(prev_all, ("vitals","Bp(sys)(mmHg)")), get_val(curr_all, ("vitals","Bp(sys)(mmHg)"))
|
105 |
+
d_p, d_c = get_val(prev_all, ("vitals","Bp(dia)(mmHg)")), get_val(curr_all, ("vitals","Bp(dia)(mmHg)"))
|
106 |
+
h_p, h_c = get_val(prev_all, ("labtests","HbA1c (%)")), get_val(curr_all, ("labtests","HbA1c (%)"))
|
107 |
+
c_p, c_c = get_val(prev_all, ("labtests","Creatinine Ratio")), get_val(curr_all, ("labtests","Creatinine Ratio"))
|
108 |
+
return {
|
109 |
+
"added_dx": sorted(list(active_set(curr_all,"diagnosis") - active_set(prev_all,"diagnosis"))),
|
110 |
+
"started_meds": sorted(list(active_set(curr_all,"medications") - active_set(prev_all,"medications"))),
|
111 |
+
"stopped_meds": sorted(list(active_set(prev_all,"medications") - active_set(curr_all,"medications"))),
|
112 |
+
"weight": {"prev": w_p, "curr": w_c, "delta": (w_c - w_p) if w_p and w_c else None},
|
113 |
+
"bp_sys": {"prev": s_p, "curr": s_c, "delta": (s_c - s_p) if s_p and s_c else None},
|
114 |
+
"bp_dia": {"prev": d_p, "curr": d_c, "delta": (d_c - d_p) if d_p and d_c else None},
|
115 |
+
"hba1c": {"prev": h_p, "curr": h_c, "delta": (h_c - h_p) if h_p and h_c else None},
|
116 |
+
"cratio": {"prev": c_p, "curr": c_c, "delta": (c_c - c_p) if c_p and c_c else None},
|
117 |
+
}
|
118 |
+
def build_compact_baseline(all_visits):
|
119 |
+
return f"Latest date: {latest_value(all_visits,('chartdate',)) or 'N/A'}\n" \
|
120 |
+
f"Active Diagnoses: {', '.join(sorted(active_set(all_visits,'diagnosis'))) or 'N/A'}\n" \
|
121 |
+
f"Active Medications: {', '.join(sorted(active_set(all_visits,'medications'))) or 'N/A'}\n" \
|
122 |
+
f"Latest Vitals: Bp: {latest_value(all_visits,('vitals','Bp(sys)(mmHg)'))}/{latest_value(all_visits,('vitals','Bp(dia)(mmHg)'))} mmHg, Weight: {latest_value(all_visits,('weight',))}\n" \
|
123 |
+
f"Latest Labs: HbA1c: {latest_value(all_visits,('labtests','HbA1c (%)'))}%, Creatinine: {latest_value(all_visits,('labtests','Creatinine Ratio'))}"
|
124 |
+
def delta_to_text(delta):
|
125 |
+
L = []
|
126 |
+
if delta["added_dx"]: L.append("New Diagnoses: " + ", ".join(delta["added_dx"]))
|
127 |
+
if delta["started_meds"]: L.append("Medications Started: " + ", ".join(delta["started_meds"]))
|
128 |
+
if delta["stopped_meds"]: L.append("Medications Stopped: " + ", ".join(delta["stopped_meds"]))
|
129 |
+
w = delta["weight"]; L.append(f"Weight: {_fmt(w['prev'])} -> {_fmt(w['curr'])} (Δ {_fmt(w['delta'], '+.1f')})")
|
130 |
+
s, d = delta["bp_sys"], delta["bp_dia"]; L.append(f"BP: {_fmt(s['curr'])}/{_fmt(d['curr'])} (Δs {_fmt(s['delta'], '+.0f')}, Δd {_fmt(d['delta'], '+.0f')})")
|
131 |
+
h, c = delta["hba1c"], delta["cratio"]; L.append(f"HbA1c: {_fmt(h['prev'])} -> {_fmt(h['curr'])} (Δ {_fmt(h['delta'], '.1f')})"); L.append(f"Creatinine: {_fmt(c['prev'])} -> {_fmt(c['curr'])} (Δ {_fmt(c['delta'], '.1f')})")
|
132 |
+
return "\n".join(L)
|
133 |
+
def build_main_prompt(prev_summary, baseline, delta_text):
|
134 |
+
prev_excerpt = textwrap.shorten(prev_summary, width=700, placeholder="...") if prev_summary else "None"
|
135 |
+
return (
|
136 |
+
"You are an expert clinical AI assistant. Your task is to update a patient summary.\n"
|
137 |
+
"Use the PRIOR SUMMARY for context. The STRUCTURED BASELINE and DELTAS are the absolute ground truth.\n"
|
138 |
+
"Produce a concise, physician-ready update. Never omit critical new information from the deltas.\n\n"
|
139 |
+
"The summary MUST have four sections:\n"
|
140 |
+
"1) Clinical Assessment\n"
|
141 |
+
"2) Key Trends & Changes\n"
|
142 |
+
"3) Plan & Suggested Actions\n"
|
143 |
+
"4) Direct Guidance for Physician\n\n"
|
144 |
+
f"PRIOR SUMMARY (context):\n{prev_excerpt}\n\n"
|
145 |
+
f"STRUCTURED BASELINE (authoritative):\n{baseline}\n\n"
|
146 |
+
f"STRUCTURED DELTAS (authoritative):\n{delta_text}\n\n"
|
147 |
+
"Now generate the complete, updated clinical summary with all four sections:"
|
148 |
+
)
|
149 |
+
def validate_and_compare_summaries(old_summary, new_summary, update_name=""):
|
150 |
+
report = f"### Validation Report for {update_name}\n"
|
151 |
+
report += "This report validates that the updated summary incorporates new information correctly.\n"
|
152 |
+
report += "\n**Unified Diff (Line-by-Line Changes):**\n"
|
153 |
+
diff = difflib.unified_diff(
|
154 |
+
old_summary.splitlines(), new_summary.splitlines(),
|
155 |
+
fromfile='Previous Summary', tofile='Current Summary', lineterm=''
|
156 |
+
)
|
157 |
+
diff_text = "\n".join(list(diff))
|
158 |
+
if not diff_text:
|
159 |
+
report += "No textual differences found between summaries.\n"
|
160 |
+
else:
|
161 |
+
report += "```diff\n" + diff_text + "\n```\n"
|
162 |
+
return report
|
export_phi3_openvino.py
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from optimum.intel.openvino import OVModelForCausalLM
|
2 |
+
from transformers import AutoTokenizer
|
3 |
+
|
4 |
+
model_id = "microsoft/Phi-3-mini-4k-instruct"
|
5 |
+
export_dir = "ov_models/microsoft_Phi-3-mini-4k-instruct_ir"
|
6 |
+
|
7 |
+
tokenizer = AutoTokenizer.from_pretrained(model_id, library_name="transformers")
|
8 |
+
model = OVModelForCausalLM.from_pretrained(model_id, export=True, save_dir=export_dir)
|
9 |
+
tokenizer.save_pretrained(export_dir)
|
old_requirements.txt
ADDED
@@ -0,0 +1,165 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
about-time==4.2.1
|
2 |
+
accelerate==0.25.0
|
3 |
+
aiofiles==23.2.1
|
4 |
+
aiohappyeyeballs==2.6.1
|
5 |
+
aiohttp==3.12.15
|
6 |
+
aiosignal==1.4.0
|
7 |
+
alive-progress==3.3.0
|
8 |
+
altair==5.5.0
|
9 |
+
annotated-types==0.7.0
|
10 |
+
anyio==4.10.0
|
11 |
+
attrs==25.3.0
|
12 |
+
autograd==1.8.0
|
13 |
+
bitsandbytes==0.47.0
|
14 |
+
blinker==1.9.0
|
15 |
+
blis==0.7.11
|
16 |
+
catalogue==2.0.10
|
17 |
+
certifi==2025.8.3
|
18 |
+
cffi==1.17.1
|
19 |
+
charset-normalizer==3.4.3
|
20 |
+
click==8.2.1
|
21 |
+
cloudpathlib==0.16.0
|
22 |
+
cma==4.3.0
|
23 |
+
colorama==0.4.6
|
24 |
+
confection==0.1.5
|
25 |
+
contourpy==1.3.2
|
26 |
+
cryptography==45.0.6
|
27 |
+
cycler==0.12.1
|
28 |
+
cymem==2.0.11
|
29 |
+
datasets==4.0.0
|
30 |
+
Deprecated==1.2.18
|
31 |
+
dill==0.3.8
|
32 |
+
einops==0.7.0
|
33 |
+
en-core-web-sm @ https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.7.1/en_core_web_sm-3.7.1-py3-none-any.whl#sha256=86cc141f63942d4b2c5fcee06630fd6f904788d2f0ab005cce45aadb8fb73889
|
34 |
+
fastapi==0.116.1
|
35 |
+
ffmpy==0.6.1
|
36 |
+
filelock==3.18.0
|
37 |
+
Flask==3.1.0
|
38 |
+
flask-cors==5.0.1
|
39 |
+
fonttools==4.59.0
|
40 |
+
frozenlist==1.7.0
|
41 |
+
fsspec==2025.3.0
|
42 |
+
gradio==4.13.0
|
43 |
+
gradio_client==0.8.0
|
44 |
+
graphemeu==0.7.2
|
45 |
+
gunicorn==21.2.0
|
46 |
+
h11==0.16.0
|
47 |
+
httpcore==1.0.9
|
48 |
+
httpx==0.28.1
|
49 |
+
huggingface-hub==0.34.4
|
50 |
+
idna==3.10
|
51 |
+
importlib_resources==6.5.2
|
52 |
+
intel-openmp==2021.4.0
|
53 |
+
itsdangerous==2.2.0
|
54 |
+
Jinja2==3.1.6
|
55 |
+
joblib==1.5.1
|
56 |
+
jsonschema==4.25.0
|
57 |
+
jsonschema-specifications==2025.4.1
|
58 |
+
kiwisolver==1.4.9
|
59 |
+
langcodes==3.5.0
|
60 |
+
language_data==1.3.0
|
61 |
+
llvmlite==0.44.0
|
62 |
+
lxml==6.0.0
|
63 |
+
marisa-trie==1.2.1
|
64 |
+
markdown-it-py==4.0.0
|
65 |
+
MarkupSafe==2.1.5
|
66 |
+
matplotlib==3.10.5
|
67 |
+
mdurl==0.1.2
|
68 |
+
mkl==2021.4.0
|
69 |
+
more-itertools==10.7.0
|
70 |
+
mpmath==1.3.0
|
71 |
+
multidict==6.6.4
|
72 |
+
multiprocess==0.70.16
|
73 |
+
murmurhash==1.0.13
|
74 |
+
narwhals==2.1.1
|
75 |
+
natsort==8.4.0
|
76 |
+
networkx==3.4.2
|
77 |
+
ninja==1.11.1.4
|
78 |
+
nltk==3.8.1
|
79 |
+
nncf==2.17.0
|
80 |
+
numba==0.61.2
|
81 |
+
numpy==1.24.3
|
82 |
+
onnx==1.18.0
|
83 |
+
openai-whisper==20231117
|
84 |
+
opencv-python-headless==4.8.1.78
|
85 |
+
openvino==2025.2.0
|
86 |
+
openvino-telemetry==2025.2.0
|
87 |
+
openvino-tokenizers==2025.2.0.1
|
88 |
+
optimum==1.27.0
|
89 |
+
optimum-intel==1.25.2
|
90 |
+
orjson==3.11.2
|
91 |
+
packaging==25.0
|
92 |
+
pandas==2.1.4
|
93 |
+
pdf2image==1.16.3
|
94 |
+
pdfminer.six==20221105
|
95 |
+
pdfplumber==0.10.3
|
96 |
+
Pillow==10.1.0
|
97 |
+
preshed==3.0.10
|
98 |
+
propcache==0.3.2
|
99 |
+
protobuf==4.25.1
|
100 |
+
psutil==7.0.0
|
101 |
+
pyarrow==21.0.0
|
102 |
+
pycparser==2.22
|
103 |
+
pydantic==2.11.7
|
104 |
+
pydantic_core==2.33.2
|
105 |
+
pydot==3.0.4
|
106 |
+
pydub==0.25.1
|
107 |
+
Pygments==2.19.2
|
108 |
+
pymoo==0.6.1.5
|
109 |
+
pyparsing==3.2.3
|
110 |
+
PyPDF2==3.0.1
|
111 |
+
pypdfium2==4.30.0
|
112 |
+
pytesseract==0.3.10
|
113 |
+
python-dateutil==2.9.0.post0
|
114 |
+
python-docx==1.0.1
|
115 |
+
python-dotenv==1.0.1
|
116 |
+
python-multipart==0.0.20
|
117 |
+
pytz==2025.2
|
118 |
+
PyYAML==6.0.2
|
119 |
+
referencing==0.36.2
|
120 |
+
regex==2025.7.34
|
121 |
+
requests==2.32.5
|
122 |
+
rich==13.9.4
|
123 |
+
rpds-py==0.27.0
|
124 |
+
safetensors==0.6.2
|
125 |
+
scikit-learn==1.3.2
|
126 |
+
scipy==1.11.4
|
127 |
+
semantic-version==2.10.0
|
128 |
+
sentence-transformers==5.1.0
|
129 |
+
sentencepiece==0.1.99
|
130 |
+
shellingham==1.5.4
|
131 |
+
six==1.17.0
|
132 |
+
smart-open==6.4.0
|
133 |
+
sniffio==1.3.1
|
134 |
+
spacy==3.7.2
|
135 |
+
spacy-legacy==3.0.12
|
136 |
+
spacy-loggers==1.0.5
|
137 |
+
srsly==2.5.1
|
138 |
+
starlette==0.47.2
|
139 |
+
sympy==1.14.0
|
140 |
+
tabulate==0.9.0
|
141 |
+
tbb==2021.13.1
|
142 |
+
termcolor==3.1.0
|
143 |
+
thinc==8.2.5
|
144 |
+
threadpoolctl==3.6.0
|
145 |
+
tiktoken==0.5.2
|
146 |
+
tokenizers==0.21.4
|
147 |
+
tomlkit==0.12.0
|
148 |
+
torch==2.3.0
|
149 |
+
torchaudio==2.3.0
|
150 |
+
torchvision==0.18.0
|
151 |
+
tqdm==4.67.1
|
152 |
+
transformers==4.53.3
|
153 |
+
typer==0.9.4
|
154 |
+
typing-inspection==0.4.1
|
155 |
+
typing_extensions==4.14.1
|
156 |
+
tzdata==2025.2
|
157 |
+
urllib3==2.5.0
|
158 |
+
uvicorn==0.35.0
|
159 |
+
wasabi==1.1.3
|
160 |
+
weasel==0.3.4
|
161 |
+
websockets==11.0.3
|
162 |
+
Werkzeug==3.1.3
|
163 |
+
wrapt==1.17.3
|
164 |
+
xxhash==3.5.0
|
165 |
+
yarl==1.20.1
|
ov_models/microsoft_Phi-3-mini-4k-instruct_ir/chat_template.jinja
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{% for message in messages %}{% if message['role'] == 'system' %}{{'<|system|>
|
2 |
+
' + message['content'] + '<|end|>
|
3 |
+
'}}{% elif message['role'] == 'user' %}{{'<|user|>
|
4 |
+
' + message['content'] + '<|end|>
|
5 |
+
'}}{% elif message['role'] == 'assistant' %}{{'<|assistant|>
|
6 |
+
' + message['content'] + '<|end|>
|
7 |
+
'}}{% endif %}{% endfor %}{% if add_generation_prompt %}{{ '<|assistant|>
|
8 |
+
' }}{% else %}{{ eos_token }}{% endif %}
|
ov_models/microsoft_Phi-3-mini-4k-instruct_ir/special_tokens_map.json
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"bos_token": {
|
3 |
+
"content": "<s>",
|
4 |
+
"lstrip": false,
|
5 |
+
"normalized": false,
|
6 |
+
"rstrip": false,
|
7 |
+
"single_word": false
|
8 |
+
},
|
9 |
+
"eos_token": {
|
10 |
+
"content": "<|endoftext|>",
|
11 |
+
"lstrip": false,
|
12 |
+
"normalized": false,
|
13 |
+
"rstrip": false,
|
14 |
+
"single_word": false
|
15 |
+
},
|
16 |
+
"pad_token": {
|
17 |
+
"content": "<|endoftext|>",
|
18 |
+
"lstrip": false,
|
19 |
+
"normalized": false,
|
20 |
+
"rstrip": false,
|
21 |
+
"single_word": false
|
22 |
+
},
|
23 |
+
"unk_token": {
|
24 |
+
"content": "<unk>",
|
25 |
+
"lstrip": false,
|
26 |
+
"normalized": false,
|
27 |
+
"rstrip": false,
|
28 |
+
"single_word": false
|
29 |
+
}
|
30 |
+
}
|
ov_models/microsoft_Phi-3-mini-4k-instruct_ir/tokenizer.json.REMOVED.git-id
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
759de6dd15d187c9ececdea11d3287d4cb4b604a
|