vectorizer.py 4.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import logging
  2. from typing import List
  3. import numpy as np
  4. import requests
  5. from requests.adapters import HTTPAdapter
  6. from urllib3.util.retry import Retry
  7. logger = logging.getLogger(__name__)
  8. class Vectorizer:
  9. _instance = None
  10. def __init__(self):
  11. self.api_url = "http://172.16.8.98:11434/api/embeddings"
  12. self.model_name = "bge-m3"
  13. self.session = requests.Session()
  14. retries = Retry(total=3, backoff_factor=1)
  15. self.session.mount('http://', HTTPAdapter(max_retries=retries))
  16. @staticmethod
  17. def get_embedding(text: str) -> List[float]:
  18. return Vectorizer()._call_ollama_api(text)
  19. def _initialize_model(self):
  20. logger.info("Initialized Ollama API client for bge-m3 model")
  21. @classmethod
  22. def get_instance(cls):
  23. if cls._instance is None:
  24. cls._instance = cls()
  25. return cls._instance
  26. def chunk_text(self, text: str, chunk_size: int = 500) -> List[str]:
  27. tokens = self.tokenizer.tokenize(text)
  28. return [self.tokenizer.convert_tokens_to_string(tokens[i:i+chunk_size])
  29. for i in range(0, len(tokens), chunk_size)]
  30. def encode(self, text: str, batch_size: int = 32) -> List[float]:
  31. if not text:
  32. return [0.0] * 1024 # 调整为1024维以匹配数据库
  33. return self._call_ollama_api(text)
  34. def batch_encode(self, texts: List[str], batch_size: int = 64) -> List[List[float]]:
  35. return [self._call_ollama_api(text) for text in texts]
  36. def _call_ollama_api(self, text: str) -> List[float]:
  37. try:
  38. response = self.session.post(
  39. self.api_url,
  40. json={
  41. "model": self.model_name,
  42. "prompt": text,
  43. "options": {"embedding_only": True}
  44. },
  45. timeout=30
  46. )
  47. response.raise_for_status()
  48. embedding_array = np.array(response.json()["embedding"])
  49. l2_norm = np.linalg.norm(embedding_array)
  50. if l2_norm > 0:
  51. embedding_array = embedding_array / l2_norm
  52. return embedding_array.tolist()
  53. except Exception as e:
  54. logger.error(f"API请求失败: {str(e)}")
  55. raise
  56. if __name__ == '__main__':
  57. text ='''姓名:李XX
  58. 性别:女
  59. 年龄:55岁
  60. 住院号:NJZY20231102
  61. 主诉:突发胸痛伴呼吸困难2小时
  62. 现病史:患者于下午3时许突发胸痛,位于心前区,呈压榨性疼痛,伴呼吸困难,持续不缓解,无恶心呕吐及二便失禁。急诊测血压150/90mmHg,心率100次/分。心电图示II、III、aVF导联ST段弓背向上抬高0.3-0.5mV。发病前2周曾诉间断性胸闷,每次持续数分钟自行缓解。
  63. 既往史:高血压8年(间断服用降压药),无糖尿病史,无手术史。长期吸烟(20包/年),饮酒史5年(红酒约150g/日)。
  64. 体格检查:BP 155/92mmHg,心率102次/分。神志清楚,痛苦面容,双肺呼吸音清,未闻及干湿性啰音。心界不大,心率102次/分,律齐,心尖区可闻及2/6级收缩期杂音。
  65. 辅助检查:心电图示II、III、aVF导联ST段弓背向上抬高0.3-0.5mV;心肌酶谱:肌酸激酶同工酶(CK-MB)100U/L,肌钙蛋白T(cTnT)0.4ng/ml;心脏超声示左室下壁运动减弱。
  66. 诊断:急性下壁心肌梗死
  67. 治疗计划:
  68. 1. 抗血小板治疗:阿司匹林300mg嚼服,氯吡格雷300mg负荷剂量后75mg qd。
  69. 2. 抗凝治疗:低分子量肝素4000U皮下注射,每12小时1次。
  70. 3. 冠状动脉介入治疗(PCI):急诊行冠状动脉造影,必要时行支架植入术。
  71. 4. 调脂治疗:阿托伐他汀20mg qn。
  72. 5. 血管扩张剂:硝酸甘油静脉泵入。'''
  73. embedding = get_embedding(text)
  74. print(f'生成的embedding向量:\n{embedding}')