From dabd20efe434704c96044dbd6c084e8266d1ef3f Mon Sep 17 00:00:00 2001
From: xqz <837938965@qq.com>
Date: 星期二, 08 七月 2025 18:34:40 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/develop' into develop

---
 qwen_ollama.py |  224 ++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 131 insertions(+), 93 deletions(-)

diff --git a/qwen_ollama.py b/qwen_ollama.py
index 92a197a..8fa71e7 100644
--- a/qwen_ollama.py
+++ b/qwen_ollama.py
@@ -10,7 +10,7 @@
 import logging
 from PIL import Image
 from logging.handlers import RotatingFileHandler
-
+from transformers import AutoModelForVision2Seq, AutoProcessor
 
 class detect_tasks():
     def __init__(self):
@@ -19,6 +19,20 @@
 
         # 鍒濆鍖朚ilvus闆嗗悎
         self.collection = None
+
+        self.model = AutoModelForVision2Seq.from_pretrained(
+            "./Qwen2.5-VL-3B-Instruct-GPTQ-Int4",
+            device_map="auto"
+        )
+
+        self.processor = AutoProcessor.from_pretrained(
+            "./Qwen2.5-VL-3B-Instruct-GPTQ-Int4",
+            trust_remote_code=True,
+            use_fast=True  # 寮哄埗鍚敤蹇�熷鐞嗗櫒
+        )
+
+
+
 
     def remove_duplicate_lines(self, text):
 
@@ -67,43 +81,50 @@
             self.logger.addHandler(handler)
 
     def image_desc(self, image_path, ollama_url, ollama_mode="qwen2.5vl:3b"):
-        try:
-            image_des = None
-            # 鍥剧墖棰勫鐞�
-            img = Image.open(image_path)
-            buffered = io.BytesIO()
-            img.save(buffered, format="JPEG", quality=85)
-            img_str = base64.b64encode(buffered.getvalue()).decode('utf-8')
-            # 璋冪敤API
-            response = requests.post(
-                f"{ollama_url}/api/generate",
-                json={
-                    "model": ollama_mode,
-                    "prompt": "璇锋寜浠ヤ笅瑕佹眰鎻忚堪鍥剧墖锛歕n1. 鍒楀嚭涓昏鐗╀綋\n2.涓嶈繘琛屾帹鐞嗗拰think\n杩斿洖灏忎簬2000瀛楃殑鏁存鎻忚堪,鎻忚堪涓殑鐗╀綋淇℃伅涓嶅姞鏁板瓧搴忓彿",
-                    "images": [img_str],
-                    "options": {
-                        "num_gpu_layers": 35
-                    },
-                    "stream": False  # 闈炴祦寮�
-                },
-                headers={"Content-Type": "application/json"}
-            )
-            result = response.json()
-            if result and result["response"]:
-                image_des = (result["response"]).replace('\n', '')
-                if len(image_des) > 4 and image_des.startswith("杩欏紶鍥剧墖"):
-                    image_des = image_des[4:]
+        image = Image.open(image_path).convert("RGB")  # 鏇挎崲涓烘偍鐨勫浘鐗囪矾寰�
+        image = image.resize((600, 600), Image.Resampling.LANCZOS)  # 楂樿川閲忕缉鏀�
 
-                image_des = self.remove_duplicate_lines(image_des)
-                image_des = self.remove_duplicate_lines_d(image_des)
-                image_des = self.remove_duplicate_lines_n(image_des)
-                # self.logger.info(image_des)
-            else:
-                self.logger.info(f"{self._thread_name}绾跨▼锛氭墽琛屽浘鐗囨弿杩版椂鍑洪敊:{image_path, result, response}")
-            return image_des
-        except Exception as e:
-            self.logger.info(f"{self._thread_name}绾跨▼锛氭墽琛屽浘鐗囨弿杩版椂鍑洪敊:{image_path, e}")
-            return None
+        messages = [
+            {
+                "role": "user",
+                "content": [
+                    {
+                        "type": "image",
+                    },
+                    {"type": "text", "text": "璇疯缁嗘弿杩板浘鐗囦腑鐨勭洰鏍囦俊鎭強鐗瑰緛銆傝繑鍥炴牸寮忎负鏁存鏂囧瓧鎻忚堪"},
+                ],
+            }
+        ]
+
+        # Preparation for inference
+        text = self.processor.apply_chat_template(
+            messages, add_generation_prompt=True
+        )
+
+        inputs = self.processor(
+            text=[text],
+            images=[image],
+            padding=True,
+            return_tensors="pt",
+        )
+        inputs = inputs.to("cuda")
+
+        with torch.no_grad():
+            outputs = self.model.generate(**inputs,
+                                     max_new_tokens=300,
+                                     do_sample=True,
+                                     temperature=0.7,
+                                     renormalize_logits=True
+                                     )
+
+        generated_ids = outputs[:, len(inputs.input_ids[0]):]
+        image_text = self.processor.batch_decode(
+            generated_ids, skip_special_tokens=True, clean_up_tokenization_spaces=True
+        )
+
+        image_des = (image_text[0]).strip()
+
+        return image_des
 
     def get_rule(self, ragurl):
         try:
@@ -193,6 +214,8 @@
         )
         # 浠巎son鎻愬彇data瀛楁鍐呭
         ret = response.json()["data"]
+        #result = response.json()
+        #ret = result.get("data") or result.get("message", {}).get("content", "")
         # 绉婚櫎<think>鏍囩鍜屽唴瀹�
         ret = re.sub(r'<think>.*?</think>', '', ret, flags=re.DOTALL)
         # 瀛楃涓叉竻鐞�,绉婚櫎绌烘牸,鍒惰〃绗�,鎹㈣绗�,鏄熷彿
@@ -202,12 +225,14 @@
     #澶勭悊寤鸿
     def image_rule_chat_suggestion(self, rule_text, ollama_url, ollama_mode="qwen2.5vl:3b"):
         self.logger.info("----------------------------------------------------------------")
+        # 璇锋眰鍐呭
         content = (
             f"璇锋牴鎹繚瑙勫唴瀹筟{rule_text}]\n杩涜杩斿洖澶勭悊杩濊寤鸿锛屼笉杩涜鎺ㄧ悊鍜宼hink銆傝繑鍥炵簿鍑嗕俊鎭�")
         response = requests.post(
+            # ollama鍦板潃
             url=f"{ollama_url}/chat",
             json={
-
+                # 鎸囧畾妯″瀷
                 "llm_name": "qwen3:8b",
                 "messages": [
                     {"role": "user", "content": content}
@@ -215,118 +240,131 @@
                 "stream": False  # 鍏抽棴娴佸紡杈撳嚭
             }
         )
+        # 浠巎son鎻愬彇data瀛楁鍐呭
         ret = response.json()["data"]
+        #result = response.json()
+        #ret = result.get("data") or result.get("message", {}).get("content", "")
+        # 绉婚櫎<think>鏍囩鍜屽唴瀹�
         ret = re.sub(r'<think>.*?</think>', '', ret, flags=re.DOTALL)
+        # 瀛楃涓叉竻鐞�,绉婚櫎绌烘牸,鍒惰〃绗�,鎹㈣绗�,鏄熷彿
         ret = ret.replace(" ", "").replace("\t", "").replace("\n", "").replace("**","")
         print(ret)
         return ret
 
-        # print(response.json())
-        # ret = response.json()["detail"]
-
+    # RAG鏈嶅姟鍙戦�佽姹�,鑾峰彇鐭ヨ瘑搴撳唴瀹�
     def get_filedata(self, searchtext, ragurl):
         search_data = {
+            # 鐭ヨ瘑搴撻泦鍚�
             "collection_name": "smart_knowledge",
+            # 鏌ヨ鏂囨湰
             "query_text": searchtext,
+            # 鎼滅储妯″紡
             "search_mode": "hybrid",
+            # 鏈�澶氳繑鍥炵粨鏋�
             "limit": 100,
+            # 璋冨瘑鍚戦噺鎼滅储鏉冮噸
             "weight_dense": 0.7,
+            # 绋�鐤忓悜閲忔悳绱㈡潈閲�
             "weight_sparse": 0.3,
+            # 绌哄瓧绗︿覆
             "filter_expr": "",
+            # 鍙繑鍥� text 瀛楁
             "output_fields": ["text"]
         }
+        # 鍚� ragurl + "/search" 绔偣鍙戦�丳OST璇锋眰
         response = requests.post(ragurl + "/search", json=search_data)
+        # 浠庡搷搴斾腑鑾峰彇'results'瀛楁
         results = response.json().get('results')
+        # 鍒濆鍖� text
         text = ""
+        # 閬嶅巻鎵�鏈夌粨鏋滆鍒�(rule)锛屽皢姣忔潯瑙勫垯鐨�'entity'涓殑'text'瀛楁鍙栧嚭.
         for rule in results:
             text = text + rule['entity'].get('text') + ";\n"
 
         return text
-
+    # 鍚慠AG绯荤粺鎻掑叆json鏍煎紡鏁版嵁
     async def insert_json_data(self, ragurl, data):
         try:
+            # data 瑕佹彃鍏ョ殑鏁版嵁
             data = {'collection_name': "smartrag", "data": data, "description": ""}
+            # 鏈嶅姟鐨勫熀鍦板潃
             requests.post(ragurl + "/insert_json_data", json=data, timeout=(0.3, 0.3))
             # self.logger.info(f"璋冪敤褰曞儚鏈嶅姟:{ragurl, data}")
         except Exception as e:
             # self.logger.info(f"{self._thread_name}绾跨▼锛氳皟鐢ㄥ綍鍍忔椂鍑洪敊:鍦板潃锛歿ragurl}锛歿e}")
             return
 
-    def tark_do(self, image_id, ollamaurl, ragurl, ollamamode, ragmode):
+    def tark_do(self, res, ollamaurl, ragurl, ollamamode, ragmode):
         try:
             # 1. 浠庨泦鍚圓鑾峰彇鍚戦噺鍜屽厓鏁版嵁
             is_waning = 0
-            res_a = self.collection.query(
-                expr=f"id == 458942504686042840",
-                output_fields=["id", "zh_desc_class", "text_vector", "bounding_box", "video_point_name", "task_id",
-                               "task_name", "event_level_id", "event_level_name",
-                               "video_point_id", "detect_num", "is_waning", "waning_value", "rule_id", "detect_id",
-                               "detect_time", "image_path", "image_desc_path", "video_path","risk_description","suggestion","knowledge_id"],
-                consistency_level="Strong"
-            )
+            is_desc = 2
 
-            if not res_a:
-                self.logger.info(f"{self._thread_name}绾跨▼锛氭湭鎵惧埌ID涓� {image_id} 鐨勮褰�")
-                return 0
-
-
-            image_des = self.image_desc(f"/opt/smart/img/1748763385.245874.jpg", ollamaurl, ollamamode)
+            # 鐢熸垚鍥剧墖鎻忚堪
+            image_des = self.image_desc(res['image_desc_path'], ollamaurl, ollamamode)
             risk_description = ""
             suggestion = ""
+            # 鍥剧墖鎻忚堪鐢熸垚鎴愬姛
             if image_des:
-                is_waning = self.image_rule_chat(image_des, res_a[0]['waning_value'], ollamaurl, ollamamode)
+                is_desc = 2
+                # 璋冪敤瑙勫垯鍖归厤鏂规硶,鍒ゆ柇鏄惁棰勮
+                is_waning = self.image_rule_chat(image_des, res['waning_value'], ollamaurl, ollamamode)
+                # 濡傛灉棰勮,鍒欑敓鎴愰殣鎮f弿杩板拰澶勭悊寤鸿
+                if is_waning == 1:
+                    # 鑾峰彇瑙勭珷鍒跺害鏁版嵁
+                    filedata = self.get_filedata(res['waning_value'], ragurl)
+                    # 鐢熸垚闅愭偅鎻忚堪
+                    risk_description = self.image_rule_chat_with_detail(filedata,res['waning_value'], ragurl, ragmode)
+                    # 鐢熸垚澶勭悊寤鸿
+                    suggestion = self.image_rule_chat_suggestion(res['waning_value'], ragurl, ragmode)
 
-                if is_waning == 0:
-
-                    filedata = self.get_filedata(res_a[0]['waning_value'], ragurl)
-                    risk_description = self.image_rule_chat_with_detail(filedata,res_a[0]['waning_value'], ragurl, ragmode)
-                    suggestion = self.image_rule_chat_suggestion(res_a[0]['waning_value'], ragurl, ragmode)
+            else:
+                is_desc = 3
 
             # 鏁版嵁缁�
             data = {
-                "id": image_id,
-                "event_level_id": res_a[0]['event_level_id'],  # event_level_id
-                "event_level_name": res_a[0]['event_level_name'],  # event_level_id
-                "rule_id": res_a[0]["rule_id"],
-                "video_point_id": res_a[0]['video_point_id'],  # video_point_id
-                "video_point_name": res_a[0]['video_point_name'],
+                "id": res['id'],
+                "event_level_id": res['event_level_id'],  # event_level_id
+                "event_level_name": res['event_level_name'],  # event_level_id
+                "rule_id": res["rule_id"],
+                "video_point_id": res['video_point_id'],  # video_point_id
+                "video_point_name": res['video_point_name'],
                 "is_waning": is_waning,
+                "is_desc": is_desc,
                 "zh_desc_class": image_des,  # text_vector
-                "bounding_box": res_a[0]['bounding_box'],  # bounding_box
-                "task_id": res_a[0]['task_id'],  # task_id
-                "task_name": res_a[0]['task_name'],  # task_id
-                "detect_id": res_a[0]['detect_id'],  # detect_id
-                "detect_time": res_a[0]['detect_time'],  # detect_time
-                "detect_num": res_a[0]['detect_num'],
-                "waning_value": res_a[0]['waning_value'],
-                "image_path": res_a[0]['image_path'],  # image_path
-                "image_desc_path": res_a[0]['image_desc_path'],  # image_desc_path
-                "video_path": res_a[0]['video_path'],
-                "text_vector": res_a[0]['text_vector'],
+                "bounding_box": res['bounding_box'],  # bounding_box
+                "task_id": res['task_id'],  # task_id
+                "task_name": res['task_name'],  # task_id
+                "detect_id": res['detect_id'],  # detect_id
+                "detect_time": res['detect_time'],  # detect_time
+                "detect_num": res['detect_num'],
+                "waning_value": res['waning_value'],
+                "image_path": res['image_path'],  # image_path
+                "image_desc_path": res['image_desc_path'],  # image_desc_path
+                "video_path": res['video_path'],
+                "text_vector": res['text_vector'],
                 "risk_description": risk_description,
                 "suggestion": suggestion,
-                "knowledge_id": res_a[0]['knowledge_id']
+                "knowledge_id": res['knowledge_id']
             }
-
-
 
             # 淇濆瓨鍒癿ilvus
             image_id = self.collection.upsert(data).primary_keys
+            logging.info(image_id)
             data = {
                 "id": str(image_id[0]),
-                "video_point_id": res_a[0]['video_point_id'],
-                "video_path": res_a[0]["video_point_name"],
+                "video_point_id": res['video_point_id'],
+                "video_path": res["video_point_name"],
                 "zh_desc_class": image_des,
-                "detect_time": res_a[0]['detect_time'],
-                "image_path": f"{res_a[0]['image_path']}",
-                "task_name": res_a[0]["task_name"],
-                "event_level_name": res_a[0]["event_level_name"],
-                "rtsp_address": f"{res_a[0]['video_path']}"
+                "detect_time": res['detect_time'],
+                "image_path": f"{res['image_path']}",
+                "task_name": res["task_name"],
+                "event_level_name": res["event_level_name"],
+                "rtsp_address": f"{res['video_path']}"
             }
             # 璋冪敤rag
             asyncio.run(self.insert_json_data(ragurl, data))
             return image_id
         except Exception as e:
-            self.logger.info(f"{self._thread_name}绾跨▼锛氭墽琛屾ā鍨嬭В鏋愭椂鍑洪敊:浠诲姟锛歿image_id} :{e}")
-            return 0
-
+            self.logger.info(f"{self._thread_name}绾跨▼锛氭墽琛屾ā鍨嬭В鏋愭椂鍑洪敊:浠诲姟锛歿res['id']} :{e}")
+            return 0
\ No newline at end of file

--
Gitblit v1.8.0