Spaces:
Sleeping
Sleeping
YanBoChen
commited on
Commit
Β·
4d836bc
1
Parent(s):
9731a88
fix(MedicalAdviceGenerator): enhance fallback generation with primary result simplification and increased token limits
Browse files- dataset/keywords/special_terms_emergency.json +30 -25
- src/generation.py +88 -9
dataset/keywords/special_terms_emergency.json
CHANGED
@@ -1,26 +1,31 @@
|
|
1 |
{
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
1 |
{
|
2 |
+
"cardiac": {
|
3 |
+
"mi": ["mi", "m.i.", "myocardial infarction", "MI", "STEMI", "NSTEMI"],
|
4 |
+
"acs": ["acs", "ACS", "acute coronary syndrome"]
|
5 |
+
},
|
6 |
+
"respiratory": {
|
7 |
+
"ards": ["ards", "ARDS", "acute respiratory distress syndrome"],
|
8 |
+
"respiratory_failure": ["respiratory failure", "resp failure", "RF"]
|
9 |
+
},
|
10 |
+
"neurological": {
|
11 |
+
"loc": ["loc", "LOC", "loss of consciousness"],
|
12 |
+
"cva": ["cva", "CVA", "stroke", "cerebrovascular accident"]
|
13 |
+
},
|
14 |
+
"shock": {
|
15 |
+
"shock": ["shock", "circulatory failure"],
|
16 |
+
"septic_shock": ["septic shock", "sepsis induced shock"]
|
17 |
+
},
|
18 |
+
"bleeding": {
|
19 |
+
"gi_bleed": [
|
20 |
+
"gi bleed",
|
21 |
+
"gi bleeding",
|
22 |
+
"gastrointestinal hemorrhage",
|
23 |
+
"GI hemorrhage"
|
24 |
+
],
|
25 |
+
"hemorrhage": ["hemorrhage", "bleeding", "blood loss"]
|
26 |
+
},
|
27 |
+
"vital_signs": {
|
28 |
+
"hypotension": ["hypotension", "low bp", "low blood pressure"],
|
29 |
+
"tachycardia": ["tachycardia", "elevated heart rate", "fast heart rate"]
|
30 |
+
}
|
31 |
+
}
|
src/generation.py
CHANGED
@@ -31,14 +31,14 @@ logger = logging.getLogger(__name__)
|
|
31 |
# Fallback Generation Configuration
|
32 |
FALLBACK_TIMEOUTS = {
|
33 |
"primary": 30.0, # Primary Med42-70B with full RAG context
|
34 |
-
"fallback_1": 15.0, # Simplified
|
35 |
"fallback_2": 1.0 # RAG template generation (instant)
|
36 |
}
|
37 |
|
38 |
FALLBACK_TOKEN_LIMITS = {
|
39 |
-
"primary":
|
40 |
-
"fallback_1":
|
41 |
-
"fallback_2": 0
|
42 |
}
|
43 |
|
44 |
FALLBACK_CONFIDENCE_SCORES = {
|
@@ -363,8 +363,9 @@ class MedicalAdviceGenerator:
|
|
363 |
# Check for API errors in response
|
364 |
if result.get('error'):
|
365 |
logger.warning(f"β οΈ Med42-70B returned error: {result['error']}")
|
366 |
-
#
|
367 |
-
|
|
|
368 |
|
369 |
# Check for empty response
|
370 |
if not result.get('raw_response', '').strip():
|
@@ -514,7 +515,7 @@ class MedicalAdviceGenerator:
|
|
514 |
"disclaimer": "This system experienced a technical error. Please consult with qualified healthcare providers for medical decisions."
|
515 |
}
|
516 |
|
517 |
-
def _attempt_fallback_generation(self, original_prompt: str, primary_error: str) -> Dict[str, Any]:
|
518 |
"""
|
519 |
Orchestrate fallback generation attempts with detailed logging
|
520 |
|
@@ -524,20 +525,38 @@ class MedicalAdviceGenerator:
|
|
524 |
Args:
|
525 |
original_prompt: The complete RAG prompt that failed in primary generation
|
526 |
primary_error: Error details from the primary generation attempt
|
|
|
527 |
|
528 |
Returns:
|
529 |
Dict containing successful fallback response or final error response
|
530 |
"""
|
531 |
logger.info("π FALLBACK: Attempting fallback generation strategies")
|
532 |
|
533 |
-
# Fallback 1:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
534 |
try:
|
535 |
logger.info("π FALLBACK 1: Med42-70B without RAG context")
|
536 |
fallback_1_result = self._attempt_simplified_med42(original_prompt, primary_error)
|
537 |
|
538 |
if not fallback_1_result.get('error'):
|
539 |
logger.info("β
FALLBACK 1: Success - Med42-70B without RAG")
|
540 |
-
# Mark response as fallback method 1
|
541 |
fallback_1_result['fallback_method'] = 'med42_simplified'
|
542 |
fallback_1_result['primary_error'] = primary_error
|
543 |
return fallback_1_result
|
@@ -588,6 +607,66 @@ class MedicalAdviceGenerator:
|
|
588 |
'latency': 0.0
|
589 |
}
|
590 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
591 |
def _attempt_simplified_med42(self, original_prompt: str, primary_error: str) -> Dict[str, Any]:
|
592 |
"""
|
593 |
Attempt Med42-70B generation with simplified prompt (Fallback 1)
|
|
|
31 |
# Fallback Generation Configuration
|
32 |
FALLBACK_TIMEOUTS = {
|
33 |
"primary": 30.0, # Primary Med42-70B with full RAG context
|
34 |
+
"fallback_1": 15.0, # Simplified primary generation
|
35 |
"fallback_2": 1.0 # RAG template generation (instant)
|
36 |
}
|
37 |
|
38 |
FALLBACK_TOKEN_LIMITS = {
|
39 |
+
"primary": 1600, # Full comprehensive medical advice (increased)
|
40 |
+
"fallback_1": 1200, # Simplified primary result (increased)
|
41 |
+
"fallback_2": 0 # Template-based, no LLM tokens
|
42 |
}
|
43 |
|
44 |
FALLBACK_CONFIDENCE_SCORES = {
|
|
|
363 |
# Check for API errors in response
|
364 |
if result.get('error'):
|
365 |
logger.warning(f"β οΈ Med42-70B returned error: {result['error']}")
|
366 |
+
# Pass any available content for potential simplification
|
367 |
+
primary_content = result.get('raw_response', '')
|
368 |
+
return self._attempt_fallback_generation(prompt, result['error'], primary_content)
|
369 |
|
370 |
# Check for empty response
|
371 |
if not result.get('raw_response', '').strip():
|
|
|
515 |
"disclaimer": "This system experienced a technical error. Please consult with qualified healthcare providers for medical decisions."
|
516 |
}
|
517 |
|
518 |
+
def _attempt_fallback_generation(self, original_prompt: str, primary_error: str, primary_result: str = None) -> Dict[str, Any]:
|
519 |
"""
|
520 |
Orchestrate fallback generation attempts with detailed logging
|
521 |
|
|
|
525 |
Args:
|
526 |
original_prompt: The complete RAG prompt that failed in primary generation
|
527 |
primary_error: Error details from the primary generation attempt
|
528 |
+
primary_result: Primary result content (if available) for simplification
|
529 |
|
530 |
Returns:
|
531 |
Dict containing successful fallback response or final error response
|
532 |
"""
|
533 |
logger.info("π FALLBACK: Attempting fallback generation strategies")
|
534 |
|
535 |
+
# Fallback 1: Try to simplify primary result first (if available)
|
536 |
+
if primary_result and primary_result.strip():
|
537 |
+
try:
|
538 |
+
logger.info("π FALLBACK 1: Simplifying primary result")
|
539 |
+
user_query = self._extract_user_query_from_prompt(original_prompt)
|
540 |
+
fallback_1_result = self._simplify_primary_result(primary_result, user_query or "medical query")
|
541 |
+
|
542 |
+
if not fallback_1_result.get('error'):
|
543 |
+
logger.info("β
FALLBACK 1: Success - Primary result simplified")
|
544 |
+
fallback_1_result['fallback_method'] = 'primary_simplified'
|
545 |
+
fallback_1_result['primary_error'] = primary_error
|
546 |
+
return fallback_1_result
|
547 |
+
else:
|
548 |
+
logger.warning(f"β FALLBACK 1: Simplification failed - {fallback_1_result.get('error')}")
|
549 |
+
|
550 |
+
except Exception as e:
|
551 |
+
logger.error(f"β FALLBACK 1: Exception during simplification - {e}")
|
552 |
+
|
553 |
+
# Fallback 1 Alternative: Med42-70B without RAG context (if no primary result)
|
554 |
try:
|
555 |
logger.info("π FALLBACK 1: Med42-70B without RAG context")
|
556 |
fallback_1_result = self._attempt_simplified_med42(original_prompt, primary_error)
|
557 |
|
558 |
if not fallback_1_result.get('error'):
|
559 |
logger.info("β
FALLBACK 1: Success - Med42-70B without RAG")
|
|
|
560 |
fallback_1_result['fallback_method'] = 'med42_simplified'
|
561 |
fallback_1_result['primary_error'] = primary_error
|
562 |
return fallback_1_result
|
|
|
607 |
'latency': 0.0
|
608 |
}
|
609 |
|
610 |
+
def _simplify_primary_result(self, primary_result: str, user_query: str) -> Dict[str, Any]:
|
611 |
+
"""
|
612 |
+
Simplify the primary result into concise key points (Fallback 1)
|
613 |
+
|
614 |
+
This method takes the successful primary result and simplifies it using Med42-70B
|
615 |
+
to create a more concise version while preserving medical accuracy.
|
616 |
+
|
617 |
+
Args:
|
618 |
+
primary_result: The successful primary generation result
|
619 |
+
user_query: Original user query for context
|
620 |
+
|
621 |
+
Returns:
|
622 |
+
Dict with simplified result or error details
|
623 |
+
"""
|
624 |
+
logger.info("π FALLBACK 1: Simplifying primary result")
|
625 |
+
|
626 |
+
try:
|
627 |
+
# Create simplification prompt
|
628 |
+
simplification_prompt = f"""Summarize the following medical advice into concise, actionable key points:
|
629 |
+
|
630 |
+
Original Medical Advice:
|
631 |
+
{primary_result}
|
632 |
+
|
633 |
+
Original Query: {user_query}
|
634 |
+
|
635 |
+
Provide a clear, concise summary focusing on immediate clinical actions and key recommendations."""
|
636 |
+
|
637 |
+
logger.info(f"π FALLBACK 1: Simplifying with Med42-70B (max_tokens={FALLBACK_TOKEN_LIMITS['fallback_1']}, timeout={FALLBACK_TIMEOUTS['fallback_1']}s)")
|
638 |
+
|
639 |
+
# Call Med42-70B for simplification
|
640 |
+
result = self.llm_client.analyze_medical_query(
|
641 |
+
query=simplification_prompt,
|
642 |
+
max_tokens=FALLBACK_TOKEN_LIMITS["fallback_1"],
|
643 |
+
timeout=FALLBACK_TIMEOUTS["fallback_1"]
|
644 |
+
)
|
645 |
+
|
646 |
+
if result.get('status') == 'success' and result.get('response'):
|
647 |
+
simplified_advice = result['response'].strip()
|
648 |
+
|
649 |
+
if simplified_advice and len(simplified_advice) > 10:
|
650 |
+
logger.info("β
FALLBACK 1: Successfully simplified primary result")
|
651 |
+
return {
|
652 |
+
'medical_advice': simplified_advice,
|
653 |
+
'confidence_score': FALLBACK_CONFIDENCE_SCORES["fallback_1"],
|
654 |
+
'latency': result.get('latency', 0.0),
|
655 |
+
'fallback_method': 'primary_simplified',
|
656 |
+
'error': None
|
657 |
+
}
|
658 |
+
else:
|
659 |
+
logger.error("β FALLBACK 1: Simplified result too short")
|
660 |
+
return {'error': 'Simplified result too short or empty'}
|
661 |
+
else:
|
662 |
+
error_msg = result.get('error', 'Unknown error during simplification')
|
663 |
+
logger.error(f"β FALLBACK 1: Simplification failed - {error_msg}")
|
664 |
+
return {'error': f'Simplification failed: {error_msg}'}
|
665 |
+
|
666 |
+
except Exception as e:
|
667 |
+
logger.error(f"β FALLBACK 1: Exception during simplification - {e}")
|
668 |
+
return {'error': f'Exception during simplification: {str(e)}'}
|
669 |
+
|
670 |
def _attempt_simplified_med42(self, original_prompt: str, primary_error: str) -> Dict[str, Any]:
|
671 |
"""
|
672 |
Attempt Med42-70B generation with simplified prompt (Fallback 1)
|